From dc821c04f3701f866d8e6f48f153829578922447 Mon Sep 17 00:00:00 2001 From: ddl Date: Wed, 10 Apr 2013 16:26:51 +0800 Subject: [PATCH] camera(v0.4.1): cif:v0.4.1 generic_sensor:v0.1.0 rk_camera:v0.1.0 --- arch/arm/mach-rk30/board-rk30-sdk-camera.c | 534 +- arch/arm/mach-rk30/include/mach/rk30_camera.h | 7 +- arch/arm/plat-rk/include/plat/rk_camera.h | 371 +- arch/arm/plat-rk/rk_camera.c | 816 +- drivers/media/video/Kconfig | 473 +- drivers/media/video/Makefile | 10 +- drivers/media/video/gc0307.c | 4356 ++---- drivers/media/video/gc0307_old.c | 3079 ++++ drivers/media/video/gc0308.c | 4118 ++---- drivers/media/video/gc0308_old.c | 2957 ++++ drivers/media/video/gc0309.c | 3939 ++--- drivers/media/video/gc0309_old.c | 2862 ++++ drivers/media/video/gc0328.c | 994 ++ drivers/media/video/gc0329.c | 4131 ++---- drivers/media/video/gc0329_old.c | 3046 ++++ drivers/media/video/gc2015.c | 4190 ++---- drivers/media/video/gc2015_old.c | 3095 ++++ drivers/media/video/gc2035.c | 2702 +--- drivers/media/video/gc2035_old.c | 3267 +++++ drivers/media/video/generic_sensor.c | 1387 ++ drivers/media/video/generic_sensor.h | 1291 ++ drivers/media/video/gt2005.c | 4967 ++----- drivers/media/video/gt2005_old.c | 3727 +++++ drivers/media/video/hm2057.c | 1241 ++ drivers/media/video/mt9p111.c | 7277 +++------- drivers/media/video/mt9p111_old.c | 5587 ++++++++ drivers/media/video/nt99160_2way.c | 1264 ++ drivers/media/video/nt99240_2way.c | 1200 ++ drivers/media/video/nt99252_3way.c | 1177 ++ drivers/media/video/nt99340_2way.c | 1183 ++ drivers/media/video/ov2659.c | 4500 ++---- drivers/media/video/ov2659_old.c | 3372 +++++ drivers/media/video/ov5640.c | 5708 ++------ drivers/media/video/ov5640_af_firmware.c | 7 +- drivers/media/video/ov5640_af_firmware_old.c | 11929 ++++++++++++++++ drivers/media/video/ov5640_old.c | 4199 ++++++ drivers/media/video/rk30_camera.c | 112 +- drivers/media/video/rk30_camera_oneframe.c | 533 +- drivers/media/video/sp2518.c | 3543 +---- drivers/media/video/sp2518_old.c | 3389 +++++ include/media/soc_camera.h | 4 +- include/media/v4l2-chip-ident.h | 14 +- 42 files changed, 74681 insertions(+), 37877 deletions(-) mode change 100644 => 100755 arch/arm/mach-rk30/board-rk30-sdk-camera.c create mode 100755 drivers/media/video/gc0307_old.c create mode 100755 drivers/media/video/gc0308_old.c create mode 100755 drivers/media/video/gc0309_old.c create mode 100755 drivers/media/video/gc0328.c create mode 100755 drivers/media/video/gc0329_old.c create mode 100755 drivers/media/video/gc2015_old.c create mode 100755 drivers/media/video/gc2035_old.c create mode 100755 drivers/media/video/generic_sensor.c create mode 100755 drivers/media/video/generic_sensor.h create mode 100755 drivers/media/video/gt2005_old.c create mode 100755 drivers/media/video/hm2057.c create mode 100755 drivers/media/video/mt9p111_old.c create mode 100755 drivers/media/video/nt99160_2way.c create mode 100755 drivers/media/video/nt99240_2way.c create mode 100755 drivers/media/video/nt99252_3way.c create mode 100755 drivers/media/video/nt99340_2way.c create mode 100755 drivers/media/video/ov2659_old.c create mode 100755 drivers/media/video/ov5640_af_firmware_old.c create mode 100755 drivers/media/video/ov5640_old.c create mode 100755 drivers/media/video/sp2518_old.c mode change 100644 => 100755 include/media/soc_camera.h diff --git a/arch/arm/mach-rk30/board-rk30-sdk-camera.c b/arch/arm/mach-rk30/board-rk30-sdk-camera.c old mode 100644 new mode 100755 index 67f76f609c79..4af6d2a6ba66 --- a/arch/arm/mach-rk30/board-rk30-sdk-camera.c +++ b/arch/arm/mach-rk30/board-rk30-sdk-camera.c @@ -1,146 +1,120 @@ #ifdef CONFIG_VIDEO_RK29 -/*---------------- Camera Sensor Macro Define Begin ------------------------*/ -/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/ -#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642 /* back camera sensor */ -#define CONFIG_SENSOR_IIC_ADDR_0 0x78 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_0 4 -#define CONFIG_SENSOR_CIF_INDEX_0 1 -#define CONFIG_SENSOR_ORIENTATION_0 90 -#define CONFIG_SENSOR_POWER_PIN_0 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_0 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_0 RK30_PIN1_PD6 -#define CONFIG_SENSOR_FALSH_PIN_0 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_0 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_0 30000 - -#define CONFIG_SENSOR_01 RK29_CAM_SENSOR_OV5642 /* back camera sensor 1 */ -#define CONFIG_SENSOR_IIC_ADDR_01 0x00 -#define CONFIG_SENSOR_CIF_INDEX_01 1 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_01 4 -#define CONFIG_SENSOR_ORIENTATION_01 90 -#define CONFIG_SENSOR_POWER_PIN_01 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_01 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_01 RK30_PIN1_PD6 -#define CONFIG_SENSOR_FALSH_PIN_01 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_01 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_01 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_01 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_01 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_01 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_01 30000 - -#define CONFIG_SENSOR_02 RK29_CAM_SENSOR_OV5640 /* back camera sensor 2 */ -#define CONFIG_SENSOR_IIC_ADDR_02 0x00 -#define CONFIG_SENSOR_CIF_INDEX_02 1 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_02 4 -#define CONFIG_SENSOR_ORIENTATION_02 90 -#define CONFIG_SENSOR_POWER_PIN_02 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_02 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_02 RK30_PIN1_PD6 -#define CONFIG_SENSOR_FALSH_PIN_02 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_02 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_02 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_02 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_02 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_02 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_02 30000 - -#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659 /* front camera sensor 0 */ -#define CONFIG_SENSOR_IIC_ADDR_1 0x60 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 3 -#define CONFIG_SENSOR_CIF_INDEX_1 0 -#define CONFIG_SENSOR_ORIENTATION_1 270 -#define CONFIG_SENSOR_POWER_PIN_1 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_1 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_1 RK30_PIN1_PB7 -#define CONFIG_SENSOR_FALSH_PIN_1 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_1 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_1 30000 - -#define CONFIG_SENSOR_11 RK29_CAM_SENSOR_OV2659 /* front camera sensor 1 */ -#define CONFIG_SENSOR_IIC_ADDR_11 0x00 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_11 3 -#define CONFIG_SENSOR_CIF_INDEX_11 0 -#define CONFIG_SENSOR_ORIENTATION_11 270 -#define CONFIG_SENSOR_POWER_PIN_11 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_11 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_11 INVALID_GPIO//RK30_PIN1_PB7 -#define CONFIG_SENSOR_FALSH_PIN_11 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_11 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_11 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_11 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_11 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_11 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_11 30000 - -#define CONFIG_SENSOR_12 RK29_CAM_SENSOR_OV2659//RK29_CAM_SENSOR_OV2655 /* front camera sensor 2 */ -#define CONFIG_SENSOR_IIC_ADDR_12 0x00 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_12 3 -#define CONFIG_SENSOR_CIF_INDEX_12 0 -#define CONFIG_SENSOR_ORIENTATION_12 270 -#define CONFIG_SENSOR_POWER_PIN_12 INVALID_GPIO -#define CONFIG_SENSOR_RESET_PIN_12 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_12 INVALID_GPIO//RK30_PIN1_PB7 -#define CONFIG_SENSOR_FALSH_PIN_12 INVALID_GPIO -#define CONFIG_SENSOR_POWERACTIVE_LEVEL_12 RK29_CAM_POWERACTIVE_L -#define CONFIG_SENSOR_RESETACTIVE_LEVEL_12 RK29_CAM_RESETACTIVE_L -#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_12 RK29_CAM_POWERDNACTIVE_H -#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_12 RK29_CAM_FLASHACTIVE_L - -#define CONFIG_SENSOR_QCIF_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_240X160_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_QVGA_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_CIF_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_VGA_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_480P_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_SVGA_FPS_FIXED_12 15000 -#define CONFIG_SENSOR_720P_FPS_FIXED_12 30000 - +#include +/* 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(RK29_CAM_SENSOR_OV5640, + back, + RK30_PIN1_PD6, + 0, + 0, + 4, + 1), + + /* + new_camera_device(RK29_CAM_SENSOR_OV5642, + back, + RK30_PIN1_PD6, + 0, + 0, + 4, + 1), + + new_camera_device(RK29_CAM_SENSOR_HM5065, + back, + RK30_PIN1_PD6, + 0, + 0, + 4, + 1), + + */ + /* + new_camera_device_ex(RK29_CAM_SENSOR_MT9P111, + back, + INVALID_VALUE, + INVALID_VALUE, + INVALID_VALUE, + INVALID_VALUE, + INVALID_VALUE, + RK30_PIN1_PD6, + CONS(RK29_CAM_SENSOR_MT9P111,_PWRDN_ACTIVE), + 0, + CONS(RK29_CAM_SENSOR_MT9P111,_FULL_RESOLUTION), + 0x00, + 4, + 100000, + CONS(RK29_CAM_SENSOR_MT9P111,_I2C_ADDR), + 1, + 24), + + + */ + /* + new_camera_device(RK29_CAM_SENSOR_SP2518, + front, + RK30_PIN1_PB7, + 0, + 0, + 3, + 0), + */ + /* + new_camera_device(RK29_CAM_SENSOR_GC2035, + front, + RK30_PIN1_PB7, + 0, + 0, + 3, + 0), + + + */ + new_camera_device(RK29_CAM_SENSOR_OV2659, + front, + RK30_PIN1_PB7, + 0, + 0, + 3, + 0), + + + 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 ---------*/ @@ -156,62 +130,40 @@ #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) +#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!!"; struct regulator *ldo_18,*ldo_28; - int camera_power = res->gpio_power; - int camera_ioflag = res->gpio_flag; - int camera_io_init = res->gpio_init; - - ldo_28 = regulator_get(NULL, "ldo7"); // vcc28_cif - ldo_18 = regulator_get(NULL, "ldo1"); // vcc18_cif - if (ldo_28 == NULL || IS_ERR(ldo_28) || ldo_18 == NULL || IS_ERR(ldo_18)){ + + ldo_28 = regulator_get(NULL, "ldo7"); // vcc28_cif + ldo_18 = regulator_get(NULL, "ldo1"); // vcc18_cif + if (ldo_28 == NULL || IS_ERR(ldo_28) || ldo_18 == NULL || IS_ERR(ldo_18)){ printk("get cif ldo failed!\n"); - return; - } + return -1; + } 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); - regulator_put(ldo_18); - mdelay(10); - if (camera_power != INVALID_GPIO) { - if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) { - gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - // dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - } - } - } - else{ - 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); - - regulator_set_voltage(ldo_18, 1800000, 1800000); - // regulator_set_suspend_voltage(ldo, 1800000); - regulator_enable(ldo_18); - // printk("%s set ldo1 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18)); - regulator_put(ldo_18); - if (camera_power != INVALID_GPIO) { - if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) { - gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - //dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - mdelay(10); - } - } - + 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); + regulator_put(ldo_18); + mdelay(10); + } else { + 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); + + regulator_set_voltage(ldo_18, 1800000, 1800000); + //regulator_set_suspend_voltage(ldo, 1800000); + regulator_enable(ldo_18); + //printk("%s set ldo1 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18)); + regulator_put(ldo_18); } -} -#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; + return 0; } #endif @@ -262,208 +214,8 @@ static struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = { #endif }; -#if CONFIG_SENSOR_IIC_ADDR_0 -static struct reginfo_t rk_init_data_sensor_reg_0[] = -{ - {0x0000, 0x00,0,0} - }; -static struct reginfo_t rk_init_data_sensor_winseqreg_0[] ={ - {0x0000, 0x00,0,0} - }; -#endif - -#if CONFIG_SENSOR_IIC_ADDR_1 -static struct reginfo_t rk_init_data_sensor_reg_1[] = -{ - {0x0000, 0x00,0,0} -}; -static struct reginfo_t rk_init_data_sensor_winseqreg_1[] = -{ - {0x0000, 0x00,0,0} -}; -#endif -#if CONFIG_SENSOR_IIC_ADDR_01 -static struct reginfo_t rk_init_data_sensor_reg_01[] = -{ - {0x0000, 0x00,0,0} -}; -static struct reginfo_t rk_init_data_sensor_winseqreg_01[] = -{ - {0x0000, 0x00,0,0} -}; -#endif -#if CONFIG_SENSOR_IIC_ADDR_02 -static struct reginfo_t rk_init_data_sensor_reg_02[] = -{ - {0x0000, 0x00,0,0} -}; -static struct reginfo_t rk_init_data_sensor_winseqreg_02[] = -{ - {0x0000, 0x00,0,0} -}; -#endif -#if CONFIG_SENSOR_IIC_ADDR_11 -static struct reginfo_t rk_init_data_sensor_reg_11[] = -{ - {0x0000, 0x00,0,0} -}; -static struct reginfo_t rk_init_data_sensor_winseqreg_11[] = -{ - {0x0000, 0x00,0,0} -}; -#endif -#if CONFIG_SENSOR_IIC_ADDR_12 -static struct reginfo_t rk_init_data_sensor_reg_12[] = -{ - {0x0000, 0x00,0,0} -}; -static struct reginfo_t rk_init_data_sensor_winseqreg_12[] = -{ - {0x0000, 0x00,0,0} -}; -#endif -static rk_sensor_user_init_data_s rk_init_data_sensor[RK_CAM_NUM] = -{ - #if CONFIG_SENSOR_IIC_ADDR_0 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_0, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_0, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_0) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_0) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #endif - #if CONFIG_SENSOR_IIC_ADDR_1 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_1, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_1, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_1) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_1) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #endif - #if CONFIG_SENSOR_IIC_ADDR_01 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_01, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_01, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_01) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_01) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #endif - #if CONFIG_SENSOR_IIC_ADDR_02 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_02, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_02, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_02) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_02) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #endif - #if CONFIG_SENSOR_IIC_ADDR_11 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_11, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_11, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_11) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_11) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #endif - #if CONFIG_SENSOR_IIC_ADDR_12 - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = rk_init_data_sensor_reg_12, - .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_12, - .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_12) / sizeof(struct reginfo_t), - .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_12) / sizeof(struct reginfo_t), - }, - #else - { - .rk_sensor_init_width = INVALID_VALUE, - .rk_sensor_init_height = INVALID_VALUE, - .rk_sensor_init_bus_param = INVALID_VALUE, - .rk_sensor_init_pixelcode = INVALID_VALUE, - .rk_sensor_init_data = NULL, - .rk_sensor_init_winseq = NULL, - .rk_sensor_winseq_size = 0, - .rk_sensor_init_data_size = 0, - }, - #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 */ diff --git a/arch/arm/mach-rk30/include/mach/rk30_camera.h b/arch/arm/mach-rk30/include/mach/rk30_camera.h index 39a6064fe2a1..4547c529b525 100755 --- a/arch/arm/mach-rk30/include/mach/rk30_camera.h +++ b/arch/arm/mach-rk30/include/mach/rk30_camera.h @@ -46,11 +46,8 @@ #define CAMERA_SCALE_CROP_MACHINE "pp" #endif -#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM) - #define CAMERA_VIDEOBUF_ARM_ACCESS 1 -#else - #define CAMERA_VIDEOBUF_ARM_ACCESS 0 -#endif + +#define CAMERA_VIDEOBUF_ARM_ACCESS 1 #endif diff --git a/arch/arm/plat-rk/include/plat/rk_camera.h b/arch/arm/plat-rk/include/plat/rk_camera.h index caea6a2275e7..e282b27e7789 100755 --- a/arch/arm/plat-rk/include/plat/rk_camera.h +++ b/arch/arm/plat-rk/include/plat/rk_camera.h @@ -24,20 +24,117 @@ #include #include - +#include #define RK29_CAM_PLATFORM_DEV_ID 33 #define RK_CAM_PLATFORM_DEV_ID_0 RK29_CAM_PLATFORM_DEV_ID #define RK_CAM_PLATFORM_DEV_ID_1 (RK_CAM_PLATFORM_DEV_ID_0+1) -#define INVALID_GPIO -1 #define INVALID_VALUE -1 +#define INVALID_GPIO INVALID_VALUE #define RK29_CAM_IO_SUCCESS 0 #define RK29_CAM_EIO_INVALID -1 #define RK29_CAM_EIO_REQUESTFAIL -2 +#define RK29_CAM_POWERACTIVE_BITPOS 0x00 +#define RK29_CAM_RESETACTIVE_BITPOS 0x01 +#define RK29_CAM_POWERDNACTIVE_BITPOS 0x02 +#define RK29_CAM_FLASHACTIVE_BITPOS 0x03 + #define RK_CAM_NUM 6 #define RK29_CAM_SUPPORT_NUMS RK_CAM_NUM #define RK_CAM_SUPPORT_RESOLUTION 0x800000 + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define _CONS4(a,b,c,d) a##b##c##d +#define CONS4(a,b,c,d) _CONS4(a,b,c,d) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define new_camera_device_ex(sensor_name,\ + face,\ + ori,\ + pwr_io,\ + pwr_active,\ + rst_io,\ + rst_active,\ + pwdn_io,\ + pwdn_active,\ + flash_attach,\ + res,\ + mir,\ + i2c_chl,\ + i2c_spd,\ + i2c_addr,\ + cif_chl,\ + mclk)\ + {\ + .dev = {\ + .i2c_cam_info = {\ + I2C_BOARD_INFO(STR(sensor_name), i2c_addr>>1),\ + },\ + .link_info = {\ + .bus_id= RK29_CAM_PLATFORM_DEV_ID+cif_chl,\ + .i2c_adapter_id = i2c_chl,\ + .module_name = STR(sensor_name),\ + },\ + .device_info = {\ + .name = "soc-camera-pdrv",\ + .dev = {\ + .init_name = STR(CONS(_CONS(sensor_name,_),face)),\ + },\ + },\ + },\ + .io = {\ + .gpio_power = pwr_io,\ + .gpio_reset = rst_io,\ + .gpio_powerdown = pwdn_io,\ + .gpio_flash = INVALID_GPIO,\ + .gpio_flag = ((pwr_active&0x01)<>(idx*4))&0x0f) + +#define sensor_PWRSEQ_DEFAULT (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,1)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN,2)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,3)) + +#define ov7675_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov9650_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2655_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov2659_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov7690_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov3640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov3660_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov5640_PWRSEQ sensor_PWRSEQ_DEFAULT +#define ov5642_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define s5k6aa_PWRSEQ sensor_PWRSEQ_DEFAULT +#define s5k5ca_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define mt9d112_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9d113_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9t111_PWRSEQ sensor_PWRSEQ_DEFAULT +#define mt9p111_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define gt2005_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0307_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0308_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0328_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0309_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc0329_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2015_PWRSEQ sensor_PWRSEQ_DEFAULT +#define gc2035_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define siv120b_PWRSEQ sensor_PWRSEQ_DEFAULT +#define siv121d_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sid130B_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define hi253_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hi704_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define nt99160_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99240_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99250_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99252_PWRSEQ sensor_PWRSEQ_DEFAULT +#define nt99340_PWRSEQ sensor_PWRSEQ_DEFAULT + +#define sp0718_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp0838_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp0a19_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp1628_PWRSEQ sensor_PWRSEQ_DEFAULT +#define sp2518_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hm2057_PWRSEQ sensor_PWRSEQ_DEFAULT +#define hm5065_PWRSEQ (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,1)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN,0)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,3)) +#define mtk9335isp_PWRSEQ sensor_PWRSEQ_DEFAULT +#define end_PWRSEQ 0xffffffff + + + /*---------------- Camera Sensor Must Define Macro End ------------------------*/ -#define RK29_CAM_POWERACTIVE_BITPOS 0x00 +//#define RK29_CAM_POWERACTIVE_BITPOS 0x00 #define RK29_CAM_POWERACTIVE_MASK (1<= level) \ - printk(KERN_WARNING"rk_cam_io: " fmt , ## arg); } while (0) + printk(KERN_WARNING"%s(%d):" fmt , CAMMODULE_NAME,__LINE__,## arg); } while (0) -#define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__) +#define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__) +#define eprintk(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__) #define SENSOR_NAME_0 STR(CONFIG_SENSOR_0) /* back camera sensor 0 */ #define SENSOR_NAME_1 STR(CONFIG_SENSOR_1) /* front camera sensor 0 */ @@ -306,11 +307,9 @@ static int rk_sensor_io_init(void); static int rk_sensor_io_deinit(int sensor); static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on); static int rk_sensor_power(struct device *dev, int on); -#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) \ - || (CONFIG_SENSOR_RESET_PIN_01 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_02 != INVALID_GPIO) \ - || (CONFIG_SENSOR_RESET_PIN_11 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_12 != INVALID_GPIO) +static int rk_sensor_register(void); static int rk_sensor_reset(struct device *dev); -#endif + static int rk_sensor_powerdown(struct device *dev, int on); static struct rk29camera_platform_data rk_camera_platform_data = { @@ -318,10 +317,10 @@ static struct rk29camera_platform_data rk_camera_platform_data = { .io_deinit = rk_sensor_io_deinit, .iomux = rk_sensor_iomux, .sensor_ioctrl = rk_sensor_ioctrl, - + .sensor_register = rk_sensor_register, .gpio_res = { { - #if CONFIG_SENSOR_IIC_ADDR_0 + #if defined CONFIG_SENSOR_IIC_ADDR_0 && CONFIG_SENSOR_IIC_ADDR_0 .gpio_reset = CONFIG_SENSOR_RESET_PIN_0, .gpio_power = CONFIG_SENSOR_POWER_PIN_0, .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_0, @@ -339,7 +338,7 @@ static struct rk29camera_platform_data rk_camera_platform_data = { .dev_name = NULL, #endif }, { - #if CONFIG_SENSOR_IIC_ADDR_1 + #if defined CONFIG_SENSOR_IIC_ADDR_1 && CONFIG_SENSOR_IIC_ADDR_1 .gpio_reset = CONFIG_SENSOR_RESET_PIN_1, .gpio_power = CONFIG_SENSOR_POWER_PIN_1, .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_1, @@ -455,11 +454,21 @@ static struct rk29camera_platform_data rk_camera_platform_data = { .info = { { + #ifdef CONFIG_SENSOR_0 .dev_name = SENSOR_DEVICE_NAME_0, .orientation = CONFIG_SENSOR_ORIENTATION_0, + #else + .dev_name = NULL, + .orientation = 0x00, + #endif },{ + #ifdef CONFIG_SENSOR_1 .dev_name = SENSOR_DEVICE_NAME_1, .orientation = CONFIG_SENSOR_ORIENTATION_1, + #else + .dev_name = NULL, + .orientation = 0x00, + #endif #ifdef CONFIG_SENSOR_01 },{ .dev_name = SENSOR_DEVICE_NAME_01, @@ -700,6 +709,7 @@ static struct rk29camera_platform_data rk_camera_platform_data = { }, #endif }, + .register_dev_new = new_camera, }; @@ -714,15 +724,15 @@ static int sensor_power_default_cb (struct rk29camera_gpio_res *res, int on) if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) { if (on) { gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + dprintk("%s PowerPin=%d ..PinLevel = %x \n",res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); msleep(10); } else { gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + dprintk("%s PowerPin=%d ..PinLevel = %x \n",res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); } } else { ret = RK29_CAM_EIO_REQUESTFAIL; - printk("%s..%s..PowerPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_power); + eprintk("%s PowerPin=%d request failed!\n", res->dev_name,camera_power); } } else { ret = RK29_CAM_EIO_INVALID; @@ -742,14 +752,14 @@ static int sensor_reset_default_cb (struct rk29camera_gpio_res *res, int on) 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)); - dprintk("%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + dprintk("%s ResetPin=%d ..PinLevel = %x \n",res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); } else { gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); - dprintk("%s..%s..ResetPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + dprintk("%s ResetPin= %d..PinLevel = %x \n",res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); } } else { ret = RK29_CAM_EIO_REQUESTFAIL; - printk("%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_reset); + eprintk("%s ResetPin=%d request failed!\n", res->dev_name,camera_reset); } } else { ret = RK29_CAM_EIO_INVALID; @@ -769,14 +779,14 @@ static int sensor_powerdown_default_cb (struct rk29camera_gpio_res *res, int on) if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) { if (on) { gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); - dprintk("%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + dprintk("%s PowerDownPin=%d ..PinLevel = %x \n" ,res->dev_name,camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); } else { gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); - dprintk("%s..%s..PowerDownPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + dprintk("%s PowerDownPin= %d..PinLevel = %x \n" ,res->dev_name, camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); } } else { ret = RK29_CAM_EIO_REQUESTFAIL; - dprintk("%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_powerdown); + dprintk("%s PowerDownPin=%d request failed!\n", res->dev_name,camera_powerdown); } } else { ret = RK29_CAM_EIO_INVALID; @@ -799,33 +809,33 @@ static int sensor_flash_default_cb (struct rk29camera_gpio_res *res, int on) case Flash_Off: { gpio_set_value(camera_flash,(((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); - dprintk("\n%s..%s..FlashPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin= %d..PinLevel = %x \n", res->dev_name, camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); break; } case Flash_On: { gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); - dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin=%d ..PinLevel = %x \n", res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); break; } case Flash_Torch: { gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); - dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s FlashPin=%d ..PinLevel = %x \n", res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); break; } default: { - printk("%s..%s..Flash command(%d) is invalidate \n",__FUNCTION__,res->dev_name,on); + eprintk("%s Flash command(%d) is invalidate \n", res->dev_name,on); break; } } } else { ret = RK29_CAM_EIO_REQUESTFAIL; - printk("%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_flash); + eprintk("%s FlashPin=%d request failed!\n", res->dev_name,camera_flash); } } else { ret = RK29_CAM_EIO_INVALID; @@ -836,6 +846,7 @@ static void rk29_sensor_fps_get(int idx, unsigned int *val, int w, int h) { switch (idx) { + #ifdef CONFIG_SENSOR_0 case 0: { if ((w==176) && (h==144)) { @@ -859,6 +870,8 @@ static void rk29_sensor_fps_get(int idx, unsigned int *val, int w, int h) } break; } + #endif + #ifdef CONFIG_SENSOR_1 case 1: { if ((w==176) && (h==144)) { @@ -882,7 +895,7 @@ static void rk29_sensor_fps_get(int idx, unsigned int *val, int w, int h) } break; } - + #endif #ifdef CONFIG_SENSOR_01 case 2: { @@ -985,150 +998,279 @@ static void rk29_sensor_fps_get(int idx, unsigned int *val, int w, int h) } #endif default: - printk(KERN_ERR"rk_cam_io: sensor-%d have not been define in board file!",idx); + eprintk(" sensor-%d have not been define in board file!",idx); } } - -static int rk_sensor_io_init(void) +static int _rk_sensor_io_init_(struct rk29camera_gpio_res *gpio_res) { - int ret = 0, i,j; + int ret = 0, i; unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO; unsigned int camera_ioflag; - static bool is_init = false; - struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; - - if(is_init) { - return 0; - } else { - is_init = true; - } - - if (sensor_ioctl_cb.sensor_power_cb == NULL) - sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb; - if (sensor_ioctl_cb.sensor_reset_cb == NULL) - sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb; - if (sensor_ioctl_cb.sensor_powerdown_cb == NULL) - sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb; - if (sensor_ioctl_cb.sensor_flash_cb == NULL) - sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb; - - for(i = 0;i < RK_CAM_NUM; i++){ - if (plat_data->gpio_res[i].dev_name == NULL) - continue; - camera_reset = plat_data->gpio_res[i].gpio_reset; - camera_power = plat_data->gpio_res[i].gpio_power; - camera_powerdown = plat_data->gpio_res[i].gpio_powerdown; - camera_flash = plat_data->gpio_res[i].gpio_flash; - camera_ioflag = plat_data->gpio_res[i].gpio_flag; - plat_data->gpio_res[i].gpio_init = 0; - - if (camera_power != INVALID_GPIO) { - ret = gpio_request(camera_power, "camera power"); - if (ret) { - for (j=0; jgpio_res[j].gpio_power) - break; - } - if (i==j) { - printk(KERN_ERR"rk_cam_io: %s..%s..power pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power); - goto sensor_io_init_erro; + struct rk29camera_gpio_res *io_res; + bool io_requested_in_camera; + + camera_reset = gpio_res->gpio_reset; + camera_power = gpio_res->gpio_power; + camera_powerdown = gpio_res->gpio_powerdown; + camera_flash = gpio_res->gpio_flash; + camera_ioflag = gpio_res->gpio_flag; + gpio_res->gpio_init = 0; + + if (camera_power != INVALID_GPIO) { + ret = gpio_request(camera_power, "camera power"); + if (ret) { + io_requested_in_camera = false; + for (i=0; igpio_init & RK29_CAM_POWERACTIVE_MASK) { + if (io_res->gpio_power == camera_power) + io_requested_in_camera = true; } } - if (rk_camera_platform_data.iomux(camera_power) < 0) { - printk(KERN_ERR "rk_cam_io: %s..%s..power pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power); - goto sensor_io_init_erro; + if (io_requested_in_camera==false) { + i=0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + io_res = &new_camera[i].io; + if (io_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) { + if (io_res->gpio_power == camera_power) + io_requested_in_camera = true; + } + i++; + } } - plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK; - gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - - dprintk("%s....power pin(%d) init success(0x%x) \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + if (io_requested_in_camera==false) { + printk( "%s power pin(%d) init failed\n", gpio_res->dev_name,camera_power); + goto _rk_sensor_io_init_end_; + } else { + ret =0; + } + } + if (rk_camera_platform_data.iomux(camera_power) < 0) { + ret = -1; + eprintk("%s power pin(%d) iomux init failed\n",gpio_res->dev_name,camera_power); + goto _rk_sensor_io_init_end_; } + + gpio_res->gpio_init |= RK29_CAM_POWERACTIVE_MASK; + gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); - if (camera_reset != INVALID_GPIO) { - ret = gpio_request(camera_reset, "camera reset"); - if (ret) { - for (j=0; jgpio_res[j].gpio_reset) { - break; - } - } - if (i==j) { - printk(KERN_ERR"rk_cam_io: %s..%s..reset pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_reset); - goto sensor_io_init_erro; + dprintk("%s power pin(%d) init success(0x%x) \n" ,gpio_res->dev_name,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + + } + + if (camera_reset != INVALID_GPIO) { + ret = gpio_request(camera_reset, "camera reset"); + if (ret) { + io_requested_in_camera = false; + for (i=0; igpio_init & RK29_CAM_RESETACTIVE_MASK) { + if (io_res->gpio_reset == camera_reset) + io_requested_in_camera = true; } } - if (rk_camera_platform_data.iomux(camera_reset) < 0) { - printk(KERN_ERR"rk_cam_io: %s..%s..reset pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_reset); - goto sensor_io_init_erro; + if (io_requested_in_camera==false) { + i=0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + io_res = &new_camera[i].io; + if (io_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) { + if (io_res->gpio_reset == camera_reset) + io_requested_in_camera = true; + } + i++; + } } - plat_data->gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK; - gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); - gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); - - dprintk("%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + if (io_requested_in_camera==false) { + eprintk("%s reset pin(%d) init failed\n" ,gpio_res->dev_name,camera_reset); + goto _rk_sensor_io_init_end_; + } else { + ret =0; + } + } + if (rk_camera_platform_data.iomux(camera_reset) < 0) { + ret = -1; + eprintk("%s reset pin(%d) iomux init failed\n", gpio_res->dev_name,camera_reset); + goto _rk_sensor_io_init_end_; } + + gpio_res->gpio_init |= RK29_CAM_RESETACTIVE_MASK; + gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); - if (camera_powerdown != INVALID_GPIO) { - ret = gpio_request(camera_powerdown, "camera powerdown"); - if (ret) { - for (j=0; jgpio_res[j].gpio_powerdown) { - break; - } - } - if (i==j) { - printk(KERN_ERR"rk_cam_io: %s..%s..powerdown pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_powerdown); - goto sensor_io_init_erro; + dprintk("%s reset pin(%d) init success(0x%x)\n" ,gpio_res->dev_name,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + + } + + if (camera_powerdown != INVALID_GPIO) { + ret = gpio_request(camera_powerdown, "camera powerdown"); + if (ret) { + io_requested_in_camera = false; + for (i=0; igpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (io_res->gpio_powerdown == camera_powerdown) + io_requested_in_camera = true; } } - if (rk_camera_platform_data.iomux(camera_powerdown) < 0) { - printk(KERN_ERR "rk_cam_io: %s..%s..powerdown pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_powerdown); - goto sensor_io_init_erro; + if (io_requested_in_camera==false) { + i=0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + io_res = &new_camera[i].io; + if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (io_res->gpio_powerdown == camera_powerdown) + io_requested_in_camera = true; + } + i++; + } } - plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK; - gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); - gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); - - dprintk("%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + if (io_requested_in_camera==false) { + eprintk("%s powerdown pin(%d) init failed\n",gpio_res->dev_name,camera_powerdown); + goto _rk_sensor_io_init_end_; + } else { + ret =0; + } + } + if (rk_camera_platform_data.iomux(camera_powerdown) < 0) { + ret = -1; + eprintk("%s powerdown pin(%d) iomux init failed\n",gpio_res->dev_name,camera_powerdown); + goto _rk_sensor_io_init_end_; } + + gpio_res->gpio_init |= RK29_CAM_POWERDNACTIVE_MASK; + gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); - if (camera_flash != INVALID_GPIO) { - ret = gpio_request(camera_flash, "camera flash"); - if (ret) { - for (j=0; jgpio_res[j].gpio_flash) { - break; - } - } - if (i==j) { - printk(KERN_ERR"rk_cam_io: %s..%s..flash pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_flash); - goto sensor_io_init_erro; + dprintk("%s powerdown pin(%d) init success(0x%x) \n" ,gpio_res->dev_name,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + + } + + if (camera_flash != INVALID_GPIO) { + ret = gpio_request(camera_flash, "camera flash"); + if (ret) { + io_requested_in_camera = false; + for (i=0; igpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (io_res->gpio_powerdown == camera_powerdown) + io_requested_in_camera = true; } } - if (rk_camera_platform_data.iomux(camera_flash) < 0) { - printk(KERN_ERR "rk_cam_io: %s..%s..flash pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_flash); + if (io_requested_in_camera==false) { + i=0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + io_res = &new_camera[i].io; + if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (io_res->gpio_powerdown == camera_powerdown) + io_requested_in_camera = true; + } + i++; + } } - plat_data->gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK; - gpio_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); /* falsh off */ - gpio_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + ret = 0; //ddl@rock-chips.com : flash is only a function, sensor is also run; + if (io_requested_in_camera==false) { + eprintk("%s flash pin(%d) init failed\n",gpio_res->dev_name,camera_flash); + goto _rk_sensor_io_init_end_; + } + } + + if (rk_camera_platform_data.iomux(camera_flash) < 0) { + printk("%s flash pin(%d) iomux init failed\n",gpio_res->dev_name,camera_flash); + } + + gpio_res->gpio_init |= RK29_CAM_FLASHACTIVE_MASK; + gpio_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); /* falsh off */ + gpio_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + + dprintk("%s flash pin(%d) init success(0x%x) \n",gpio_res->dev_name, camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + + } +_rk_sensor_io_init_end_: + return ret; + +} + +static int _rk_sensor_io_deinit_(struct rk29camera_gpio_res *gpio_res) +{ + unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; + unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO; + + camera_reset = gpio_res->gpio_reset; + camera_power = gpio_res->gpio_power; + camera_powerdown = gpio_res->gpio_powerdown; + camera_flash = gpio_res->gpio_flash; + + if (gpio_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) { + if (camera_power != INVALID_GPIO) { + gpio_direction_input(camera_power); + gpio_free(camera_power); + } + } - dprintk("%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + if (gpio_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) { + if (camera_reset != INVALID_GPIO) { + gpio_direction_input(camera_reset); + gpio_free(camera_reset); + } + } + + if (gpio_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (camera_powerdown != INVALID_GPIO) { + gpio_direction_input(camera_powerdown); + gpio_free(camera_powerdown); + } + } + + if (gpio_res->gpio_init & RK29_CAM_FLASHACTIVE_MASK) { + if (camera_flash != INVALID_GPIO) { + gpio_direction_input(camera_flash); + gpio_free(camera_flash); + } + } + gpio_res->gpio_init = 0; + + return 0; +} - } +static int rk_sensor_io_init(void) +{ + int i,j; + static bool is_init = false; + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + if(is_init) { + return 0; + } else { + is_init = true; + } + + if (sensor_ioctl_cb.sensor_power_cb == NULL) + sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb; + if (sensor_ioctl_cb.sensor_reset_cb == NULL) + sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb; + if (sensor_ioctl_cb.sensor_powerdown_cb == NULL) + sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb; + if (sensor_ioctl_cb.sensor_flash_cb == NULL) + sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb; + + for(i = 0;i < RK_CAM_NUM; i++) { + if (plat_data->gpio_res[i].dev_name == NULL) + continue; + + if (_rk_sensor_io_init_(&plat_data->gpio_res[i])<0) + goto sensor_io_init_erro; for (j=0; j<10; j++) { memset(&plat_data->info[i].fival[j],0x00,sizeof(struct v4l2_frmivalenum)); @@ -1170,69 +1312,72 @@ static int rk_sensor_io_init(void) continue; sensor_io_init_erro: - rk_sensor_io_deinit(i); + _rk_sensor_io_deinit_(&plat_data->gpio_res[i]); } + + i = 0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + if (_rk_sensor_io_init_(&new_camera[i].io)<0) + _rk_sensor_io_deinit_(&new_camera[i].io); + + i++; + } return 0; } static int rk_sensor_io_deinit(int sensor) { - unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO; + int i; struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; - camera_reset = plat_data->gpio_res[sensor].gpio_reset; - camera_power = plat_data->gpio_res[sensor].gpio_power; - camera_powerdown = plat_data->gpio_res[sensor].gpio_powerdown; - camera_flash = plat_data->gpio_res[sensor].gpio_flash; - - if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) { - if (camera_power != INVALID_GPIO) { - gpio_direction_input(camera_power); - gpio_free(camera_power); - } - } - - if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) { - if (camera_reset != INVALID_GPIO) { - gpio_direction_input(camera_reset); - gpio_free(camera_reset); - } - } + for(i = 0;i < RK_CAM_NUM; i++) { + if (plat_data->gpio_res[i].dev_name == NULL) + continue; + + _rk_sensor_io_deinit_(&plat_data->gpio_res[i]); + } - if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { - if (camera_powerdown != INVALID_GPIO) { - gpio_direction_input(camera_powerdown); - gpio_free(camera_powerdown); - } - } + i = 0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + _rk_sensor_io_deinit_(&new_camera[i].io); - if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) { - if (camera_flash != INVALID_GPIO) { - gpio_direction_input(camera_flash); - gpio_free(camera_flash); - } - } - plat_data->gpio_res[sensor].gpio_init = 0; - + i++; + } + return 0; } static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on) { - struct rk29camera_gpio_res *res = NULL; - int ret = RK29_CAM_IO_SUCCESS,i = 0; - + struct rk29camera_gpio_res *res = NULL; + struct rkcamera_platform_data *new_cam_dev = NULL; struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; - //for test reg + int ret = RK29_CAM_IO_SUCCESS,i = 0; + struct soc_camera_link *dev_icl = NULL; + + //for test reg for(i = 0;i < RK_CAM_NUM;i++){ if(plat_data->gpio_res[i].dev_name && (strcmp(plat_data->gpio_res[i].dev_name, dev_name(dev)) == 0)) { res = (struct rk29camera_gpio_res *)&plat_data->gpio_res[i]; + dev_icl = &plat_data->register_dev[i].link_info; break; } - } + } + + if (res == NULL) { + i = 0; + while (strstr(new_camera[i].dev_name,"end")==NULL) { + if (strcmp(new_camera[i].dev_name, dev_name(dev)) == 0) { + res = (struct rk29camera_gpio_res *)&new_camera[i].io; + new_cam_dev = &new_camera[i]; + dev_icl = &new_camera[i].dev.link_info; + break; + } + i++; + } + } if (res == NULL) { - printk(KERN_ERR "rk_cam_io: %s is not regisiterd in rk29_camera_platform_data!!\n",dev_name(dev)); + eprintk("%s is not regisiterd in rk29_camera_platform_data!!\n",dev_name(dev)); ret = RK29_CAM_EIO_INVALID; goto rk_sensor_ioctrl_end; } @@ -1242,9 +1387,9 @@ static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, i case Cam_Power: { if (sensor_ioctl_cb.sensor_power_cb) { - ret = sensor_ioctl_cb.sensor_power_cb(res, on); + ret = sensor_ioctl_cb.sensor_power_cb(res, on); } else { - printk(KERN_ERR "sensor_ioctl_cb.sensor_power_cb is NULL"); + eprintk("sensor_ioctl_cb.sensor_power_cb is NULL"); WARN_ON(1); } break; @@ -1253,8 +1398,10 @@ static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, i { if (sensor_ioctl_cb.sensor_reset_cb) { ret = sensor_ioctl_cb.sensor_reset_cb(res, on); + + ret = (ret != RK29_CAM_EIO_INVALID)?ret:0; } else { - printk(KERN_ERR "sensor_ioctl_cb.sensor_reset_cb is NULL"); + eprintk( "sensor_ioctl_cb.sensor_reset_cb is NULL"); WARN_ON(1); } break; @@ -1265,7 +1412,7 @@ static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, i if (sensor_ioctl_cb.sensor_powerdown_cb) { ret = sensor_ioctl_cb.sensor_powerdown_cb(res, on); } else { - printk(KERN_ERR "sensor_ioctl_cb.sensor_powerdown_cb is NULL"); + eprintk( "sensor_ioctl_cb.sensor_powerdown_cb is NULL"); WARN_ON(1); } break; @@ -1276,38 +1423,215 @@ static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, i if (sensor_ioctl_cb.sensor_flash_cb) { ret = sensor_ioctl_cb.sensor_flash_cb(res, on); } else { - printk(KERN_ERR "sensor_ioctl_cb.sensor_flash_cb is NULL!"); + eprintk( "sensor_ioctl_cb.sensor_flash_cb is NULL!"); WARN_ON(1); } break; } + + case Cam_Mclk: + { + if (plat_data->sensor_mclk && dev_icl) { + plat_data->sensor_mclk(dev_icl->bus_id,(on!=0)?1:0,on); + } else { + eprintk( "%s(%d): sensor_mclk(%p) or dev_icl(%p) is NULL\n", + __FUNCTION__,__LINE__,plat_data->sensor_mclk,dev_icl); + } + break; + } + default: { - printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd); + eprintk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd); break; } } rk_sensor_ioctrl_end: return ret; } + +static int rk_sensor_pwrseq(struct device *dev,int powerup_sequence, int on, int mclk_rate) +{ + int ret =0; + int i,powerup_type; + + for (i=0; i<8; i++) { + + if (on == 1) + powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence,i); + else + powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence,(7-i)); + + switch (powerup_type) + { + case SENSOR_PWRSEQ_AVDD: + case SENSOR_PWRSEQ_DOVDD: + case SENSOR_PWRSEQ_DVDD: + case SENSOR_PWRSEQ_PWR: + { + ret = rk_sensor_ioctrl(dev,Cam_Power, on); + if (ret<0) { + eprintk("SENSOR_PWRSEQ_PWR failed\n"); + } else { + msleep(10); + dprintk("SensorPwrSeq-power: %d\n",on); + } + break; + } + + case SENSOR_PWRSEQ_HWRST: + { + ret = rk_sensor_ioctrl(dev,Cam_Reset, 1); + msleep(2); + ret |= rk_sensor_ioctrl(dev,Cam_Reset, 0); + if (ret<0) { + eprintk("SENSOR_PWRSEQ_HWRST failed\n"); + } else { + dprintk("SensorPwrSeq-reset: %d\n",on); + } + break; + } + + case SENSOR_PWRSEQ_PWRDN: + { + ret = rk_sensor_ioctrl(dev,Cam_PowerDown, !on); + if (ret<0) { + eprintk("SENSOR_PWRSEQ_PWRDN failed\n"); + } else { + dprintk("SensorPwrSeq-power down: %d \n",!on); + } + break; + } + + case SENSOR_PWRSEQ_CLKIN: + { + ret = rk_sensor_ioctrl(dev,Cam_Mclk, (on?mclk_rate:on)); + if (ret<0) { + eprintk("SENSOR_PWRSEQ_CLKIN failed\n"); + } else { + dprintk("SensorPwrSeq-clock: %d\n",on); + } + break; + } + + default: + break; + } + + } + + return ret; +} + static int rk_sensor_power(struct device *dev, int on) { - if (!on) /* ddl@rock-chips.com : Ensure sensor enter standby or power off */ - rk_sensor_powerdown(dev,1); - rk_sensor_ioctrl(dev,Cam_Power,on); - return 0; + int i, powerup_sequence,mclk_rate; + + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + struct rk29camera_gpio_res *dev_io = NULL; + struct rkcamera_platform_data *new_camera=NULL, *new_device=NULL; + bool real_pwroff = true; + int ret = 0; + + //ddl@rock-chips.com: other sensor must switch into standby before turn on power; + for(i = 0;i < RK_CAM_NUM; i++) { + if (plat_data->gpio_res[i].dev_name == NULL) + continue; + + if (plat_data->gpio_res[i].gpio_powerdown != INVALID_GPIO) { + gpio_direction_output(plat_data->gpio_res[i].gpio_powerdown, + ((plat_data->gpio_res[i].gpio_flag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + } + + if (strcmp(plat_data->gpio_res[i].dev_name,dev_name(dev))) { + if (sensor_ioctl_cb.sensor_powerdown_cb && on) + sensor_ioctl_cb.sensor_powerdown_cb(&plat_data->gpio_res[i],1); + } else { + dev_io = &plat_data->gpio_res[i]; + real_pwroff = true; + } + } + + new_camera = plat_data->register_dev_new; + while (strstr(new_camera->dev_name,"end")==NULL) { + + if (new_camera->io.gpio_powerdown != INVALID_GPIO) { + gpio_direction_output(new_camera->io.gpio_powerdown, + ((new_camera->io.gpio_flag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + } + + if (strcmp(new_camera->dev_name,dev_name(dev))) { + if (sensor_ioctl_cb.sensor_powerdown_cb && on) + sensor_ioctl_cb.sensor_powerdown_cb(&new_camera->io,1); + } else { + new_device = new_camera; + dev_io = &new_camera->io; + + if (!Sensor_Support_DirectResume(new_camera->pwdn_info)) + real_pwroff = true; + else + real_pwroff = false; + } + new_camera++; + } + + if (new_device != NULL) { + powerup_sequence = new_device->powerup_sequence; + if ((new_device->mclk_rate == 24) || (new_device->mclk_rate == 48)) + mclk_rate = new_device->mclk_rate*1000000; + else + mclk_rate = 24000000; + } else { + powerup_sequence = sensor_PWRSEQ_DEFAULT; + mclk_rate = 24000000; + } + + if (on) { + rk_sensor_pwrseq(dev, powerup_sequence, on,mclk_rate); + } else { + if (real_pwroff) { + rk_sensor_pwrseq(dev, powerup_sequence, on,mclk_rate); + + /*ddl@rock-chips.com: all power down switch to Hi-Z after power off*/ + for(i = 0;i < RK_CAM_NUM; i++) { + if (plat_data->gpio_res[i].dev_name == NULL) + continue; + if (plat_data->gpio_res[i].gpio_powerdown != INVALID_GPIO) { + gpio_direction_input(plat_data->gpio_res[i].gpio_powerdown); + } + } + + new_camera = plat_data->register_dev_new; + while (strstr(new_camera->dev_name,"end")==NULL) { + if (new_camera->io.gpio_powerdown != INVALID_GPIO) { + gpio_direction_input(new_camera->io.gpio_powerdown); + } + new_camera->pwdn_info |= 0x01; + new_camera++; + } + } else { + rk_sensor_ioctrl(dev,Cam_PowerDown, !on); + + rk_sensor_ioctrl(dev,Cam_Mclk, 0); + } + + msleep(500); + } + return ret; } -#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) \ - || (CONFIG_SENSOR_RESET_PIN_01 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_02 != INVALID_GPIO) \ - || (CONFIG_SENSOR_RESET_PIN_11 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_12 != INVALID_GPIO) static int rk_sensor_reset(struct device *dev) { +#if 0 rk_sensor_ioctrl(dev,Cam_Reset,1); msleep(2); rk_sensor_ioctrl(dev,Cam_Reset,0); +#else + /* + *ddl@rock-chips.com : the rest function invalidate, because this operate is put together in rk_sensor_power; + */ +#endif return 0; } -#endif static int rk_sensor_powerdown(struct device *dev, int on) { return rk_sensor_ioctrl(dev,Cam_PowerDown,on); @@ -1353,15 +1677,15 @@ int camera_set_platform_param(int id, int i2c, int gpio) if(id < 0 || id >= 6) return -EINVAL; for(i = 0; i < 6; i++){ - if(i == id){ - printk("%s: id = %d, i2c = %d, gpio = %d\n", __func__, id, i2c, gpio); - } - if(rk_camera_platform_data.gpio_res[i].dev_name && - strcmp(rk_camera_platform_data.gpio_res[i].dev_name, dev_name[id]) == 0) - rk_camera_platform_data.gpio_res[i].gpio_powerdown = gpio; - if(rk_camera_platform_data.register_dev[i].link_info.module_name && - strcmp(rk_camera_platform_data.register_dev[i].link_info.module_name, module_name[id]) == 0) - rk_camera_platform_data.register_dev[i].link_info.i2c_adapter_id = i2c; + if(i == id){ + printk("%s: id = %d, i2c = %d, gpio = %d\n", __func__, id, i2c, gpio); + } + if(rk_camera_platform_data.gpio_res[i].dev_name && + strcmp(rk_camera_platform_data.gpio_res[i].dev_name, dev_name[id]) == 0) + rk_camera_platform_data.gpio_res[i].gpio_powerdown = gpio; + if(rk_camera_platform_data.register_dev[i].link_info.module_name && + strcmp(rk_camera_platform_data.register_dev[i].link_info.module_name, module_name[id]) == 0) + rk_camera_platform_data.register_dev[i].link_info.i2c_adapter_id = i2c; } return 0; @@ -1373,5 +1697,55 @@ int camera_set_platform_param(int id, int i2c, int gpio) } #endif +int rk_sensor_register(void) +{ + int i; + + i = 0; + while (strstr(new_camera[i].dev.device_info.dev.init_name,"end")==NULL) { + + if (new_camera[i].dev.i2c_cam_info.addr == INVALID_VALUE) { + WARN(1, + KERN_ERR "%s(%d): new_camera[%d] i2c addr is invalidate!", + __FUNCTION__,__LINE__,i); + continue; + } + + sprintf(new_camera[i].dev_name,"%s_%d",new_camera[i].dev.device_info.dev.init_name,i+3); + new_camera[i].dev.device_info.dev.init_name =(const char*)&new_camera[i].dev_name[0]; + new_camera[i].io.dev_name =(const char*)&new_camera[i].dev_name[0]; + + if (new_camera[i].orientation == INVALID_VALUE) { + if (strstr(new_camera[i].dev_name,"back")) { + new_camera[i].orientation = 90; + } else { + new_camera[i].orientation = 270; + } + } + + new_camera[i].dev.link_info.power = rk_sensor_power; + new_camera[i].dev.link_info.powerdown = rk_sensor_powerdown; + + new_camera[i].dev.link_info.board_info =&new_camera[i].dev.i2c_cam_info; + new_camera[i].dev.device_info.id = i+6; + new_camera[i].dev.device_info.dev.platform_data = &new_camera[i].dev.link_info; + + if (new_camera[i].flash == true) { + if (CONFIG_SENSOR_FLASH_IOCTL_USR == 0) { + eprintk("new_camera[%d] have been configed as attach flash, but CONFIG_SENSOR_FLASH_IOCTL_USR isn't turn on!",i); + + new_camera[i].flash = false; + } + } + + new_camera[i].dev.link_info.priv_usr = &rk_camera_platform_data; + platform_device_register(&new_camera[i].dev.device_info); + i++; + } + + sprintf(new_camera[i].dev_name,"%s",new_camera[i].dev.device_info.dev.init_name); + + return 0; +} #endif diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6cdd07d2b795..0f10c615d09a 100755 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -787,8 +787,8 @@ config SOC_CAMERA_IMX074 tristate "imx074 support" depends on SOC_CAMERA && I2C help - This driver supports IMX074 cameras from Sony - + This driver supports IMX074 cameras from Sony + config SOC_CAMERA_MT9M001 tristate "mt9m001 support" depends on SOC_CAMERA && I2C @@ -814,51 +814,7 @@ config SOC_CAMERA_MT9T031 tristate "mt9t031 support" depends on SOC_CAMERA && I2C help - This driver supports MT9T031 cameras from Micron. - -config SOC_CAMERA_MT9T111 - tristate "mt9t111 support for rockchip" - depends on SOC_CAMERA && I2C - help - This driver supports MT9T111 cameras from Micron for rockchip. - -config MT9T111_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9T111 - bool "MT9T111 user defined init series" - default n - -config SOC_CAMERA_MT9P111 - tristate "mt9p111 support for rockchip" - depends on SOC_CAMERA && I2C - help - This driver supports MT9P111 cameras from Micron for rockchip. - -config MT9P111_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9P111 - bool "MT9P111 user defined init series" - default n - -config SOC_CAMERA_MT9D112 - tristate "mt9d112 support for rockchip" - depends on SOC_CAMERA && I2C - help - This driver supports MT9D112 cameras from Micron for rockchip - -config MT9D112_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9D112 - bool "MT9D112 user defined init series" - default n - -config SOC_CAMERA_MT9D113 - tristate "mt9d113 support for rockchip" - depends on SOC_CAMERA && I2C - help - This driver supports MT9D113 cameras from Micron for rockchip - -config MT9D113_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9D113 - bool "MT9D113 user defined init series" - default n + This driver supports MT9T031 cameras from Micron. config SOC_CAMERA_MT9T112 tristate "mt9t112 support" @@ -866,10 +822,6 @@ config SOC_CAMERA_MT9T112 help This driver supports MT9T112 cameras from Aptina. -config MT9T112_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9T112 - bool "MT9T112 user defined init series" - default n config SOC_CAMERA_MT9V022 tristate "mt9v022 support" @@ -878,10 +830,6 @@ config SOC_CAMERA_MT9V022 help This driver supports MT9V022 cameras from Micron -config MT9V022_USER_DEFINED_SERIES - depends on SOC_CAMERA_MT9V022 - bool "MT9V022 user defined init series" - default n config SOC_CAMERA_RJ54N1 tristate "rj54n1cb0c support" @@ -895,12 +843,6 @@ config SOC_CAMERA_TW9910 help This is a tw9910 video driver -config SOC_CAMERA_PLATFORM - tristate "platform camera support" - depends on SOC_CAMERA - help - This is a generic SoC camera platform driver, useful for testing - config SOC_CAMERA_OV2640 tristate "ov2640 camera support" depends on SOC_CAMERA && I2C @@ -912,16 +854,59 @@ config SOC_CAMERA_OV6650 ---help--- This is a V4L2 SoC camera driver for the OmniVision OV6650 sensor -config OV6650_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV6650 - bool "OV6650 user defined init series" - default n - config SOC_CAMERA_OV772X tristate "ov772x camera support" depends on SOC_CAMERA && I2C help - This is a ov772x camera driver + This is a ov772x camera driver + +config SOC_CAMERA_OV9640 + tristate "ov9640 camera support" + depends on SOC_CAMERA && I2C + help + This is a ov9640 camera driver + + +config SOC_CAMERA_OV9740 + tristate "ov9740 camera support" + depends on SOC_CAMERA && I2C + help + This is a ov9740 camera driver + +config SOC_CAMERA_PLATFORM + tristate "platform camera support" + depends on SOC_CAMERA + help + This is a generic SoC camera platform driver, useful for testing + +menu "ROCKCHIP SUPPORTED SOC CAMERAS" + depends on SOC_CAMERA + +config SOC_CAMERA_MT9T111 + tristate "mt9t111 support for rockchip" + depends on SOC_CAMERA && I2C + help + This driver supports MT9T111 cameras from Micron for rockchip. + +config SOC_CAMERA_MT9P111 + tristate "mt9p111 support for rockchip" + depends on SOC_CAMERA && I2C + help + This driver supports MT9P111 cameras from Micron for rockchip. + +config SOC_CAMERA_MT9D112 + tristate "mt9d112 support for rockchip" + depends on SOC_CAMERA && I2C + help + This driver supports MT9D112 cameras from Micron for rockchip + + +config SOC_CAMERA_MT9D113 + tristate "mt9d113 support for rockchip" + depends on SOC_CAMERA && I2C + help + This driver supports MT9D113 cameras from Micron for rockchip + config SOC_CAMERA_OV7675 tristate "ov7675 camera support for rockchip" @@ -929,21 +914,12 @@ config SOC_CAMERA_OV7675 help This is a ov7675 camera driver for rockchip -config OV7675_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV7675 - bool "OV7675 user defined init series" - default n - config SOC_CAMERA_OV2655 tristate "ov2655 camera support for rockchip" depends on SOC_CAMERA && I2C help This is a ov2655 camera driver for rockchip -config OV2655_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV2655 - bool "OV2655 user defined init series" - default n config SOC_CAMERA_OV2659 tristate "ov2659 camera support for rockchip" @@ -951,10 +927,6 @@ config SOC_CAMERA_OV2659 help This is a ov2659 camera driver for rockchip -config OV2659_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV2659 - bool "OV2659 user defined init series" - default n config SOC_CAMERA_OV7690 tristate "ov7690 camera support for rockchip" @@ -962,10 +934,6 @@ config SOC_CAMERA_OV7690 help This is a ov7690 camera driver for rockchip -config OV7690_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV7690 - bool "OV7690 user defined init series" - default n config SOC_CAMERA_OV9650 tristate "ov9650 camera support for rockchip" @@ -973,10 +941,6 @@ config SOC_CAMERA_OV9650 help This is a ov9650 camera driver for rockchip -config OV9650_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV9650 - bool "OV9650 user defined init series" - default n config SOC_CAMERA_OV2640_RK tristate "ov2640 camera support for rockchip" @@ -984,14 +948,11 @@ config SOC_CAMERA_OV2640_RK help This is a ov2640 camera driver for rockchip -config OV2640_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV2640_RK - bool "OV2640 user defined init series" - default n config SOC_CAMERA_OV3640 tristate "ov3640 camera support for rockchip" - depends on SOC_CAMERA && I2C + depends on SOC_CAMERA && I2C && VIDEO_RK29 + default y help This is a ov3640 camera driver for rockchip @@ -1012,21 +973,18 @@ config OV3640_AUTOFOCUS config OV3640_FIXEDFOCUS bool "OV3640 fixed focus" endchoice - + config SOC_CAMERA_OV3660 tristate "ov3660 camera support for rockchip" depends on SOC_CAMERA && I2C help This is a ov3660 camera driver for rockchip -config OV3660_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV3660 - bool "OV3660 user defined init series" - default n config SOC_CAMERA_OV5642 tristate "ov5642 camera support for rockchip" - depends on SOC_CAMERA && I2C + depends on SOC_CAMERA && I2C && VIDEO_RK29 + default y help This is a ov5642 camera driver for rockchip @@ -1064,7 +1022,8 @@ endchoice config SOC_CAMERA_OV5640 tristate "ov5640 camera support for rockchip" - depends on SOC_CAMERA && I2C + depends on SOC_CAMERA && I2C && VIDEO_RK29 + default y help This is a ov5640 camera driver for rockchip @@ -1086,163 +1045,65 @@ config OV5640_FIXEDFOCUS bool "OV5640 fixed focus" endchoice -config SOC_CAMERA_OV5640_FOR_TD8801 - tristate "ov5640 camera support for td8801" - depends on SOC_CAMERA && I2C - help - This is a ov5640 camera driver for td8801 -choice - prompt "OV5640 Module Focus select" - depends on SOC_CAMERA_OV5640_FOR_TD8801 - default OV5640_AUTOFOCUS_FOR_TD8801 - ---help--- - -config OV5640_AUTOFOCUS_FOR_TD8801 - bool "OV5640 auto focus" - -config OV5640_FIXEDFOCUS_FOR_TD8801 - bool "OV5640 fixed focus" -endchoice - config SOC_CAMERA_S5K6AA tristate "Samsung S5K6AA camera support for rockchip" depends on SOC_CAMERA && I2C help This is a samsung S5K6AA camera driver for rockchip -config S5K6AA_USER_DEFINED_SERIES - depends on SOC_CAMERA_S5K6AA - bool "S5K6AA user defined init series" - default n - config SOC_CAMERA_GT2005 tristate "GT2005 support for rockchip" depends on SOC_CAMERA && I2C help This is a GT2005 camera driver for rockchip -config GT2005_USER_DEFINED_SERIES - depends on SOC_CAMERA_GT2005 - bool "GT2005 user defined init series" - default n - config SOC_CAMERA_GC0307 tristate "GC0307 support for rockchip" depends on SOC_CAMERA && I2C help This is a GC0307 camera driver for rockchip -config GC0307_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC0307 - bool "GC0307 user defined init series" - default n - config SOC_CAMERA_GC0308 tristate "GC0308 support for rockchip" depends on SOC_CAMERA && I2C help This is a GC0308 camera driver for rockchip -config GC0308_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC0308 - bool "GC0308 user defined init series" - default n - -config SOC_CAMERA_GC0308_INTERPOLATION - bool "support sensor interpolation for higher resolution" - depends on SOC_CAMERA_GC0308 -choice - prompt "GC0308 interpolation resolution" - depends on SOC_CAMERA_GC0308_INTERPOLATION - default SOC_CAMERA_GC0308_INTERPOLATION_1M - ---help--- - GC0308 interpolation resolution - -config SOC_CAMERA_GC0308_INTERPOLATION_1M - bool "1 megapixel 1024x768" -config SOC_CAMERA_GC0308_INTERPOLATION_2M - bool "2 megapixel 1600x1200" -config SOC_CAMERA_GC0308_INTERPOLATION_3M - bool "3 megapixel 2048x1536" -endchoice - +config SOC_CAMERA_GC0328 + tristate "GC0328 support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a GC0328 camera driver for rockchip config SOC_CAMERA_GC0309 tristate "GC0309 support for rockchip" depends on SOC_CAMERA && I2C help This is a GC0309 camera driver for rockchip -config GC0309_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC0309 - bool "GC0309 user defined init series" - default n - -config SOC_CAMERA_GC0309_FOR_TD8801 - tristate "GC0309 support for td8801" - depends on SOC_CAMERA && I2C - help - This is a GC0309 camera driver for td8801 - config SOC_CAMERA_GC2015 tristate "GC2015 support for rockchip" depends on SOC_CAMERA && I2C help This is a GC2015 camera driver for rockchip -config GC2015_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC2015 - bool "GC2015 user defined init series" - default n - config SOC_CAMERA_GC2035 tristate "GC2035 support for rockchip" depends on SOC_CAMERA && I2C help This is a GC2035 camera driver for rockchip -config GC2035_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC2035 - bool "GC2035 user defined init series" - default n - config SOC_CAMERA_HI253 tristate "HI253 support for rockchip" depends on SOC_CAMERA && I2C help This is a HI253 camera driver for rockchip -config HI253_USER_DEFINED_SERIES - depends on SOC_CAMERA_HI253 - bool "HI253 user defined init series" - default n - -config SOC_CAMERA_HI253_INTERPOLATION - bool "support sensor interpolation for higher resolution" - depends on SOC_CAMERA_HI253 - -choice - prompt "HI253 interpolation resolution" - depends on SOC_CAMERA_HI253_INTERPOLATION - default SOC_CAMERA_HI253_INTERPOLATION_3M - ---help--- - HI253 interpolation resolution - -config SOC_CAMERA_HI253_INTERPOLATION_3M - bool "3 megapixel 2048x1536" -config SOC_CAMERA_HI253_INTERPOLATION_5M - bool "5 megapixel 2592x1944" -endchoice - config SOC_CAMERA_HI704 tristate "HI704 support for rockchip" depends on SOC_CAMERA && I2C help This is a HI704 camera driver for rockchip -config HI704_USER_DEFINED_SERIES - depends on SOC_CAMERA_HI704 - bool "HI704 user defined init series" - default n config SOC_CAMERA_SIV120B tristate "siv120b support for rockchip" @@ -1250,10 +1111,6 @@ config SOC_CAMERA_SIV120B help This is a SIV120B camera driver for rockchip -config SIV120B_USER_DEFINED_SERIES - depends on SOC_CAMERA_SIV120B - bool "SIV120B user defined init series" - default n config SOC_CAMERA_SIV121D tristate "siv121d support for rockchip" @@ -1267,21 +1124,35 @@ config SOC_CAMERA_SID130B help This is a SID130B camera driver for rockchip -config SID130B_USER_DEFINED_SERIES - depends on SOC_CAMERA_SID130B - bool "SID130B user defined init series" - default n +config SOC_CAMERA_NT99160 + tristate "NT99160 support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a NT99160 camera driver for rockchip + +config SOC_CAMERA_NT99240 + tristate "NT99240 support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a NT99240 camera driver for rockchip config SOC_CAMERA_NT99250 tristate "NT99250 support for rockchip" depends on SOC_CAMERA && I2C help This is a NT99250 camera driver for rockchip - -config NT99250_USER_DEFINED_SERIES - depends on SOC_CAMERA_NT99250 - bool "NT99250 user defined init series" - default n + +config SOC_CAMERA_NT99252 + tristate "NT99252 support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a NT99252 camera driver for rockchip + +config SOC_CAMERA_NT99340 + tristate "NT99340 support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a NT99340 camera driver for rockchip config SOC_CAMERA_GC0329 tristate "gc0329 camera support for rockchip" @@ -1289,21 +1160,18 @@ config SOC_CAMERA_GC0329 help This is a gc0329 camera driver for rockchip -config GC0329_USER_DEFINED_SERIES - depends on SOC_CAMERA_GC0329 - bool "GC0329 user defined init series" - default n config SOC_CAMERA_S5K5CA tristate "s5k5ca camera support for rockchip" depends on SOC_CAMERA && I2C help This is a s5k5ca camera driver for rockchip - -config S5K5CA_USER_DEFINED_SERIES - depends on SOC_CAMERA_S5K5CA - bool "s5k5ca user defined init series" - default n + +config SOC_CAMERA_SP0718 + tristate "sp0718 camera support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a sp0718 camera driver for rockchip config SOC_CAMERA_SP0838 tristate "sp0838 camera support for rockchip" @@ -1311,10 +1179,6 @@ config SOC_CAMERA_SP0838 help This is a sp0838 camera driver for rockchip -config SP0838_USER_DEFINED_SERIES - depends on SOC_CAMERA_SP0838 - bool "sp0838 user defined init series" - default n config SOC_CAMERA_SP2518 tristate "sp2518 camera support for rockchip" @@ -1322,10 +1186,11 @@ config SOC_CAMERA_SP2518 help This is a sp2518 camera driver for rockchip -config SP2518_USER_DEFINED_SERIES - depends on SOC_CAMERA_SP2518 - bool "sp2518 user defined init series" - default n +config SOC_CAMERA_HM2057 + tristate "hm2057 camera support for rockchip" + depends on SOC_CAMERA && I2C + help + This is a HM2057 camera driver for rockchip config SOC_CAMERA_HM5065 tristate "hm5065 camera support for rockchip" @@ -1333,28 +1198,6 @@ config SOC_CAMERA_HM5065 help This is a HM5065 camera driver for rockchip - -config SOC_CAMERA_OV9640 - tristate "ov9640 camera support" - depends on SOC_CAMERA && I2C - help - This is a ov9640 camera driver - -config OV9640_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV9640 - bool "OV9640 user defined init series" - default n - -config SOC_CAMERA_OV9740 - tristate "ov9740 camera support" - depends on SOC_CAMERA && I2C - help - This is a ov9740 camera driver - -config OV9740_USER_DEFINED_SERIES - depends on SOC_CAMERA_OV9740 - bool "OV9740 user defined init series" - default n config SOC_CAMERA_MV9335 tristate "MtekVision camera isp chip" depends on SOC_CAMERA && I2C @@ -1363,64 +1206,6 @@ config SOC_CAMERA_MV9335 source "drivers/media/video/mv9335/Kconfig" -config MX1_VIDEO - bool - -config VIDEO_MX1 - tristate "i.MX1/i.MXL CMOS Sensor Interface driver" - depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA - select FIQ - select VIDEOBUF_DMA_CONTIG - select MX1_VIDEO - ---help--- - This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface - -config MX3_VIDEO - bool - -config VIDEO_MX3 - tristate "i.MX3x Camera Sensor Interface driver" - depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA - select VIDEOBUF2_DMA_CONTIG - select MX3_VIDEO - ---help--- - This is a v4l2 driver for the i.MX3x Camera Sensor Interface - -config VIDEO_PXA27x - tristate "PXA27x Quick Capture Interface driver" - depends on VIDEO_DEV && PXA27x && SOC_CAMERA - select VIDEOBUF_DMA_SG - ---help--- - This is a v4l2 driver for the PXA27x Quick Capture Interface - -config VIDEO_SH_MOBILE_CSI2 - tristate "SuperH Mobile MIPI CSI-2 Interface driver" - depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK - ---help--- - This is a v4l2 driver for the SuperH MIPI CSI-2 Interface - -config VIDEO_SH_MOBILE_CEU - tristate "SuperH Mobile CEU Interface driver" - depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK - select VIDEOBUF2_DMA_CONTIG - ---help--- - This is a v4l2 driver for the SuperH Mobile CEU Interface - -config VIDEO_OMAP1 - tristate "OMAP1 Camera Interface driver" - depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA - select VIDEOBUF_DMA_CONTIG - select VIDEOBUF_DMA_SG - ---help--- - This is a v4l2 driver for the TI OMAP1 camera interface - -config VIDEO_OMAP2 - tristate "OMAP2 Camera Capture Interface driver" - depends on VIDEO_DEV && ARCH_OMAP2 - select VIDEOBUF_DMA_SG - ---help--- - This is a v4l2 driver for the TI OMAP2 camera capture interface - config VIDEO_RK29 tristate "RKXX Camera Sensor Interface driver" depends on VIDEO_DEV && PLAT_RK && SOC_CAMERA && HAS_DMA @@ -1495,6 +1280,68 @@ config VIDEO_RKCIF_WORK_SIMUL_ON config VIDEO_RKCIF_WORK_SIMUL_OFF bool "Two cif controller cann't work sumultaneity" endchoice +endmenu + + +config MX1_VIDEO + bool + +config VIDEO_MX1 + tristate "i.MX1/i.MXL CMOS Sensor Interface driver" + depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA + select FIQ + select VIDEOBUF_DMA_CONTIG + select MX1_VIDEO + ---help--- + This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface + +config MX3_VIDEO + bool + +config VIDEO_MX3 + tristate "i.MX3x Camera Sensor Interface driver" + depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA + select VIDEOBUF2_DMA_CONTIG + select MX3_VIDEO + ---help--- + This is a v4l2 driver for the i.MX3x Camera Sensor Interface + +config VIDEO_PXA27x + tristate "PXA27x Quick Capture Interface driver" + depends on VIDEO_DEV && PXA27x && SOC_CAMERA + select VIDEOBUF_DMA_SG + ---help--- + This is a v4l2 driver for the PXA27x Quick Capture Interface + +config VIDEO_SH_MOBILE_CSI2 + tristate "SuperH Mobile MIPI CSI-2 Interface driver" + depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK + ---help--- + This is a v4l2 driver for the SuperH MIPI CSI-2 Interface + +config VIDEO_SH_MOBILE_CEU + tristate "SuperH Mobile CEU Interface driver" + depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK + select VIDEOBUF2_DMA_CONTIG + ---help--- + This is a v4l2 driver for the SuperH Mobile CEU Interface + +config VIDEO_OMAP1 + tristate "OMAP1 Camera Interface driver" + depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA + select VIDEOBUF_DMA_CONTIG + select VIDEOBUF_DMA_SG + ---help--- + This is a v4l2 driver for the TI OMAP1 camera interface + +config VIDEO_OMAP2 + tristate "OMAP2 Camera Capture Interface driver" + depends on VIDEO_DEV && ARCH_OMAP2 + select VIDEOBUF_DMA_SG + ---help--- + This is a v4l2 driver for the TI OMAP2 camera capture interface + + config VIDEO_MX2_HOSTSUPPORT bool diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 91e07a64776b..9ea35851f767 100755 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -104,8 +104,8 @@ obj-$(CONFIG_SOC_CAMERA_S5K6AA) += s5k6aa.o obj-$(CONFIG_SOC_CAMERA_GT2005) += gt2005.o obj-$(CONFIG_SOC_CAMERA_GC0307) += gc0307.o obj-$(CONFIG_SOC_CAMERA_GC0308) += gc0308.o +obj-$(CONFIG_SOC_CAMERA_GC0328) += gc0328.o obj-$(CONFIG_SOC_CAMERA_GC0309) += gc0309.o -obj-$(CONFIG_SOC_CAMERA_GC0309_FOR_TD8801) += gc0309_for_td8801.o obj-$(CONFIG_SOC_CAMERA_GC2015) += gc2015.o obj-$(CONFIG_SOC_CAMERA_GC2035) += gc2035.o obj-$(CONFIG_SOC_CAMERA_SIV120B) += siv120b.o @@ -113,11 +113,17 @@ obj-$(CONFIG_SOC_CAMERA_SIV121D) += siv121d.o obj-$(CONFIG_SOC_CAMERA_SID130B) += sid130B.o obj-$(CONFIG_SOC_CAMERA_HI253) += hi253.o obj-$(CONFIG_SOC_CAMERA_HI704) += hi704.o +obj-$(CONFIG_SOC_CAMERA_NT99160) += nt99160_2way.o +obj-$(CONFIG_SOC_CAMERA_NT99240) += nt99240_2way.o obj-$(CONFIG_SOC_CAMERA_NT99250) += nt99250.o +obj-$(CONFIG_SOC_CAMERA_NT99252) += nt99252_3way.o +obj-$(CONFIG_SOC_CAMERA_NT99340) += nt99340_2way.o obj-$(CONFIG_SOC_CAMERA_GC0329) += gc0329.o +#obj-$(CONFIG_SOC_CAMERA_SP0718) += sp0718.o obj-$(CONFIG_SOC_CAMERA_SP0838) += sp0838.o obj-$(CONFIG_SOC_CAMERA_SP2518) += sp2518.o 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/ @@ -216,6 +222,8 @@ ifeq ($(CONFIG_ARCH_RK29),y) obj-$(CONFIG_VIDEO_RKCIF_WORK_ONEFRAME) += rk29_camera_oneframe.o obj-$(CONFIG_VIDEO_RKCIF_WORK_PINGPONG) += rk29_camera_pingpang.o endif +obj-$(CONFIG_VIDEO_RKCIF_WORK_ONEFRAME) += generic_sensor.o +obj-$(CONFIG_VIDEO_RKCIF_WORK_PINGPONG) += generic_sensor.o obj-$(CONFIG_VIDEO_RK29XX_VOUT) += rk29xx/ obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o diff --git a/drivers/media/video/gc0307.c b/drivers/media/video/gc0307.c index 79c2ec36b6f4..85bf05e5925c 100755 --- a/drivers/media/video/gc0307.c +++ b/drivers/media/video/gc0307.c @@ -1,3079 +1,1279 @@ - + +#include "generic_sensor.h" + /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GC0307 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0307 -#define SENSOR_ID 0x99 -#define SENSOR_MIN_WIDTH 640//176 -#define SENSOR_MIN_HEIGHT 480//144 -#define SENSOR_MAX_WIDTH 800//1600 -#define SENSOR_MAX_HEIGHT 600//1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#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 0 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 100000//250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) -struct reginfo -{ - u8 reg; - u8 val; -}; - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_GC0307_USER_DEFINED_SERIES -#include "gc0307_user_series.c" -#else -/* init 640X480 VGA */ -static struct reginfo sensor_init_data[] = -{ -//========= close output - {0x43 ,0x00}, - {0x44 ,0xa2}, - - //========= close some functions - // open them after configure their parmameters - {0x40 ,0x10}, - {0x41 ,0x00}, - {0x42 ,0x10}, - {0x47 ,0x00}, //mode1, - {0x48 ,0xc3}, //mode2, - {0x49 ,0x00}, //dither_mode - {0x4a ,0x00}, //clock_gating_en - {0x4b ,0x00}, //mode_reg3 - {0x4E ,0x22},//0x23}, //sync mode yaowei - {0x4F ,0x01}, //AWB, AEC, every N frame - - //========= frame timing - {0x01 ,0x6a}, //HB - {0x02 ,0x70}, //VB - {0x1C ,0x00}, //Vs_st - {0x1D ,0x00}, //Vs_et - {0x10 ,0x00}, //high 4 bits of VB, HB - {0x11 ,0x05}, //row_tail, AD_pipe_number - - - - - - //========= windowing - {0x05 ,0x00}, //row_start - {0x06 ,0x00}, - {0x07 ,0x00}, //col start - {0x08 ,0x00}, - {0x09 ,0x01}, //win height - {0x0A ,0xE8}, - {0x0B ,0x02}, //win width, pixel array only 640 - {0x0C ,0x80}, - - //========= analog - {0x0D ,0x22}, //rsh_width - - {0x0E ,0x02}, //CISCTL mode2, - - - {0x12 ,0x70}, //7 hrst, 6_4 darsg, - {0x13 ,0x00}, //7 CISCTL_restart, 0 apwd - {0x14 ,0x00}, //NA - {0x15 ,0xba}, //7_4 vref - {0x16 ,0x13}, //5to4 _coln_r, __1to0__da18 - {0x17 ,0x52}, //opa_r, ref_r, sRef_r - //{0x18 ,0xc0}, //analog_mode, best case for left band. - - {0x1E ,0x0d}, //tsp_width - {0x1F ,0x32}, //sh_delay - - //========= offset - {0x47 ,0x00}, //7__test_image, __6__fixed_pga, __5__auto_DN, __4__CbCr_fix, - //__3to2__dark_sequence, __1__allow_pclk_vcync, __0__LSC_test_image - {0x19 ,0x06}, //pga_o - {0x1a ,0x06}, //pga_e - - {0x31 ,0x00}, //4 //pga_oFFset , high 8bits of 11bits - {0x3B ,0x00}, //global_oFFset, low 8bits of 11bits - - {0x59 ,0x0f}, //offset_mode - {0x58 ,0x88}, //DARK_VALUE_RATIO_G, DARK_VALUE_RATIO_RB - {0x57 ,0x08}, //DARK_CURRENT_RATE - {0x56 ,0x77}, //PGA_OFFSET_EVEN_RATIO, PGA_OFFSET_ODD_RATIO - - //========= blk - {0x35 ,0xd8}, //blk_mode - - {0x36 ,0x40}, - - {0x3C ,0x00}, - {0x3D ,0x00}, - {0x3E ,0x00}, - {0x3F ,0x00}, - - {0xb5 ,0x70}, - {0xb6 ,0x40}, - {0xb7 ,0x00}, - {0xb8 ,0x38}, - {0xb9 ,0xc3}, - {0xba ,0x0f}, - - {0x7e ,0x50},//0x45 ylz++ - {0x7f ,0x76}, //0x66 - - {0x5c ,0x48}, //78 - {0x5d ,0x58}, //88 - - - //========= manual_gain - {0x61 ,0x80}, //manual_gain_g1 - {0x63 ,0x80}, //manual_gain_r - {0x65 ,0x98}, //manual_gai_b, 0xa0=1.25, 0x98=1.1875 - {0x67 ,0x80}, //manual_gain_g2 - {0x68 ,0x18}, //global_manual_gain 2.4bits - - //=========CC _R - {0x69 ,0x58}, //54 - {0x6A ,0xf6}, //ff - {0x6B ,0xfb}, //fe - {0x6C ,0xf4}, //ff - {0x6D ,0x5a}, //5f - {0x6E ,0xe6}, //e1 - - {0x6f ,0x00}, - - //=========lsc - {0x70 ,0x14}, - {0x71 ,0x1c}, - {0x72 ,0x20}, - - {0x73 ,0x10}, - {0x74 ,0x3c}, - {0x75 ,0x52}, - - //=========dn - {0x7d ,0x2f}, //dn_mode - {0x80 ,0x0c}, //when auto_dn, check 7e,7f - {0x81 ,0x0c}, - {0x82 ,0x44}, - - //dd - {0x83 ,0x18}, //DD_TH1 - {0x84 ,0x18}, //DD_TH2 - {0x85 ,0x04}, //DD_TH3 - {0x87 ,0x34}, //32 b DNDD_low_range X16, DNDD_low_range_C_weight_center - - - //=========intp-ee - {0x88 ,0x04}, - {0x89 ,0x01}, - {0x8a ,0x50},//60 - {0x8b ,0x50},//60 - {0x8c ,0x07}, - - {0x50 ,0x0c}, - {0x5f ,0x3c}, - - {0x8e ,0x02}, - {0x86 ,0x02}, - - {0x51 ,0x20}, - {0x52 ,0x08}, - {0x53 ,0x00}, - - - //========= YCP - //contrast_center - {0x77 ,0x80}, //contrast_center - {0x78 ,0x00}, //fixed_Cb - {0x79 ,0x00}, //fixed_Cr - {0x7a ,0x00}, //luma_offset - {0x7b ,0x40}, //hue_cos - {0x7c ,0x00}, //hue_sin - - //saturation - {0xa0 ,0x40}, //global_saturation - {0xa1 ,0x42}, //luma_contrast - {0xa2 ,0x40}, //saturation_Cb //ylz 34 - {0xa3 ,0x34}, //saturation_Cr - - {0xa4 ,0xc8}, - {0xa5 ,0x02}, - {0xa6 ,0x28}, - {0xa7 ,0x02}, - - //skin - {0xa8 ,0xee}, - {0xa9 ,0x12}, - {0xaa ,0x01}, - {0xab ,0x20}, - {0xac ,0xf0}, - {0xad ,0x10}, - - //========= ABS - {0xae ,0x18}, - {0xaf ,0x74}, - {0xb0 ,0xe0}, - {0xb1 ,0x20}, - {0xb2 ,0x6c}, - {0xb3 ,0x40}, - {0xb4 ,0x04}, - - //========= AWB - {0xbb ,0x42}, - {0xbc ,0x60}, - {0xbd ,0x50}, - {0xbe ,0x50}, - - {0xbf ,0x0c}, - {0xc0 ,0x06}, - {0xc1 ,0x60}, - {0xc2 ,0xf1}, //f1 - {0xc3 ,0x40}, - {0xc4 ,0x1c}, //18//20 - {0xc5 ,0x56}, //33 - {0xc6 ,0x1d}, - - {0xca ,0x70}, - {0xcb ,0x70}, - {0xcc ,0x78}, - - {0xcd ,0x80}, //R_ratio - {0xce ,0x80}, //G_ratio , cold_white white - {0xcf ,0x80}, //B_ratio - - //========= aecT - {0x20 ,0x06},//0x02 - {0x21 ,0xc0}, - {0x22 ,0x40}, - {0x23 ,0x88}, - {0x24 ,0x96}, - {0x25 ,0x30}, - {0x26 ,0xd0}, - {0x27 ,0x00}, - - {0x28 ,0x02}, //AEC_exp_level_1bit11to8 - {0x29 ,0x58}, //AEC_exp_level_1bit7to0 - {0x2a ,0x03}, //AEC_exp_level_2bit11to8 - {0x2b ,0x84}, //AEC_exp_level_2bit7to0 - {0x2c ,0x09}, //AEC_exp_level_3bit11to8 659 - 8FPS, 8ca - 6FPS // - {0x2d ,0x60}, //AEC_exp_level_3bit7to0 - {0x2e ,0x0a}, //AEC_exp_level_4bit11to8 4FPS - {0x2f ,0x8c}, //AEC_exp_level_4bit7to0 - - {0x30 ,0x20}, - {0x31 ,0x00}, - {0x32 ,0x1c}, - {0x33 ,0x90}, - {0x34 ,0x10}, - - {0xd0 ,0x34}, - - {0xd1 ,0x40}, //AEC_target_Y - {0xd2 ,0x61},//0xf2 - {0xd4 ,0x96}, - {0xd5 ,0x01}, // william 0318 - {0xd6 ,0x96}, //antiflicker_step - {0xd7 ,0x03}, //AEC_exp_time_min ,william 20090312 - {0xd8 ,0x02}, - - {0xdd ,0x12},//0x12 - - //========= measure window - {0xe0 ,0x03}, - {0xe1 ,0x02}, - {0xe2 ,0x27}, - {0xe3 ,0x1e}, - {0xe8 ,0x3b}, - {0xe9 ,0x6e}, - {0xea ,0x2c}, - {0xeb ,0x50}, - {0xec ,0x73}, - - //========= close_frame - {0xed ,0x00}, //close_frame_num1 ,can be use to reduce FPS - {0xee ,0x00}, //close_frame_num2 - {0xef ,0x00}, //close_frame_num - - // page1 - {0xf0 ,0x01}, //select page1 - - {0x00 ,0x20}, - {0x01 ,0x20}, - {0x02 ,0x20}, - {0x03 ,0x20}, - {0x04 ,0x78}, - {0x05 ,0x78}, - {0x06 ,0x78}, - {0x07 ,0x78}, - - - - {0x10 ,0x04}, - {0x11 ,0x04}, - {0x12 ,0x04}, - {0x13 ,0x04}, - {0x14 ,0x01}, - {0x15 ,0x01}, - {0x16 ,0x01}, - {0x17 ,0x01}, - - - {0x20 ,0x00}, - {0x21 ,0x00}, - {0x22 ,0x00}, - {0x23 ,0x00}, - {0x24 ,0x00}, - {0x25 ,0x00}, - {0x26 ,0x00}, - {0x27 ,0x00}, - - {0x40 ,0x11}, - - //=============================lscP - {0x45 ,0x06}, - {0x46 ,0x06}, - {0x47 ,0x05}, - - {0x48 ,0x04}, - {0x49 ,0x03}, - {0x4a ,0x03}, - - - {0x62 ,0xd8}, - {0x63 ,0x24}, - {0x64 ,0x24}, - {0x65 ,0x24}, - {0x66 ,0xd8}, - {0x67 ,0x24}, - - {0x5a ,0x00}, - {0x5b ,0x00}, - {0x5c ,0x00}, - {0x5d ,0x00}, - {0x5e ,0x00}, - {0x5f ,0x00}, - - - //============================= ccP - - {0x69 ,0x03}, //cc_mode - - //CC_G - {0x70 ,0x5d}, - {0x71 ,0xed}, - {0x72 ,0xff}, - {0x73 ,0xe5}, - {0x74 ,0x5f}, - {0x75 ,0xe6}, - - //CC_B - {0x76 ,0x41}, - {0x77 ,0xef}, - {0x78 ,0xff}, - {0x79 ,0xff}, - {0x7a ,0x5f}, - {0x7b ,0xfa}, - - - //============================= AGP - - {0x7e ,0x00}, - {0x7f ,0x20}, //x040 - {0x80 ,0x48}, - {0x81 ,0x06}, - {0x82 ,0x08}, - - {0x83 ,0x23}, - {0x84 ,0x38}, - {0x85 ,0x4F}, - {0x86 ,0x61}, - {0x87 ,0x72}, - {0x88 ,0x80}, - {0x89 ,0x8D}, - {0x8a ,0xA2}, - {0x8b ,0xB2}, - {0x8c ,0xC0}, - {0x8d ,0xCA}, - {0x8e ,0xD3}, - {0x8f ,0xDB}, - {0x90 ,0xE2}, - {0x91 ,0xED}, - {0x92 ,0xF6}, - {0x93 ,0xFD}, - - //about gamma1 is hex r oct - {0x94 ,0x04}, - {0x95 ,0x0E}, - {0x96 ,0x1B}, - {0x97 ,0x28}, - {0x98 ,0x35}, - {0x99 ,0x41}, - {0x9a ,0x4E}, - {0x9b ,0x67}, - {0x9c ,0x7E}, - {0x9d ,0x94}, - {0x9e ,0xA7}, - {0x9f ,0xBA}, - {0xa0 ,0xC8}, - {0xa1 ,0xD4}, - {0xa2 ,0xE7}, - {0xa3 ,0xF4}, - {0xa4 ,0xFA}, - - //========= open functions - {0xf0 ,0x00}, //set back to page0 - {0x40 ,0x7e}, - {0x41 ,0x2F}, - -///// Çë×¢Ò⣬µ÷ÕûGC0307µÄ¾µÏñºÍ·­×ª£¬ÐèҪͬʱÐÞ¸ÄÈý¸ö¼Ä´æÆ÷£¬ÈçÏÂ: - - {0x0f, 0x92}, - {0x45, 0x25}, - {0x47, 0x24}, -///banding setting - { 0x01 ,0xfa}, // 24M - { 0x02 ,0x70}, - { 0x10 ,0x01}, - { 0xd6 ,0x64}, - { 0x28 ,0x02}, - { 0x29 ,0x58}, - { 0x2a ,0x02}, - { 0x2b ,0x58}, - { 0x2c ,0x02}, - { 0x2d ,0x58}, - { 0x2e ,0x06}, - { 0x2f ,0x40}, - - /************ - {0x0f, 0x02},//82 - {0x45, 0x24}, - {0x47, 0x20}, - **************/ -///// ËÄÖÖ²»Í¬µÄ·­×ªºÍ¾µÏñÉ趨£¬¿Í»§¿ÉÖ±½Ó¸´ÖÆ!!!!!! - - -#if 0 -// IMAGE_NORMAL: - {0x0f, 0xb2}, - {0x45, 0x27}, - {0x47, 0x2c}, - -// IMAGE_H_MIRROR: - {0x0f, 0xa2}, - {0x45, 0x26}, - {0x47, 0x28}, - -// IMAGE_V_MIRROR: - {0x0f, 0x92}, - {0x45, 0x25}, - {0x47, 0x24}, - -// IMAGE_HV_MIRROR: // 180 - {0x0f, 0x82}, - {0x45, 0x24}, - {0x47, 0x20}, -#endif -{0x43, 0x40}, - {0x44, 0xe2}, -{0xff, 0xff}, -}; - -static struct reginfo sensor_720p[]= -{ - {0xff, 0xff}, -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0xff, 0xff}, - -}; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0xff, 0xff}, - -}; - -/* 640X480 VGA */ - -static struct reginfo sensor_vga[] = -{ -#if 1 -{ 0x05 , 0x00}, -{ 0x06 , 0x00}, -{ 0x07 , 0x00}, -{ 0x08 , 0x00},//0x10 james 20100715 -{ 0x09 , 0x01}, -{ 0x0a , 0xe8}, -{ 0x0b , 0x02}, -{ 0x0c , 0x88},//0x80 james 20100715 -{ 0x45 , 0x24}, // bit[7:2]=001001 -{ 0x48 , 0x84}, // bit[7]=1 -{ 0xe0 , 0x03}, -{ 0xe1 , 0x02}, -{ 0xe2 , 0x27}, -{ 0xe3 , 0x1e}, -{ 0xe8 , 0x3b}, -{ 0xe9 , 0x6e}, -{ 0xea , 0x2c}, -{ 0xeb , 0x50}, -{ 0xec , 0x73}, -#else -{0x17, 0x13}, -{0x18, 0x01}, -{0x32, 0xbf}, -{0x19, 0x03}, -{0x1a, 0x7b}, -{0x03, 0x0a}, - -#endif - {0xff, 0xff}, - - -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0xff, 0xff}, - -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {0xff, 0xff}, - -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - {0xff, 0xff}, - -}; -#endif -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0xff, 0xff}, - -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0xff, 0xff}, - -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0xc7,0x4c}, //for AWB can adjust back - {0xc8,0x40}, - {0xc9,0x4a}, - {0x41,0x2f}, - {0xff, 0xff}, - - - -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x41,0x2b}, // Enable AWB - {0xc7,0x5a}, //WB_manual_gain - {0xc8,0x42}, - {0xc9,0x40}, - {0xff, 0xff}, - - -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x41,0x2b}, // Enable AWB - {0xc7,0x50}, - {0xc8,0x45}, - {0xc9,0x40}, - {0xff, 0xff}, - - -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x41,0x2b}, // Enable AWB - {0xc7,0x48}, - {0xc8,0x40}, - {0xc9,0x5c}, - {0xff, 0xff}, - - - - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x41,0x2b}, // Enable AWB - {0xc7,0x40}, - {0xc8,0x42}, - {0xc9,0x50}, - {0xff, 0xff}, - - -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - {0x7a, 0xe0}, - {0xff, 0xff}, - -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - {0x7a, 0xf0}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - {0x7a, 0x00}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - {0x7a, 0x10}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - {0x7a, 0x20}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - {0x7a, 0x30}, - {0xff, 0xff}, -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x41,0x2f}, // 1 - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x24},//20 - {0x48,0xc3}, - {0x8a,0x50},//60 - {0x8b,0x50}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0x00}, - {0x79,0x00}, - {0x7b,0x40}, - {0x7c,0x00}, - {0xff, 0xff}, - -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x41,0x2f}, // danse - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x3c}, - {0x48,0xc3}, - {0x8a,0x60}, - {0x8b,0x60}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0x00}, - {0x79,0x00}, - {0x7b,0x40}, - {0x7c,0x00}, - {0xff,0xff}, -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x41,0x2f}, - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x3c}, - {0x48,0xc3}, - {0x8a,0x60}, - {0x8b,0x60}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0xc0}, - {0x79,0x20}, - {0x7b,0x40}, - {0x7c,0x00}, - {0xff,0xff}, - - - -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x41,0x6f}, // 4 - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x20}, - {0x48,0xc3}, - {0x8a,0x60}, - {0x8b,0x60}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0x00}, - {0x79,0x00}, - {0x7b,0x40}, - {0x7c,0x00}, - {0xff, 0xff}, - -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x41,0x2f}, // 5 - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x2c}, - {0x48,0xc3}, - {0x8a,0x60}, - {0x8b,0x60}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0x70}, - {0x79,0x00}, - {0x7b,0x3f}, - {0x7c,0xf5}, - {0xff, 0xff}, - -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish 6 - {0x41,0x2f}, - {0x40,0x7e}, - {0x42,0x10}, - {0x47,0x3c}, - {0x48,0xc3}, - {0x8a,0x60}, - {0x8b,0x60}, - {0x8c,0x07}, - {0x50,0x0c}, - {0x77,0x80}, - {0xa1,0x40}, - {0x7a,0x00}, - {0x78,0xc0}, - {0x79,0xc0}, - {0x7b,0x40}, - {0x7c,0x00}, - {0xff,0xff}, - -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {0xd1, 0x38}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure1[]= -{ - {0xd1, 0x40}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure2[]= -{ - {0xd1, 0x48}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure3[]= -{ - {0xd1, 0x50}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure4[]= -{ - {0xd1, 0x58}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure5[]= -{ - {0xd1, 0x60}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_Exposure6[]= -{ - {0xd1, 0x68}, - {0xff, 0xff}, -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0xff, 0xff}, -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Contrast1[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Contrast2[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Contrast3[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Contrast4[]= -{ - {0xff, 0xff}, -}; - - -static struct reginfo sensor_Contrast5[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_Contrast6[]= -{ - {0xff, 0xff}, -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0xff, 0xff}, -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0xff, 0xff}, -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0xff, 0xff}, -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - { 0xdd ,0x22}, //0x12 - { 0x41 ,0x2f}, - { 0x21 ,0xc0}, - { 0xd2 ,0x02}, - {0xff, 0xff}, -}; - -static struct reginfo sensor_SceneNight[] = -{ - { 0xdd ,0x32}, - { 0x41 ,0x0f}, - { 0xb0 ,0x10}, - { 0x21 ,0xf0}, - - {0xff, 0xff}, -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0xff, 0xff}, - -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0xff, 0xff}, - -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0xff, 0xff}, - -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0xff, 0xff}, - -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} -}; -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val); - -/* sensor register write */ -static int sensor_write_internal(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg & 0xFF; - buf[1] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - - return err; -} - -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ -#if 1 - int ret, cnt; - for(cnt=0; cnt<1; cnt++) - { - mdelay(1); - ret=sensor_write_internal(client, reg, val); - } - return ret; -#else - u8 val_tmp; - - do - { - printk("sensor_write() : reg %02x 0x%02x\n", reg, val); - sensor_write_internal(client, reg, val); - mdelay(1); - sensor_read(client, reg, &val_tmp); - if(val_tmp != val) - { - printk("sensor_write() error: reg %02x 0x%02x != 0x%02x \n", reg, val, val_tmp); - } - mdelay(1); - } - while(val_tmp != val); - return 0; -#endif -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - //u8 buf[2]; - u8 buf[1]; - struct i2c_msg msg[2]; - - //buf[0] = reg >> 8; - buf[0] = reg; -// buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 1; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -#if 1 -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - - for(i=0; regarray[i].reg!=0xff;i++) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - } - return 0; -} -#else -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - u8 val_read; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - err = sensor_read(client, regarray[i].reg, &val_read); - SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); - i++; - } - return 0; -} -#endif - - -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int ret; - int i = 0; - - u8 value; - - SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); - for(i=0;ipowerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - int ret; - - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); */ //delay 5 microseconds - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } -#if 0 -{ - int i; - u8 val; - printk("****************** check init data\n"); - for(i=0; sensor_init_data[i].reg!=0xff; i++) - { - sensor_read(client, sensor_init_data[i].reg, &val); - printk("reg 0x%02x: org=0x%02x, val=0x%02x, %s\n", - sensor_init_data[i].reg, - sensor_init_data[i].val, - val, - sensor_init_data[i].val==val?"O":"X"); - } - printk("**********************************\n"); - -} -#endif - sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - //u8 reg_val; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { - sensor_task_lock(client, 1); - sensor_task_lock(client, 0); - } - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} -static struct reginfo sensor_power_down_sequence[]= -{ - {0xff, 0xff}, -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff) - { - winseqe_set_addr = sensor_720p; - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff) - { - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff) - { - set_w = 1280; - set_h = 1024; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_mirror(struct i2c_client *client, int on) -{ - int err = 0; - return err; -} -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_mirror(client,value) != 0) - SENSOR_TR("%s(%d): sensor_mirror failed, value:0x%x",__FUNCTION__, __LINE__,value); - - SENSOR_DG("%s(%d): sensor_mirror success, value:0x%x",__FUNCTION__, __LINE__,value); - return 0; - } - SENSOR_TR("\n %s..%s value = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_flip(struct i2c_client *client, int on) -{ - int err = 0; - return err; -} -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_flip(client,value) != 0) - SENSOR_TR("%s(%d): sensor_flip failed, value:0x%x",__FUNCTION__, __LINE__,value); - - SENSOR_DG("%s(%d): sensor_flip success, value:0x%x",__FUNCTION__, __LINE__,value); - return 0; - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) - { - *value = digitalzoom_total - digitalzoom_cur; - } - - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) - { - *value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += *value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char pid = 0; - int ret, i=0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - printk("%s(): set powerdn failed\n", __FUNCTION__); - goto sensor_video_probe_err; - } - - /* soft reset */ - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(50); *///delay 5 microseconds -re: - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &pid); - if (ret != 0) { - SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); - if(++i<100) - goto re; - ret = -ENODEV; - goto sensor_video_probe_err; - } - - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - goto re; - ret = -ENODEV; - goto sensor_video_probe_err; - } - - - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd);; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - sensor->info_priv.fmt = sensor_colour_fmts[0]; - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GC0307 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0307 +#define SENSOR_ID 0x99 +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + //========= close output + {0x43 ,0x00}, + {0x44 ,0xa2}, + + //========= close some functions + // open them after configure their parmameters + {0x40 ,0x10}, + {0x41 ,0x00}, + {0x42 ,0x10}, + {0x47 ,0x00}, //mode1, + {0x48 ,0xc3}, //mode2, + {0x49 ,0x00}, //dither_mode + {0x4a ,0x00}, //clock_gating_en + {0x4b ,0x00}, //mode_reg3 + {0x4E ,0x22},//0x23}, //sync mode yaowei + {0x4F ,0x01}, //AWB, AEC, every N frame + + //========= frame timing + {0x01 ,0x6a}, //HB + {0x02 ,0x70}, //VB + {0x1C ,0x00}, //Vs_st + {0x1D ,0x00}, //Vs_et + {0x10 ,0x00}, //high 4 bits of VB, HB + {0x11 ,0x05}, //row_tail, AD_pipe_number + + + + + + //========= windowing + {0x05 ,0x00}, //row_start + {0x06 ,0x00}, + {0x07 ,0x00}, //col start + {0x08 ,0x00}, + {0x09 ,0x01}, //win height + {0x0A ,0xE8}, + {0x0B ,0x02}, //win width, pixel array only 640 + {0x0C ,0x80}, + + //========= analog + {0x0D ,0x22}, //rsh_width + + {0x0E ,0x02}, //CISCTL mode2, + + + {0x12 ,0x70}, //7 hrst, 6_4 darsg, + {0x13 ,0x00}, //7 CISCTL_restart, 0 apwd + {0x14 ,0x00}, //NA + {0x15 ,0xba}, //7_4 vref + {0x16 ,0x13}, //5to4 _coln_r, __1to0__da18 + {0x17 ,0x52}, //opa_r, ref_r, sRef_r + //{0x18 ,0xc0}, //analog_mode, best case for left band. + + {0x1E ,0x0d}, //tsp_width + {0x1F ,0x32}, //sh_delay + + //========= offset + {0x47 ,0x00}, //7__test_image, __6__fixed_pga, __5__auto_DN, __4__CbCr_fix, + //__3to2__dark_sequence, __1__allow_pclk_vcync, __0__LSC_test_image + {0x19 ,0x06}, //pga_o + {0x1a ,0x06}, //pga_e + + {0x31 ,0x00}, //4 //pga_oFFset , high 8bits of 11bits + {0x3B ,0x00}, //global_oFFset, low 8bits of 11bits + + {0x59 ,0x0f}, //offset_mode + {0x58 ,0x88}, //DARK_VALUE_RATIO_G, DARK_VALUE_RATIO_RB + {0x57 ,0x08}, //DARK_CURRENT_RATE + {0x56 ,0x77}, //PGA_OFFSET_EVEN_RATIO, PGA_OFFSET_ODD_RATIO + + //========= blk + {0x35 ,0xd8}, //blk_mode + + {0x36 ,0x40}, + + {0x3C ,0x00}, + {0x3D ,0x00}, + {0x3E ,0x00}, + {0x3F ,0x00}, + + {0xb5 ,0x70}, + {0xb6 ,0x40}, + {0xb7 ,0x00}, + {0xb8 ,0x38}, + {0xb9 ,0xc3}, + {0xba ,0x0f}, + + {0x7e ,0x50},//0x45 ylz++ + {0x7f ,0x76}, //0x66 + + {0x5c ,0x48}, //78 + {0x5d ,0x58}, //88 + + + //========= manual_gain + {0x61 ,0x80}, //manual_gain_g1 + {0x63 ,0x80}, //manual_gain_r + {0x65 ,0x98}, //manual_gai_b, 0xa0=1.25, 0x98=1.1875 + {0x67 ,0x80}, //manual_gain_g2 + {0x68 ,0x18}, //global_manual_gain 2.4bits + + //=========CC _R + {0x69 ,0x58}, //54 + {0x6A ,0xf6}, //ff + {0x6B ,0xfb}, //fe + {0x6C ,0xf4}, //ff + {0x6D ,0x5a}, //5f + {0x6E ,0xe6}, //e1 + + {0x6f ,0x00}, + + //=========lsc + {0x70 ,0x14}, + {0x71 ,0x1c}, + {0x72 ,0x20}, + + {0x73 ,0x10}, + {0x74 ,0x3c}, + {0x75 ,0x52}, + + //=========dn + {0x7d ,0x2f}, //dn_mode + {0x80 ,0x0c}, //when auto_dn, check 7e,7f + {0x81 ,0x0c}, + {0x82 ,0x44}, + + //dd + {0x83 ,0x18}, //DD_TH1 + {0x84 ,0x18}, //DD_TH2 + {0x85 ,0x04}, //DD_TH3 + {0x87 ,0x34}, //32 b DNDD_low_range X16, DNDD_low_range_C_weight_center + + + //=========intp-ee + {0x88 ,0x04}, + {0x89 ,0x01}, + {0x8a ,0x50},//60 + {0x8b ,0x50},//60 + {0x8c ,0x07}, + + {0x50 ,0x0c}, + {0x5f ,0x3c}, + + {0x8e ,0x02}, + {0x86 ,0x02}, + + {0x51 ,0x20}, + {0x52 ,0x08}, + {0x53 ,0x00}, + + + //========= YCP + //contrast_center + {0x77 ,0x80}, //contrast_center + {0x78 ,0x00}, //fixed_Cb + {0x79 ,0x00}, //fixed_Cr + {0x7a ,0x00}, //luma_offset + {0x7b ,0x40}, //hue_cos + {0x7c ,0x00}, //hue_sin + + //saturation + {0xa0 ,0x40}, //global_saturation + {0xa1 ,0x42}, //luma_contrast + {0xa2 ,0x40}, //saturation_Cb //ylz 34 + {0xa3 ,0x34}, //saturation_Cr + + {0xa4 ,0xc8}, + {0xa5 ,0x02}, + {0xa6 ,0x28}, + {0xa7 ,0x02}, + + //skin + {0xa8 ,0xee}, + {0xa9 ,0x12}, + {0xaa ,0x01}, + {0xab ,0x20}, + {0xac ,0xf0}, + {0xad ,0x10}, + + //========= ABS + {0xae ,0x18}, + {0xaf ,0x74}, + {0xb0 ,0xe0}, + {0xb1 ,0x20}, + {0xb2 ,0x6c}, + {0xb3 ,0x40}, + {0xb4 ,0x04}, + + //========= AWB + {0xbb ,0x42}, + {0xbc ,0x60}, + {0xbd ,0x50}, + {0xbe ,0x50}, + + {0xbf ,0x0c}, + {0xc0 ,0x06}, + {0xc1 ,0x60}, + {0xc2 ,0xf1}, //f1 + {0xc3 ,0x40}, + {0xc4 ,0x1c}, //18//20 + {0xc5 ,0x56}, //33 + {0xc6 ,0x1d}, + + {0xca ,0x70}, + {0xcb ,0x70}, + {0xcc ,0x78}, + + {0xcd ,0x80}, //R_ratio + {0xce ,0x80}, //G_ratio , cold_white white + {0xcf ,0x80}, //B_ratio + + //========= aecT + {0x20 ,0x06},//0x02 + {0x21 ,0xc0}, + {0x22 ,0x40}, + {0x23 ,0x88}, + {0x24 ,0x96}, + {0x25 ,0x30}, + {0x26 ,0xd0}, + {0x27 ,0x00}, + + {0x28 ,0x02}, //AEC_exp_level_1bit11to8 + {0x29 ,0x58}, //AEC_exp_level_1bit7to0 + {0x2a ,0x03}, //AEC_exp_level_2bit11to8 + {0x2b ,0x84}, //AEC_exp_level_2bit7to0 + {0x2c ,0x09}, //AEC_exp_level_3bit11to8 659 - 8FPS, 8ca - 6FPS // + {0x2d ,0x60}, //AEC_exp_level_3bit7to0 + {0x2e ,0x0a}, //AEC_exp_level_4bit11to8 4FPS + {0x2f ,0x8c}, //AEC_exp_level_4bit7to0 + + {0x30 ,0x20}, + {0x31 ,0x00}, + {0x32 ,0x1c}, + {0x33 ,0x90}, + {0x34 ,0x10}, + + {0xd0 ,0x34}, + + {0xd1 ,0x40}, //AEC_target_Y + {0xd2 ,0x61},//0xf2 + {0xd4 ,0x96}, + {0xd5 ,0x01}, // william 0318 + {0xd6 ,0x96}, //antiflicker_step + {0xd7 ,0x03}, //AEC_exp_time_min ,william 20090312 + {0xd8 ,0x02}, + + {0xdd ,0x12},//0x12 + + //========= measure window + {0xe0 ,0x03}, + {0xe1 ,0x02}, + {0xe2 ,0x27}, + {0xe3 ,0x1e}, + {0xe8 ,0x3b}, + {0xe9 ,0x6e}, + {0xea ,0x2c}, + {0xeb ,0x50}, + {0xec ,0x73}, + + //========= close_frame + {0xed ,0x00}, //close_frame_num1 ,can be use to reduce FPS + {0xee ,0x00}, //close_frame_num2 + {0xef ,0x00}, //close_frame_num + + // page1 + {0xf0 ,0x01}, //select page1 + + {0x00 ,0x20}, + {0x01 ,0x20}, + {0x02 ,0x20}, + {0x03 ,0x20}, + {0x04 ,0x78}, + {0x05 ,0x78}, + {0x06 ,0x78}, + {0x07 ,0x78}, + + + + {0x10 ,0x04}, + {0x11 ,0x04}, + {0x12 ,0x04}, + {0x13 ,0x04}, + {0x14 ,0x01}, + {0x15 ,0x01}, + {0x16 ,0x01}, + {0x17 ,0x01}, + + + {0x20 ,0x00}, + {0x21 ,0x00}, + {0x22 ,0x00}, + {0x23 ,0x00}, + {0x24 ,0x00}, + {0x25 ,0x00}, + {0x26 ,0x00}, + {0x27 ,0x00}, + + {0x40 ,0x11}, + + //=============================lscP + {0x45 ,0x06}, + {0x46 ,0x06}, + {0x47 ,0x05}, + + {0x48 ,0x04}, + {0x49 ,0x03}, + {0x4a ,0x03}, + + + {0x62 ,0xd8}, + {0x63 ,0x24}, + {0x64 ,0x24}, + {0x65 ,0x24}, + {0x66 ,0xd8}, + {0x67 ,0x24}, + + {0x5a ,0x00}, + {0x5b ,0x00}, + {0x5c ,0x00}, + {0x5d ,0x00}, + {0x5e ,0x00}, + {0x5f ,0x00}, + + + //============================= ccP + + {0x69 ,0x03}, //cc_mode + + //CC_G + {0x70 ,0x5d}, + {0x71 ,0xed}, + {0x72 ,0xff}, + {0x73 ,0xe5}, + {0x74 ,0x5f}, + {0x75 ,0xe6}, + + //CC_B + {0x76 ,0x41}, + {0x77 ,0xef}, + {0x78 ,0xff}, + {0x79 ,0xff}, + {0x7a ,0x5f}, + {0x7b ,0xfa}, + + + //============================= AGP + + {0x7e ,0x00}, + {0x7f ,0x20}, //x040 + {0x80 ,0x48}, + {0x81 ,0x06}, + {0x82 ,0x08}, + + {0x83 ,0x23}, + {0x84 ,0x38}, + {0x85 ,0x4F}, + {0x86 ,0x61}, + {0x87 ,0x72}, + {0x88 ,0x80}, + {0x89 ,0x8D}, + {0x8a ,0xA2}, + {0x8b ,0xB2}, + {0x8c ,0xC0}, + {0x8d ,0xCA}, + {0x8e ,0xD3}, + {0x8f ,0xDB}, + {0x90 ,0xE2}, + {0x91 ,0xED}, + {0x92 ,0xF6}, + {0x93 ,0xFD}, + + //about gamma1 is hex r oct + {0x94 ,0x04}, + {0x95 ,0x0E}, + {0x96 ,0x1B}, + {0x97 ,0x28}, + {0x98 ,0x35}, + {0x99 ,0x41}, + {0x9a ,0x4E}, + {0x9b ,0x67}, + {0x9c ,0x7E}, + {0x9d ,0x94}, + {0x9e ,0xA7}, + {0x9f ,0xBA}, + {0xa0 ,0xC8}, + {0xa1 ,0xD4}, + {0xa2 ,0xE7}, + {0xa3 ,0xF4}, + {0xa4 ,0xFA}, + + //========= open functions + {0xf0 ,0x00}, //set back to page0 + {0x40 ,0x7e}, + {0x41 ,0x2F}, + + ///// Çë×¢Ò⣬µ÷ÕûGC0307µÄ¾µÏñºÍ·­×ª£¬ÐèҪͬʱÐÞ¸ÄÈý¸ö¼Ä´æÆ÷£¬ÈçÏÂ: + + {0x0f, 0xb2}, + {0x45, 0x27}, + {0x47, 0x2c}, + ///banding setting + { 0x01 ,0xfa}, // 24M + { 0x02 ,0x70}, + { 0x10 ,0x01}, + { 0xd6 ,0x64}, + { 0x28 ,0x02}, + { 0x29 ,0x58}, + { 0x2a ,0x02}, + { 0x2b ,0x58}, + { 0x2c ,0x02}, + { 0x2d ,0x58}, + { 0x2e ,0x06}, + { 0x2f ,0x40}, + + /************ + {0x0f, 0x02},//82 + {0x45, 0x24}, + {0x47, 0x20}, + **************/ + ///// ËÄÖÖ²»Í¬µÄ·­×ªºÍ¾µÏñÉ趨£¬¿Í»§¿ÉÖ±½Ó¸´ÖÆ!!!!!! + + +#if 0 + // IMAGE_NORMAL: + {0x0f, 0xb2}, + {0x45, 0x27}, + {0x47, 0x2c}, + + // IMAGE_H_MIRROR: + {0x0f, 0xa2}, + {0x45, 0x26}, + {0x47, 0x28}, + + // IMAGE_V_MIRROR: + {0x0f, 0x92}, + {0x45, 0x25}, + {0x47, 0x24}, + + // IMAGE_HV_MIRROR: // 180 + {0x0f, 0x82}, + {0x45, 0x24}, + {0x47, 0x20}, +#endif + {0x43, 0x40}, + {0x44, 0xe2}, + + 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[] = +{ +#if 1 + { 0x05 , 0x00}, + { 0x06 , 0x00}, + { 0x07 , 0x00}, + { 0x08 , 0x00},//0x10 james 20100715 + { 0x09 , 0x01}, + { 0x0a , 0xe8}, + { 0x0b , 0x02}, + { 0x0c , 0x88},//0x80 james 20100715 + { 0x45 , 0x24}, // bit[7:2]=001001 + { 0x48 , 0x84}, // bit[7]=1 + { 0xe0 , 0x03}, + { 0xe1 , 0x02}, + { 0xe2 , 0x27}, + { 0xe3 , 0x1e}, + { 0xe8 , 0x3b}, + { 0xe9 , 0x6e}, + { 0xea , 0x2c}, + { 0xeb , 0x50}, + { 0xec , 0x73}, +#else + {0x17, 0x13}, + {0x18, 0x01}, + {0x32, 0xbf}, + {0x19, 0x03}, + {0x1a, 0x7b}, + {0x03, 0x0a}, + +#endif + 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[]={ + SensorRegVal(0x00,0), + 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[]= +{ + {0xc7,0x4c}, //for AWB can adjust back + {0xc8,0x40}, + {0xc9,0x4a}, + {0x41,0x2f}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x41,0x2b}, // Enable AWB + {0xc7,0x5a}, //WB_manual_gain + {0xc8,0x42}, + {0xc9,0x40}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x41,0x2b}, // Enable AWB + {0xc7,0x50}, + {0xc8,0x45}, + {0xc9,0x40}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x41,0x2b}, // Enable AWB + {0xc7,0x48}, + {0xc8,0x40}, + {0xc9,0x5c}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x41,0x2b}, // Enable AWB + {0xc7,0x40}, + {0xc8,0x42}, + {0xc9,0x50}, + 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 + {0x7a, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + {0x7a, 0xf0}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + {0x7a, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0x7a, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0x7a, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0x7a, 0x30}, + 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[] = +{ + {0x41,0x2f}, // 1 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x24},//20 + {0x48,0xc3}, + {0x8a,0x50},//60 + {0x8b,0x50}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x41,0x2f}, // danse + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x41,0x2f}, + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0xc0}, + {0x79,0x20}, + {0x7b,0x40}, + {0x7c,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x41,0x6f}, // 4 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x20}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x41,0x2f}, // 5 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x2c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x70}, + {0x79,0x00}, + {0x7b,0x3f}, + {0x7c,0xf5}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish 6 + {0x41,0x2f}, + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0xc0}, + {0x79,0xc0}, + {0x7b,0x40}, + {0x7c,0x00}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Grayscale[]= +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + +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[]= +{ + //-3 + {0xd1, 0x38}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + //-2 + {0xd1, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + //-1 + {0xd1, 0x48}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + //default + {0xd1, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + // 1 + {0xd1, 0x58}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + // 2 + {0xd1, 0x60}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + // 3 + {0xd1, 0x68}, + 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[] = +{ + { 0xdd ,0x22}, //0x12 + { 0x41 ,0x2f}, + { 0x21 ,0xc0}, + { 0xd2 ,0x02}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + { 0xdd ,0x32}, + { 0x41 ,0x0f}, + { 0xb0 ,0x10}, + { 0x21 ,0xf0}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val1,val2,val3; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xf0, 0); + err = sensor_read(client,0x0f,&val1); + err = sensor_read(client,0x45,&val2); + err = sensor_read(client,0x47,&val3); + if(err ==0){ + if((val1 == 0xb2) && (val2 == 0x27) && (val3 == 0x2c)){//normal + err = sensor_write(client, 0x0f, 0xa2); + err = sensor_write(client, 0x45, 0x26); + err = sensor_write(client, 0x47, 0x28); + }else if((val1 == 0xa2) && (val2 == 0x26) && (val3 == 0x28)){//h_mir + err = sensor_write(client, 0x0f, 0xb2); + err = sensor_write(client, 0x45, 0x27); + err = sensor_write(client, 0x47, 0x2c); + }else if((val1 == 0x92) && (val2 == 0x25) && (val3 == 0x24)){//v_flip + err = sensor_write(client, 0x0f, 0x82); + err = sensor_write(client, 0x45, 0x24); + err = sensor_write(client, 0x47, 0x20); + }else if((val1 == 0x82) && (val2 == 0x24) && (val3 == 0x20)){//h_v_mir + err = sensor_write(client, 0x0f, 0x92); + err = sensor_write(client, 0x45, 0x25); + err = sensor_write(client, 0x47, 0x24); + } + + } + + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val1,val2,val3; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + sensor_write(client, 0xf0, 0); + err = sensor_read(client,0x0f,&val1); + err = sensor_read(client,0x45,&val2); + err = sensor_read(client,0x47,&val3); + if(err ==0){ + if((val1 == 0xb2) && (val2 == 0x27) && (val3 == 0x2c)){//normal + err = sensor_write(client, 0x0f, 0x92); + err = sensor_write(client, 0x45, 0x25); + err = sensor_write(client, 0x47, 0x24); + }else if((val1 == 0xa2) && (val2 == 0x26) && (val3 == 0x28)){//h_mir + err = sensor_write(client, 0x0f, 0x82); + err = sensor_write(client, 0x45, 0x24); + err = sensor_write(client, 0x47, 0x20); + }else if((val1 == 0x92) && (val2 == 0x25) && (val3 == 0x24)){//v_flip + err = sensor_write(client, 0x0f, 0xb2); + err = sensor_write(client, 0x45, 0x27); + err = sensor_write(client, 0x47, 0x2c); + }else if((val1 == 0x82) && (val2 == 0x24) && (val3 == 0x20)){//h_v_mir + err = sensor_write(client, 0x0f, 0xa2); + err = sensor_write(client, 0x45, 0x26); + err = sensor_write(client, 0x47, 0x28); + } + + } + + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gc0307_old.c b/drivers/media/video/gc0307_old.c new file mode 100755 index 000000000000..79c2ec36b6f4 --- /dev/null +++ b/drivers/media/video/gc0307_old.c @@ -0,0 +1,3079 @@ + +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC0307 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0307 +#define SENSOR_ID 0x99 +#define SENSOR_MIN_WIDTH 640//176 +#define SENSOR_MIN_HEIGHT 480//144 +#define SENSOR_MAX_WIDTH 800//1600 +#define SENSOR_MAX_HEIGHT 600//1200 +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#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 0 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 100000//250000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) +struct reginfo +{ + u8 reg; + u8 val; +}; + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_GC0307_USER_DEFINED_SERIES +#include "gc0307_user_series.c" +#else +/* init 640X480 VGA */ +static struct reginfo sensor_init_data[] = +{ +//========= close output + {0x43 ,0x00}, + {0x44 ,0xa2}, + + //========= close some functions + // open them after configure their parmameters + {0x40 ,0x10}, + {0x41 ,0x00}, + {0x42 ,0x10}, + {0x47 ,0x00}, //mode1, + {0x48 ,0xc3}, //mode2, + {0x49 ,0x00}, //dither_mode + {0x4a ,0x00}, //clock_gating_en + {0x4b ,0x00}, //mode_reg3 + {0x4E ,0x22},//0x23}, //sync mode yaowei + {0x4F ,0x01}, //AWB, AEC, every N frame + + //========= frame timing + {0x01 ,0x6a}, //HB + {0x02 ,0x70}, //VB + {0x1C ,0x00}, //Vs_st + {0x1D ,0x00}, //Vs_et + {0x10 ,0x00}, //high 4 bits of VB, HB + {0x11 ,0x05}, //row_tail, AD_pipe_number + + + + + + //========= windowing + {0x05 ,0x00}, //row_start + {0x06 ,0x00}, + {0x07 ,0x00}, //col start + {0x08 ,0x00}, + {0x09 ,0x01}, //win height + {0x0A ,0xE8}, + {0x0B ,0x02}, //win width, pixel array only 640 + {0x0C ,0x80}, + + //========= analog + {0x0D ,0x22}, //rsh_width + + {0x0E ,0x02}, //CISCTL mode2, + + + {0x12 ,0x70}, //7 hrst, 6_4 darsg, + {0x13 ,0x00}, //7 CISCTL_restart, 0 apwd + {0x14 ,0x00}, //NA + {0x15 ,0xba}, //7_4 vref + {0x16 ,0x13}, //5to4 _coln_r, __1to0__da18 + {0x17 ,0x52}, //opa_r, ref_r, sRef_r + //{0x18 ,0xc0}, //analog_mode, best case for left band. + + {0x1E ,0x0d}, //tsp_width + {0x1F ,0x32}, //sh_delay + + //========= offset + {0x47 ,0x00}, //7__test_image, __6__fixed_pga, __5__auto_DN, __4__CbCr_fix, + //__3to2__dark_sequence, __1__allow_pclk_vcync, __0__LSC_test_image + {0x19 ,0x06}, //pga_o + {0x1a ,0x06}, //pga_e + + {0x31 ,0x00}, //4 //pga_oFFset , high 8bits of 11bits + {0x3B ,0x00}, //global_oFFset, low 8bits of 11bits + + {0x59 ,0x0f}, //offset_mode + {0x58 ,0x88}, //DARK_VALUE_RATIO_G, DARK_VALUE_RATIO_RB + {0x57 ,0x08}, //DARK_CURRENT_RATE + {0x56 ,0x77}, //PGA_OFFSET_EVEN_RATIO, PGA_OFFSET_ODD_RATIO + + //========= blk + {0x35 ,0xd8}, //blk_mode + + {0x36 ,0x40}, + + {0x3C ,0x00}, + {0x3D ,0x00}, + {0x3E ,0x00}, + {0x3F ,0x00}, + + {0xb5 ,0x70}, + {0xb6 ,0x40}, + {0xb7 ,0x00}, + {0xb8 ,0x38}, + {0xb9 ,0xc3}, + {0xba ,0x0f}, + + {0x7e ,0x50},//0x45 ylz++ + {0x7f ,0x76}, //0x66 + + {0x5c ,0x48}, //78 + {0x5d ,0x58}, //88 + + + //========= manual_gain + {0x61 ,0x80}, //manual_gain_g1 + {0x63 ,0x80}, //manual_gain_r + {0x65 ,0x98}, //manual_gai_b, 0xa0=1.25, 0x98=1.1875 + {0x67 ,0x80}, //manual_gain_g2 + {0x68 ,0x18}, //global_manual_gain 2.4bits + + //=========CC _R + {0x69 ,0x58}, //54 + {0x6A ,0xf6}, //ff + {0x6B ,0xfb}, //fe + {0x6C ,0xf4}, //ff + {0x6D ,0x5a}, //5f + {0x6E ,0xe6}, //e1 + + {0x6f ,0x00}, + + //=========lsc + {0x70 ,0x14}, + {0x71 ,0x1c}, + {0x72 ,0x20}, + + {0x73 ,0x10}, + {0x74 ,0x3c}, + {0x75 ,0x52}, + + //=========dn + {0x7d ,0x2f}, //dn_mode + {0x80 ,0x0c}, //when auto_dn, check 7e,7f + {0x81 ,0x0c}, + {0x82 ,0x44}, + + //dd + {0x83 ,0x18}, //DD_TH1 + {0x84 ,0x18}, //DD_TH2 + {0x85 ,0x04}, //DD_TH3 + {0x87 ,0x34}, //32 b DNDD_low_range X16, DNDD_low_range_C_weight_center + + + //=========intp-ee + {0x88 ,0x04}, + {0x89 ,0x01}, + {0x8a ,0x50},//60 + {0x8b ,0x50},//60 + {0x8c ,0x07}, + + {0x50 ,0x0c}, + {0x5f ,0x3c}, + + {0x8e ,0x02}, + {0x86 ,0x02}, + + {0x51 ,0x20}, + {0x52 ,0x08}, + {0x53 ,0x00}, + + + //========= YCP + //contrast_center + {0x77 ,0x80}, //contrast_center + {0x78 ,0x00}, //fixed_Cb + {0x79 ,0x00}, //fixed_Cr + {0x7a ,0x00}, //luma_offset + {0x7b ,0x40}, //hue_cos + {0x7c ,0x00}, //hue_sin + + //saturation + {0xa0 ,0x40}, //global_saturation + {0xa1 ,0x42}, //luma_contrast + {0xa2 ,0x40}, //saturation_Cb //ylz 34 + {0xa3 ,0x34}, //saturation_Cr + + {0xa4 ,0xc8}, + {0xa5 ,0x02}, + {0xa6 ,0x28}, + {0xa7 ,0x02}, + + //skin + {0xa8 ,0xee}, + {0xa9 ,0x12}, + {0xaa ,0x01}, + {0xab ,0x20}, + {0xac ,0xf0}, + {0xad ,0x10}, + + //========= ABS + {0xae ,0x18}, + {0xaf ,0x74}, + {0xb0 ,0xe0}, + {0xb1 ,0x20}, + {0xb2 ,0x6c}, + {0xb3 ,0x40}, + {0xb4 ,0x04}, + + //========= AWB + {0xbb ,0x42}, + {0xbc ,0x60}, + {0xbd ,0x50}, + {0xbe ,0x50}, + + {0xbf ,0x0c}, + {0xc0 ,0x06}, + {0xc1 ,0x60}, + {0xc2 ,0xf1}, //f1 + {0xc3 ,0x40}, + {0xc4 ,0x1c}, //18//20 + {0xc5 ,0x56}, //33 + {0xc6 ,0x1d}, + + {0xca ,0x70}, + {0xcb ,0x70}, + {0xcc ,0x78}, + + {0xcd ,0x80}, //R_ratio + {0xce ,0x80}, //G_ratio , cold_white white + {0xcf ,0x80}, //B_ratio + + //========= aecT + {0x20 ,0x06},//0x02 + {0x21 ,0xc0}, + {0x22 ,0x40}, + {0x23 ,0x88}, + {0x24 ,0x96}, + {0x25 ,0x30}, + {0x26 ,0xd0}, + {0x27 ,0x00}, + + {0x28 ,0x02}, //AEC_exp_level_1bit11to8 + {0x29 ,0x58}, //AEC_exp_level_1bit7to0 + {0x2a ,0x03}, //AEC_exp_level_2bit11to8 + {0x2b ,0x84}, //AEC_exp_level_2bit7to0 + {0x2c ,0x09}, //AEC_exp_level_3bit11to8 659 - 8FPS, 8ca - 6FPS // + {0x2d ,0x60}, //AEC_exp_level_3bit7to0 + {0x2e ,0x0a}, //AEC_exp_level_4bit11to8 4FPS + {0x2f ,0x8c}, //AEC_exp_level_4bit7to0 + + {0x30 ,0x20}, + {0x31 ,0x00}, + {0x32 ,0x1c}, + {0x33 ,0x90}, + {0x34 ,0x10}, + + {0xd0 ,0x34}, + + {0xd1 ,0x40}, //AEC_target_Y + {0xd2 ,0x61},//0xf2 + {0xd4 ,0x96}, + {0xd5 ,0x01}, // william 0318 + {0xd6 ,0x96}, //antiflicker_step + {0xd7 ,0x03}, //AEC_exp_time_min ,william 20090312 + {0xd8 ,0x02}, + + {0xdd ,0x12},//0x12 + + //========= measure window + {0xe0 ,0x03}, + {0xe1 ,0x02}, + {0xe2 ,0x27}, + {0xe3 ,0x1e}, + {0xe8 ,0x3b}, + {0xe9 ,0x6e}, + {0xea ,0x2c}, + {0xeb ,0x50}, + {0xec ,0x73}, + + //========= close_frame + {0xed ,0x00}, //close_frame_num1 ,can be use to reduce FPS + {0xee ,0x00}, //close_frame_num2 + {0xef ,0x00}, //close_frame_num + + // page1 + {0xf0 ,0x01}, //select page1 + + {0x00 ,0x20}, + {0x01 ,0x20}, + {0x02 ,0x20}, + {0x03 ,0x20}, + {0x04 ,0x78}, + {0x05 ,0x78}, + {0x06 ,0x78}, + {0x07 ,0x78}, + + + + {0x10 ,0x04}, + {0x11 ,0x04}, + {0x12 ,0x04}, + {0x13 ,0x04}, + {0x14 ,0x01}, + {0x15 ,0x01}, + {0x16 ,0x01}, + {0x17 ,0x01}, + + + {0x20 ,0x00}, + {0x21 ,0x00}, + {0x22 ,0x00}, + {0x23 ,0x00}, + {0x24 ,0x00}, + {0x25 ,0x00}, + {0x26 ,0x00}, + {0x27 ,0x00}, + + {0x40 ,0x11}, + + //=============================lscP + {0x45 ,0x06}, + {0x46 ,0x06}, + {0x47 ,0x05}, + + {0x48 ,0x04}, + {0x49 ,0x03}, + {0x4a ,0x03}, + + + {0x62 ,0xd8}, + {0x63 ,0x24}, + {0x64 ,0x24}, + {0x65 ,0x24}, + {0x66 ,0xd8}, + {0x67 ,0x24}, + + {0x5a ,0x00}, + {0x5b ,0x00}, + {0x5c ,0x00}, + {0x5d ,0x00}, + {0x5e ,0x00}, + {0x5f ,0x00}, + + + //============================= ccP + + {0x69 ,0x03}, //cc_mode + + //CC_G + {0x70 ,0x5d}, + {0x71 ,0xed}, + {0x72 ,0xff}, + {0x73 ,0xe5}, + {0x74 ,0x5f}, + {0x75 ,0xe6}, + + //CC_B + {0x76 ,0x41}, + {0x77 ,0xef}, + {0x78 ,0xff}, + {0x79 ,0xff}, + {0x7a ,0x5f}, + {0x7b ,0xfa}, + + + //============================= AGP + + {0x7e ,0x00}, + {0x7f ,0x20}, //x040 + {0x80 ,0x48}, + {0x81 ,0x06}, + {0x82 ,0x08}, + + {0x83 ,0x23}, + {0x84 ,0x38}, + {0x85 ,0x4F}, + {0x86 ,0x61}, + {0x87 ,0x72}, + {0x88 ,0x80}, + {0x89 ,0x8D}, + {0x8a ,0xA2}, + {0x8b ,0xB2}, + {0x8c ,0xC0}, + {0x8d ,0xCA}, + {0x8e ,0xD3}, + {0x8f ,0xDB}, + {0x90 ,0xE2}, + {0x91 ,0xED}, + {0x92 ,0xF6}, + {0x93 ,0xFD}, + + //about gamma1 is hex r oct + {0x94 ,0x04}, + {0x95 ,0x0E}, + {0x96 ,0x1B}, + {0x97 ,0x28}, + {0x98 ,0x35}, + {0x99 ,0x41}, + {0x9a ,0x4E}, + {0x9b ,0x67}, + {0x9c ,0x7E}, + {0x9d ,0x94}, + {0x9e ,0xA7}, + {0x9f ,0xBA}, + {0xa0 ,0xC8}, + {0xa1 ,0xD4}, + {0xa2 ,0xE7}, + {0xa3 ,0xF4}, + {0xa4 ,0xFA}, + + //========= open functions + {0xf0 ,0x00}, //set back to page0 + {0x40 ,0x7e}, + {0x41 ,0x2F}, + +///// Çë×¢Ò⣬µ÷ÕûGC0307µÄ¾µÏñºÍ·­×ª£¬ÐèҪͬʱÐÞ¸ÄÈý¸ö¼Ä´æÆ÷£¬ÈçÏÂ: + + {0x0f, 0x92}, + {0x45, 0x25}, + {0x47, 0x24}, +///banding setting + { 0x01 ,0xfa}, // 24M + { 0x02 ,0x70}, + { 0x10 ,0x01}, + { 0xd6 ,0x64}, + { 0x28 ,0x02}, + { 0x29 ,0x58}, + { 0x2a ,0x02}, + { 0x2b ,0x58}, + { 0x2c ,0x02}, + { 0x2d ,0x58}, + { 0x2e ,0x06}, + { 0x2f ,0x40}, + + /************ + {0x0f, 0x02},//82 + {0x45, 0x24}, + {0x47, 0x20}, + **************/ +///// ËÄÖÖ²»Í¬µÄ·­×ªºÍ¾µÏñÉ趨£¬¿Í»§¿ÉÖ±½Ó¸´ÖÆ!!!!!! + + +#if 0 +// IMAGE_NORMAL: + {0x0f, 0xb2}, + {0x45, 0x27}, + {0x47, 0x2c}, + +// IMAGE_H_MIRROR: + {0x0f, 0xa2}, + {0x45, 0x26}, + {0x47, 0x28}, + +// IMAGE_V_MIRROR: + {0x0f, 0x92}, + {0x45, 0x25}, + {0x47, 0x24}, + +// IMAGE_HV_MIRROR: // 180 + {0x0f, 0x82}, + {0x45, 0x24}, + {0x47, 0x20}, +#endif +{0x43, 0x40}, + {0x44, 0xe2}, +{0xff, 0xff}, +}; + +static struct reginfo sensor_720p[]= +{ + {0xff, 0xff}, +}; + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0xff, 0xff}, + +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0xff, 0xff}, + +}; + +/* 640X480 VGA */ + +static struct reginfo sensor_vga[] = +{ +#if 1 +{ 0x05 , 0x00}, +{ 0x06 , 0x00}, +{ 0x07 , 0x00}, +{ 0x08 , 0x00},//0x10 james 20100715 +{ 0x09 , 0x01}, +{ 0x0a , 0xe8}, +{ 0x0b , 0x02}, +{ 0x0c , 0x88},//0x80 james 20100715 +{ 0x45 , 0x24}, // bit[7:2]=001001 +{ 0x48 , 0x84}, // bit[7]=1 +{ 0xe0 , 0x03}, +{ 0xe1 , 0x02}, +{ 0xe2 , 0x27}, +{ 0xe3 , 0x1e}, +{ 0xe8 , 0x3b}, +{ 0xe9 , 0x6e}, +{ 0xea , 0x2c}, +{ 0xeb , 0x50}, +{ 0xec , 0x73}, +#else +{0x17, 0x13}, +{0x18, 0x01}, +{0x32, 0xbf}, +{0x19, 0x03}, +{0x1a, 0x7b}, +{0x03, 0x0a}, + +#endif + {0xff, 0xff}, + + +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0xff, 0xff}, + +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + {0xff, 0xff}, + +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + {0xff, 0xff}, + +}; +#endif +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0xff, 0xff}, + +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0xff, 0xff}, + +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0xc7,0x4c}, //for AWB can adjust back + {0xc8,0x40}, + {0xc9,0x4a}, + {0x41,0x2f}, + {0xff, 0xff}, + + + +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x41,0x2b}, // Enable AWB + {0xc7,0x5a}, //WB_manual_gain + {0xc8,0x42}, + {0xc9,0x40}, + {0xff, 0xff}, + + +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x41,0x2b}, // Enable AWB + {0xc7,0x50}, + {0xc8,0x45}, + {0xc9,0x40}, + {0xff, 0xff}, + + +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x41,0x2b}, // Enable AWB + {0xc7,0x48}, + {0xc8,0x40}, + {0xc9,0x5c}, + {0xff, 0xff}, + + + + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x41,0x2b}, // Enable AWB + {0xc7,0x40}, + {0xc8,0x42}, + {0xc9,0x50}, + {0xff, 0xff}, + + +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + {0x7a, 0xe0}, + {0xff, 0xff}, + +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + {0x7a, 0xf0}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + {0x7a, 0x00}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + {0x7a, 0x10}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + {0x7a, 0x20}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + {0x7a, 0x30}, + {0xff, 0xff}, +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x41,0x2f}, // 1 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x24},//20 + {0x48,0xc3}, + {0x8a,0x50},//60 + {0x8b,0x50}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + {0xff, 0xff}, + +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x41,0x2f}, // danse + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + {0xff,0xff}, +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x41,0x2f}, + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0xc0}, + {0x79,0x20}, + {0x7b,0x40}, + {0x7c,0x00}, + {0xff,0xff}, + + + +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x41,0x6f}, // 4 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x20}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x00}, + {0x79,0x00}, + {0x7b,0x40}, + {0x7c,0x00}, + {0xff, 0xff}, + +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x41,0x2f}, // 5 + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x2c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0x70}, + {0x79,0x00}, + {0x7b,0x3f}, + {0x7c,0xf5}, + {0xff, 0xff}, + +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish 6 + {0x41,0x2f}, + {0x40,0x7e}, + {0x42,0x10}, + {0x47,0x3c}, + {0x48,0xc3}, + {0x8a,0x60}, + {0x8b,0x60}, + {0x8c,0x07}, + {0x50,0x0c}, + {0x77,0x80}, + {0xa1,0x40}, + {0x7a,0x00}, + {0x78,0xc0}, + {0x79,0xc0}, + {0x7b,0x40}, + {0x7c,0x00}, + {0xff,0xff}, + +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + {0xd1, 0x38}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure1[]= +{ + {0xd1, 0x40}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure2[]= +{ + {0xd1, 0x48}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure3[]= +{ + {0xd1, 0x50}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure4[]= +{ + {0xd1, 0x58}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure5[]= +{ + {0xd1, 0x60}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_Exposure6[]= +{ + {0xd1, 0x68}, + {0xff, 0xff}, +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0xff, 0xff}, +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Contrast1[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Contrast2[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Contrast3[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Contrast4[]= +{ + {0xff, 0xff}, +}; + + +static struct reginfo sensor_Contrast5[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_Contrast6[]= +{ + {0xff, 0xff}, +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0xff, 0xff}, +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0xff, 0xff}, +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0xff, 0xff}, +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + { 0xdd ,0x22}, //0x12 + { 0x41 ,0x2f}, + { 0x21 ,0xc0}, + { 0xd2 ,0x02}, + {0xff, 0xff}, +}; + +static struct reginfo sensor_SceneNight[] = +{ + { 0xdd ,0x32}, + { 0x41 ,0x0f}, + { 0xb0 ,0x10}, + { 0x21 ,0xf0}, + + {0xff, 0xff}, +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0xff, 0xff}, + +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0xff, 0xff}, + +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0xff, 0xff}, + +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0xff, 0xff}, + +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val); + +/* sensor register write */ +static int sensor_write_internal(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg & 0xFF; + buf[1] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + + return err; +} + +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ +#if 1 + int ret, cnt; + for(cnt=0; cnt<1; cnt++) + { + mdelay(1); + ret=sensor_write_internal(client, reg, val); + } + return ret; +#else + u8 val_tmp; + + do + { + printk("sensor_write() : reg %02x 0x%02x\n", reg, val); + sensor_write_internal(client, reg, val); + mdelay(1); + sensor_read(client, reg, &val_tmp); + if(val_tmp != val) + { + printk("sensor_write() error: reg %02x 0x%02x != 0x%02x \n", reg, val, val_tmp); + } + mdelay(1); + } + while(val_tmp != val); + return 0; +#endif +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + //u8 buf[2]; + u8 buf[1]; + struct i2c_msg msg[2]; + + //buf[0] = reg >> 8; + buf[0] = reg; +// buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 1; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +#if 1 +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + + for(i=0; regarray[i].reg!=0xff;i++) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + } + return 0; +} +#else +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + u8 val_read; + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + err = sensor_read(client, regarray[i].reg, &val_read); + SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); + i++; + } + return 0; +} +#endif + + +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int ret; + int i = 0; + + u8 value; + + SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); + for(i=0;ipowerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + int ret; + + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); */ //delay 5 microseconds + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } +#if 0 +{ + int i; + u8 val; + printk("****************** check init data\n"); + for(i=0; sensor_init_data[i].reg!=0xff; i++) + { + sensor_read(client, sensor_init_data[i].reg, &val); + printk("reg 0x%02x: org=0x%02x, val=0x%02x, %s\n", + sensor_init_data[i].reg, + sensor_init_data[i].val, + val, + sensor_init_data[i].val==val?"O":"X"); + } + printk("**********************************\n"); + +} +#endif + sensor_task_lock(client,0); + //icd->user_width = SENSOR_INIT_WIDTH; + //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + //u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_task_lock(client, 1); + sensor_task_lock(client, 0); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} +static struct reginfo sensor_power_down_sequence[]= +{ + {0xff, 0xff}, +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff) + { + winseqe_set_addr = sensor_720p; + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff) + { + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff) + { + set_w = 1280; + set_h = 1024; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_mirror(struct i2c_client *client, int on) +{ + int err = 0; + return err; +} +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_mirror(client,value) != 0) + SENSOR_TR("%s(%d): sensor_mirror failed, value:0x%x",__FUNCTION__, __LINE__,value); + + SENSOR_DG("%s(%d): sensor_mirror success, value:0x%x",__FUNCTION__, __LINE__,value); + return 0; + } + SENSOR_TR("\n %s..%s value = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_flip(struct i2c_client *client, int on) +{ + int err = 0; + return err; +} +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_flip(client,value) != 0) + SENSOR_TR("%s(%d): sensor_flip failed, value:0x%x",__FUNCTION__, __LINE__,value); + + SENSOR_DG("%s(%d): sensor_flip success, value:0x%x",__FUNCTION__, __LINE__,value); + return 0; + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + { + *value = digitalzoom_total - digitalzoom_cur; + } + + if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + { + *value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += *value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char pid = 0; + int ret, i=0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + printk("%s(): set powerdn failed\n", __FUNCTION__); + goto sensor_video_probe_err; + } + + /* soft reset */ + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(50); *///delay 5 microseconds +re: + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &pid); + if (ret != 0) { + SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); + if(++i<100) + goto re; + ret = -ENODEV; + goto sensor_video_probe_err; + } + + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + goto re; + ret = -ENODEV; + goto sensor_video_probe_err; + } + + + return 0; + +sensor_video_probe_err: + + return ret; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd);; + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/gc0308.c b/drivers/media/video/gc0308.c index 7dc2544eacc6..fa2cc65a831b 100755 --- a/drivers/media/video/gc0308.c +++ b/drivers/media/video/gc0308.c @@ -1,2957 +1,1163 @@ - + +#include "generic_sensor.h" /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GC0308 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0308 -#define SENSOR_ID 0x9b -#define SENSOR_MIN_WIDTH 640//176 -#define SENSOR_MIN_HEIGHT 480//144 -#define SENSOR_MAX_WIDTH_REAL 640 -#define SENSOR_MAX_HEIGHT_REAL 480 -#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_5M) - #define SENSOR_MAX_WIDTH 2592 - #define SENSOR_MAX_HEIGHT 1944 -#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_3M) - #define SENSOR_MAX_WIDTH 2048 - #define SENSOR_MAX_HEIGHT 1536 -#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_2M) - #define SENSOR_MAX_WIDTH 1600 - #define SENSOR_MAX_HEIGHT 1200 -#else - #define SENSOR_MAX_WIDTH SENSOR_MAX_WIDTH_REAL - #define SENSOR_MAX_HEIGHT SENSOR_MAX_HEIGHT_REAL -#endif -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -struct reginfo -{ - u8 reg; - u8 val; -}; - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_GC0308_USER_DEFINED_SERIES -#include "gc0308_user_series.c" -#else -/* init 640X480 VGA */ -static struct reginfo sensor_init_data[] = -{ - - {0xfe , 0x80}, - - {0xfe , 0x00}, // set page0 - - {0xd2 , 0x10}, // close AEC - {0x22 , 0x55}, // close AWB - - {0x03 , 0x01}, - {0x04 , 0x2c}, - {0x5a , 0x56}, - {0x5b , 0x40}, - {0x5c , 0x4a}, - - {0x22 , 0x57}, // Open AWB - - {0x01 , 0xfa}, - {0x02 , 0x70}, - {0x0f , 0x01}, - - - {0xe2 , 0x00}, //anti-flicker step [11:8] - {0xe3 , 0x64}, //anti-flicker step [7:0] - - {0xe4 , 0x02}, //exp level 1 16.67fps - {0xe5 , 0x58}, - {0xe6 , 0x03}, //exp level 2 12.5fps - {0xe7 , 0x20}, - {0xe8 , 0x04}, //exp level 3 8.33fps - {0xe9 , 0xb0}, - {0xea , 0x09}, //exp level 4 4.00fps - {0xeb , 0xc4}, - - //{0xec , 0x20}, - - {0x05 , 0x00}, - {0x06 , 0x00}, - {0x07 , 0x00}, - {0x08 , 0x00}, - {0x09 , 0x01}, - {0x0a , 0xe8}, - {0x0b , 0x02}, - {0x0c , 0x88}, - {0x0d , 0x02}, - {0x0e , 0x02}, - {0x10 , 0x22}, - {0x11 , 0xfd}, - {0x12 , 0x2a}, - {0x13 , 0x00}, - //{0x14 , 0x10}, - {0x15 , 0x0a}, - {0x16 , 0x05}, - {0x17 , 0x01}, - {0x18 , 0x44}, - {0x19 , 0x44}, - {0x1a , 0x1e}, - {0x1b , 0x00}, - {0x1c , 0xc1}, - {0x1d , 0x08}, - {0x1e , 0x60}, - {0x1f , 0x17}, - - - {0x20 , 0xff}, - {0x21 , 0xf8}, - {0x22 , 0x57}, - {0x24 , 0xa2}, - {0x25 , 0x0f}, - - //output sync_mode - {0x26 , 0x02}, //0x03 20101016 zhj - {0x2f , 0x01}, - {0x30 , 0xf7}, - {0x31 , 0x50}, - {0x32 , 0x00}, - {0x39 , 0x04}, - {0x3a , 0x18}, - {0x3b , 0x20}, - {0x3c , 0x00}, - {0x3d , 0x00}, - {0x3e , 0x00}, - {0x3f , 0x00}, - {0x50 , 0x10}, - {0x53 , 0x82}, - {0x54 , 0x80}, - {0x55 , 0x80}, - {0x56 , 0x82}, - {0x8b , 0x40}, - {0x8c , 0x40}, - {0x8d , 0x40}, - {0x8e , 0x2e}, - {0x8f , 0x2e}, - {0x90 , 0x2e}, - {0x91 , 0x3c}, - {0x92 , 0x50}, - {0x5d , 0x12}, - {0x5e , 0x1a}, - {0x5f , 0x24}, - {0x60 , 0x07}, - {0x61 , 0x15}, - {0x62 , 0x08}, - {0x64 , 0x03}, - {0x66 , 0xe8}, - {0x67 , 0x86}, - {0x68 , 0xa2}, - {0x69 , 0x18}, - {0x6a , 0x0f}, - {0x6b , 0x00}, - {0x6c , 0x5f}, - {0x6d , 0x8f}, - {0x6e , 0x55}, - {0x6f , 0x38}, - {0x70 , 0x15}, - {0x71 , 0x33}, - {0x72 , 0xdc}, - {0x73 , 0x80}, - {0x74 , 0x02}, - {0x75 , 0x3f}, - {0x76 , 0x02}, - {0x77 , 0x36}, - {0x78 , 0x88}, - {0x79 , 0x81}, - {0x7a , 0x81}, - {0x7b , 0x22}, - {0x7c , 0xff}, - {0x93 , 0x48}, - {0x94 , 0x00}, - {0x95 , 0x05}, - {0x96 , 0xe8}, - {0x97 , 0x40}, - {0x98 , 0xf0}, - {0xb1 , 0x38}, - {0xb2 , 0x38}, - {0xbd , 0x38}, - {0xbe , 0x36}, - {0xd0 , 0xc9}, - {0xd1 , 0x10}, - //{0xd2 , 0x90}, - {0xd3 , 0x80}, - {0xd5 , 0xf2}, - {0xd6 , 0x16}, - {0xdb , 0x92}, - {0xdc , 0xa5}, - {0xdf , 0x23}, - {0xd9 , 0x00}, - {0xda , 0x00}, - {0xe0 , 0x09}, - - {0xed , 0x04}, - {0xee , 0xa0}, - {0xef , 0x40}, - {0x80 , 0x03}, - {0x80 , 0x03}, - {0x9F , 0x10}, - {0xA0 , 0x20}, - {0xA1 , 0x38}, - {0xA2 , 0x4E}, - {0xA3 , 0x63}, - {0xA4 , 0x76}, - {0xA5 , 0x87}, - {0xA6 , 0xA2}, - {0xA7 , 0xB8}, - {0xA8 , 0xCA}, - {0xA9 , 0xD8}, - {0xAA , 0xE3}, - {0xAB , 0xEB}, - {0xAC , 0xF0}, - {0xAD , 0xF8}, - {0xAE , 0xFD}, - {0xAF , 0xFF}, - {0xc0 , 0x00}, - {0xc1 , 0x10}, - {0xc2 , 0x1C}, - {0xc3 , 0x30}, - {0xc4 , 0x43}, - {0xc5 , 0x54}, - {0xc6 , 0x65}, - {0xc7 , 0x75}, - {0xc8 , 0x93}, - {0xc9 , 0xB0}, - {0xca , 0xCB}, - {0xcb , 0xE6}, - {0xcc , 0xFF}, - {0xf0 , 0x02}, - {0xf1 , 0x01}, - {0xf2 , 0x01}, - {0xf3 , 0x30}, - {0xf9 , 0x9f}, - {0xfa , 0x78}, - - //--------------------------------------------------------------- - {0xfe , 0x01},// set page1 - - {0x00 , 0xf5}, - {0x02 , 0x1a}, - {0x0a , 0xa0}, - {0x0b , 0x60}, - {0x0c , 0x08}, - {0x0e , 0x4c}, - {0x0f , 0x39}, - {0x11 , 0x3f}, - {0x12 , 0x72}, - {0x13 , 0x13}, - {0x14 , 0x42}, - {0x15 , 0x43}, - {0x16 , 0xc2}, - {0x17 , 0xa8}, - {0x18 , 0x18}, - {0x19 , 0x40}, - {0x1a , 0xd0}, - {0x1b , 0xf5}, - {0x70 , 0x40}, - {0x71 , 0x58}, - {0x72 , 0x30}, - {0x73 , 0x48}, - {0x74 , 0x20}, - {0x75 , 0x60}, - {0x77 , 0x20}, - {0x78 , 0x32}, - {0x30 , 0x03}, - {0x31 , 0x40}, - {0x32 , 0xe0}, - {0x33 , 0xe0}, - {0x34 , 0xe0}, - {0x35 , 0xb0}, - {0x36 , 0xc0}, - {0x37 , 0xc0}, - {0x38 , 0x04}, - {0x39 , 0x09}, - {0x3a , 0x12}, - {0x3b , 0x1C}, - {0x3c , 0x28}, - {0x3d , 0x31}, - {0x3e , 0x44}, - {0x3f , 0x57}, - {0x40 , 0x6C}, - {0x41 , 0x81}, - {0x42 , 0x94}, - {0x43 , 0xA7}, - {0x44 , 0xB8}, - {0x45 , 0xD6}, - {0x46 , 0xEE}, - {0x47 , 0x0d}, - {0xfe , 0x00}, // set page0 - - //-----------Update the registers 2010/07/06-------------// - //Registers of Page0 - {0xfe , 0x00}, // set page0 - {0x10 , 0x26}, - {0x11 , 0x0d}, // fd,modified by mormo 2010/07/06 - {0x1a , 0x2a}, // 1e,modified by mormo 2010/07/06 - - {0x1c , 0x49}, // c1,modified by mormo 2010/07/06 - {0x1d , 0x9a}, // 08,modified by mormo 2010/07/06 - {0x1e , 0x61}, // 60,modified by mormo 2010/07/06 - - {0x3a , 0x20}, - - {0x50 , 0x14}, // 10,modified by mormo 2010/07/06 - {0x53 , 0x80}, - {0x56 , 0x80}, - - {0x8b , 0x20}, //LSC - {0x8c , 0x20}, - {0x8d , 0x20}, - {0x8e , 0x14}, - {0x8f , 0x10}, - {0x90 , 0x14}, - - {0x94 , 0x02}, - {0x95 , 0x07}, - {0x96 , 0xe0}, - - {0xb1 , 0x40}, // YCPT - {0xb2 , 0x40}, - {0xb3 , 0x40}, - {0xb6 , 0xe0}, - - {0xd0 , 0xcb}, // AECT c9,modifed by mormo 2010/07/06 - {0xd3 , 0x48}, // 80,modified by mormor 2010/07/06 - - {0xf2 , 0x02}, - {0xf7 , 0x12}, - {0xf8 , 0x0a}, - - //Registers of Page1 - {0xfe , 0x01},// set page1 - {0x02 , 0x20}, - {0x04 , 0x10}, - {0x05 , 0x08}, - {0x06 , 0x20}, - {0x08 , 0x0a}, - - {0x0e , 0x44}, - {0x0f , 0x32}, - {0x10 , 0x41}, - {0x11 , 0x37}, - {0x12 , 0x22}, - {0x13 , 0x19}, - {0x14 , 0x44}, - {0x15 , 0x44}, - - {0x19 , 0x50}, - {0x1a , 0xd8}, - - {0x32 , 0x10}, - - {0x35 , 0x00}, - {0x36 , 0x80}, - {0x37 , 0x00}, - //-----------Update the registers end---------// - - - {0xfe , 0x00}, // set page0 - {0xd2 , 0x90}, - - - //-----------GAMMA Select(3)---------------// - {0x9F , 0x10}, - {0xA0 , 0x20}, - {0xA1 , 0x38}, - {0xA2 , 0x4E}, - {0xA3 , 0x63}, - {0xA4 , 0x76}, - {0xA5 , 0x87}, - {0xA6 , 0xA2}, - {0xA7 , 0xB8}, - {0xA8 , 0xCA}, - {0xA9 , 0xD8}, - {0xAA , 0xE3}, - {0xAB , 0xEB}, - {0xAC , 0xF0}, - {0xAD , 0xF8}, - {0xAE , 0xFD}, - {0xAF , 0xFF}, - - /*GC0308_GAMMA_Select, - 1: //smallest gamma curve - {0x9F , 0x0B}, - {0xA0 , 0x16}, - {0xA1 , 0x29}, - {0xA2 , 0x3C}, - {0xA3 , 0x4F}, - {0xA4 , 0x5F}, - {0xA5 , 0x6F}, - {0xA6 , 0x8A}, - {0xA7 , 0x9F}, - {0xA8 , 0xB4}, - {0xA9 , 0xC6}, - {0xAA , 0xD3}, - {0xAB , 0xDD}, - {0xAC , 0xE5}, - {0xAD , 0xF1}, - {0xAE , 0xFA}, - {0xAF , 0xFF}, - - 2: - {0x9F , 0x0E}, - {0xA0 , 0x1C}, - {0xA1 , 0x34}, - {0xA2 , 0x48}, - {0xA3 , 0x5A}, - {0xA4 , 0x6B}, - {0xA5 , 0x7B}, - {0xA6 , 0x95}, - {0xA7 , 0xAB}, - {0xA8 , 0xBF}, - {0xA9 , 0xCE}, - {0xAA , 0xD9}, - {0xAB , 0xE4}, - {0xAC , 0xEC}, - {0xAD , 0xF7}, - {0xAE , 0xFD}, - {0xAF , 0xFF}, - - 3: - {0x9F , 0x10}, - {0xA0 , 0x20}, - {0xA1 , 0x38}, - {0xA2 , 0x4E}, - {0xA3 , 0x63}, - {0xA4 , 0x76}, - {0xA5 , 0x87}, - {0xA6 , 0xA2}, - {0xA7 , 0xB8}, - {0xA8 , 0xCA}, - {0xA9 , 0xD8}, - {0xAA , 0xE3}, - {0xAB , 0xEB}, - {0xAC , 0xF0}, - {0xAD , 0xF8}, - {0xAE , 0xFD}, - {0xAF , 0xFF}, - - 4: - {0x9F , 0x14}, - {0xA0 , 0x28}, - {0xA1 , 0x44}, - {0xA2 , 0x5D}, - {0xA3 , 0x72}, - {0xA4 , 0x86}, - {0xA5 , 0x95}, - {0xA6 , 0xB1}, - {0xA7 , 0xC6}, - {0xA8 , 0xD5}, - {0xA9 , 0xE1}, - {0xAA , 0xEA}, - {0xAB , 0xF1}, - {0xAC , 0xF5}, - {0xAD , 0xFB}, - {0xAE , 0xFE}, - {0xAF , 0xFF}, - - 5: //largest gamma curve - {0x9F , 0x15}, - {0xA0 , 0x2A}, - {0xA1 , 0x4A}, - {0xA2 , 0x67}, - {0xA3 , 0x79}, - {0xA4 , 0x8C}, - {0xA5 , 0x9A}, - {0xA6 , 0xB3}, - {0xA7 , 0xC5}, - {0xA8 , 0xD5}, - {0xA9 , 0xDF}, - {0xAA , 0xE8}, - {0xAB , 0xEE}, - {0xAC , 0xF3}, - {0xAD , 0xFA}, - {0xAE , 0xFD}, - {0xAF , 0xFF}, */ - //-----------GAMMA Select End--------------// - - - - - //-------------H_V_Switch(4)---------------// - {0x14 , 0x10}, //0x10 - - /*GC0308_H_V_Switch, - - 1: // normal - {0x14 , 0x10}, - - 2: // IMAGE_H_MIRROR - {0x14 , 0x11}, - - 3: // IMAGE_V_MIRROR - {0x14 , 0x12}, - - 4: // IMAGE_HV_MIRROR - {0x14 , 0x13}, - */ - //-------------H_V_Select End--------------// - -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0x00,0x00} -}; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0x0, 0x0}, -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - {0x17, 0x13}, - {0x18, 0x01}, - {0x32, 0xbf}, - {0x19, 0x03}, - {0x1a, 0x7b}, - {0x03, 0x0a}, - {0x00,0x00} -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x00,0x00} -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {0x00,0x00} -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - {0x00,0x00} -}; -#endif -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x00, 0x00} -}; - - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x5a, 0x4c}, - {0x5b, 0x40}, - {0x5c, 0x4a}, - {0x22, 0x57}, - {0x00, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x22, 0x55}, // Disable AWB - {0x5a, 0x5a}, - {0x5b, 0x42}, - {0x5c, 0x40}, - {0x00, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x22, 0x55}, // Disable AWB - {0x5a, 0x50}, - {0x5b, 0x45}, - {0x5c, 0x40}, - {0x00, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x22, 0x55}, // Disable AWB - {0x5a, 0x48}, - {0x5b, 0x40}, - {0x5c, 0x5c}, - {0x00, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x22, 0x55}, // Disable AWB - {0x5a, 0x40}, - {0x5b, 0x42}, - {0x5c, 0x50}, - {0x00, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - {0xb5, 0xe0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - {0xb5, 0xf0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - {0xb5, 0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - {0xb5, 0x20}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - {0xb5, 0x30}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - {0xb5, 0x40}, - {0x00, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x23,0x00}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x73,0x00}, - {0x77,0x38}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x73,0x00}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x73,0x00}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0xd2}, - {0xbb,0x28}, - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x23,0x01}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x73,0x00}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00,0x00} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x73,0x00}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x50}, - {0xbb,0xe0}, - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0x7f}, - {0xd2,0x90}, - {0x77,0x88}, - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0xc0}, - {0xbb,0xc0}, - {0x00,0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {0xd3, 0x30}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - {0xd3, 0x38}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - {0xd3, 0x40}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - {0xd3, 0x48}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - {0xd3, 0x50}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - {0xd3, 0x58}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - {0xd3, 0x60}, - {0x00, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0x00, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - {0xb3,0x34}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - {0xb3,0x38}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - {0xb3,0x3d}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - {0xb3,0x40}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - {0xb3,0x44}, - {0x00, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - {0xb3,0x48}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - {0xb3,0x50}, - {0x00, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0x00, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x00, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - {0xec, 0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_SceneNight[] = -{ - {0xec, 0x30}, - {0x00, 0x00} -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg & 0xFF; - buf[1] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - //u8 buf[2]; - u8 buf[1]; - struct i2c_msg msg[2]; - - //buf[0] = reg >> 8; - buf[0] = reg; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 1; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -#if 1 -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - - //for(i=0; i < sizeof(sensor_init_data) / 2;i++) - while((regarray[i].reg != 0) || (regarray[i].val != 0)) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - i++; - } - - return 0; -} -#else -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - u8 val_read; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - err = sensor_read(client, regarray[i].reg, &val_read); - SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); - i++; - } - return 0; -} -#endif - -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int ret; - int i = 0; - - u8 value; - - SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); - for(i=0;ipowerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - int ret; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); */ //delay 5 microseconds - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - //u8 reg_val; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } -#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION) - else if (((set_w <= SENSOR_MAX_WIDTH) && (set_h <= SENSOR_MAX_HEIGHT)) ) - { - winseqe_set_addr = sensor_vga; - set_w = SENSOR_MAX_WIDTH_REAL; - set_h = SENSOR_MAX_HEIGHT_REAL; - } -#endif - - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - msleep(600); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - /* ddl@rock-chips.com : It is query max resolution only. */ - if (mf->reserved[6] == 0xfefe5a5a) { - mf->height = SENSOR_MAX_HEIGHT; - mf->width = SENSOR_MAX_WIDTH; - ret = 0; - goto sensor_try_fmt_end; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } -#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION) - else if (((set_w <= SENSOR_MAX_WIDTH) && (set_h <= SENSOR_MAX_HEIGHT)) ) - { - set_w = SENSOR_MAX_WIDTH_REAL; - set_h = SENSOR_MAX_HEIGHT_REAL; - } -#endif - - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - - mf->colorspace = fmt->colorspace; -sensor_try_fmt_end: - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) - { - *value = digitalzoom_total - digitalzoom_cur; - } - - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) - { - *value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += *value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char pid = 0; - int ret; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(50); *///delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &pid); - if (ret != 0) { - SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GC0308 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0308 +#define SENSOR_ID 0x9b +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0xfe , 0x80}, + + {0xfe , 0x00}, // set page0 + + {0xd2 , 0x10}, // close AEC + {0x22 , 0x55}, // close AWB + + {0x03 , 0x01}, + {0x04 , 0x2c}, + {0x5a , 0x56}, + {0x5b , 0x40}, + {0x5c , 0x4a}, + + {0x22 , 0x57}, // Open AWB + + {0x01 , 0xfa}, + {0x02 , 0x70}, + {0x0f , 0x01}, + + + {0xe2 , 0x00}, //anti-flicker step [11:8] + {0xe3 , 0x64}, //anti-flicker step [7:0] + + {0xe4 , 0x02}, //exp level 1 16.67fps + {0xe5 , 0x58}, + {0xe6 , 0x03}, //exp level 2 12.5fps + {0xe7 , 0x20}, + {0xe8 , 0x04}, //exp level 3 8.33fps + {0xe9 , 0xb0}, + {0xea , 0x09}, //exp level 4 4.00fps + {0xeb , 0xc4}, + + //{0xec , 0x20}, + + {0x05 , 0x00}, + {0x06 , 0x00}, + {0x07 , 0x00}, + {0x08 , 0x00}, + {0x09 , 0x01}, + {0x0a , 0xe8}, + {0x0b , 0x02}, + {0x0c , 0x88}, + {0x0d , 0x02}, + {0x0e , 0x02}, + {0x10 , 0x22}, + {0x11 , 0xfd}, + {0x12 , 0x2a}, + {0x13 , 0x00}, + {0x14 , 0x10}, //0x10 + //-------------H_V_Switch(4)---------------// + /* 1: // normal + {0x14 , 0x10}, + 2: // IMAGE_H_MIRROR + {0x14 , 0x11}, + + 3: // IMAGE_V_MIRROR + {0x14 , 0x12}, + + 4: // IMAGE_HV_MIRROR + {0x14 , 0x13},*/ + {0x15 , 0x0a}, + {0x16 , 0x05}, + {0x17 , 0x01}, + {0x18 , 0x44}, + {0x19 , 0x44}, + {0x1a , 0x1e}, + {0x1b , 0x00}, + {0x1c , 0xc1}, + {0x1d , 0x08}, + {0x1e , 0x60}, + {0x1f , 0x17}, + + + {0x20 , 0xff}, + {0x21 , 0xf8}, + {0x22 , 0x57}, + {0x24 , 0xa2}, + {0x25 , 0x0f}, + + //output sync_mode + {0x26 , 0x02}, //0x03 20101016 zhj + {0x2f , 0x01}, + {0x30 , 0xf7}, + {0x31 , 0x50}, + {0x32 , 0x00}, + {0x39 , 0x04}, + {0x3a , 0x18}, + {0x3b , 0x20}, + {0x3c , 0x00}, + {0x3d , 0x00}, + {0x3e , 0x00}, + {0x3f , 0x00}, + {0x50 , 0x10}, + {0x53 , 0x82}, + {0x54 , 0x80}, + {0x55 , 0x80}, + {0x56 , 0x82}, + {0x8b , 0x40}, + {0x8c , 0x40}, + {0x8d , 0x40}, + {0x8e , 0x2e}, + {0x8f , 0x2e}, + {0x90 , 0x2e}, + {0x91 , 0x3c}, + {0x92 , 0x50}, + {0x5d , 0x12}, + {0x5e , 0x1a}, + {0x5f , 0x24}, + {0x60 , 0x07}, + {0x61 , 0x15}, + {0x62 , 0x08}, + {0x64 , 0x03}, + {0x66 , 0xe8}, + {0x67 , 0x86}, + {0x68 , 0xa2}, + {0x69 , 0x18}, + {0x6a , 0x0f}, + {0x6b , 0x00}, + {0x6c , 0x5f}, + {0x6d , 0x8f}, + {0x6e , 0x55}, + {0x6f , 0x38}, + {0x70 , 0x15}, + {0x71 , 0x33}, + {0x72 , 0xdc}, + {0x73 , 0x80}, + {0x74 , 0x02}, + {0x75 , 0x3f}, + {0x76 , 0x02}, + {0x77 , 0x36}, + {0x78 , 0x88}, + {0x79 , 0x81}, + {0x7a , 0x81}, + {0x7b , 0x22}, + {0x7c , 0xff}, + {0x93 , 0x48}, + {0x94 , 0x00}, + {0x95 , 0x05}, + {0x96 , 0xe8}, + {0x97 , 0x40}, + {0x98 , 0xf0}, + {0xb1 , 0x38}, + {0xb2 , 0x38}, + {0xbd , 0x38}, + {0xbe , 0x36}, + {0xd0 , 0xc9}, + {0xd1 , 0x10}, + //{0xd2 , 0x90}, + {0xd3 , 0x80}, + {0xd5 , 0xf2}, + {0xd6 , 0x16}, + {0xdb , 0x92}, + {0xdc , 0xa5}, + {0xdf , 0x23}, + {0xd9 , 0x00}, + {0xda , 0x00}, + {0xe0 , 0x09}, + + {0xed , 0x04}, + {0xee , 0xa0}, + {0xef , 0x40}, + {0x80 , 0x03}, + {0x80 , 0x03}, + {0x9F , 0x10}, + {0xA0 , 0x20}, + {0xA1 , 0x38}, + {0xA2 , 0x4E}, + {0xA3 , 0x63}, + {0xA4 , 0x76}, + {0xA5 , 0x87}, + {0xA6 , 0xA2}, + {0xA7 , 0xB8}, + {0xA8 , 0xCA}, + {0xA9 , 0xD8}, + {0xAA , 0xE3}, + {0xAB , 0xEB}, + {0xAC , 0xF0}, + {0xAD , 0xF8}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + /*GC0308_GAMMA_Select, + 1: //smallest gamma curve + {0x9F , 0x0B}, + {0xA0 , 0x16}, + {0xA1 , 0x29}, + {0xA2 , 0x3C}, + {0xA3 , 0x4F}, + {0xA4 , 0x5F}, + {0xA5 , 0x6F}, + {0xA6 , 0x8A}, + {0xA7 , 0x9F}, + {0xA8 , 0xB4}, + {0xA9 , 0xC6}, + {0xAA , 0xD3}, + {0xAB , 0xDD}, + {0xAC , 0xE5}, + {0xAD , 0xF1}, + {0xAE , 0xFA}, + {0xAF , 0xFF}, + + 2: + {0x9F , 0x0E}, + {0xA0 , 0x1C}, + {0xA1 , 0x34}, + {0xA2 , 0x48}, + {0xA3 , 0x5A}, + {0xA4 , 0x6B}, + {0xA5 , 0x7B}, + {0xA6 , 0x95}, + {0xA7 , 0xAB}, + {0xA8 , 0xBF}, + {0xA9 , 0xCE}, + {0xAA , 0xD9}, + {0xAB , 0xE4}, + {0xAC , 0xEC}, + {0xAD , 0xF7}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + + 3: + {0x9F , 0x10}, + {0xA0 , 0x20}, + {0xA1 , 0x38}, + {0xA2 , 0x4E}, + {0xA3 , 0x63}, + {0xA4 , 0x76}, + {0xA5 , 0x87}, + {0xA6 , 0xA2}, + {0xA7 , 0xB8}, + {0xA8 , 0xCA}, + {0xA9 , 0xD8}, + {0xAA , 0xE3}, + {0xAB , 0xEB}, + {0xAC , 0xF0}, + {0xAD , 0xF8}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + + 4: + {0x9F , 0x14}, + {0xA0 , 0x28}, + {0xA1 , 0x44}, + {0xA2 , 0x5D}, + {0xA3 , 0x72}, + {0xA4 , 0x86}, + {0xA5 , 0x95}, + {0xA6 , 0xB1}, + {0xA7 , 0xC6}, + {0xA8 , 0xD5}, + {0xA9 , 0xE1}, + {0xAA , 0xEA}, + {0xAB , 0xF1}, + {0xAC , 0xF5}, + {0xAD , 0xFB}, + {0xAE , 0xFE}, + {0xAF , 0xFF}, + + 5: //largest gamma curve + {0x9F , 0x15}, + {0xA0 , 0x2A}, + {0xA1 , 0x4A}, + {0xA2 , 0x67}, + {0xA3 , 0x79}, + {0xA4 , 0x8C}, + {0xA5 , 0x9A}, + {0xA6 , 0xB3}, + {0xA7 , 0xC5}, + {0xA8 , 0xD5}, + {0xA9 , 0xDF}, + {0xAA , 0xE8}, + {0xAB , 0xEE}, + {0xAC , 0xF3}, + {0xAD , 0xFA}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, */ + //-----------GAMMA Select End--------------// + + {0xc0 , 0x00}, + {0xc1 , 0x10}, + {0xc2 , 0x1C}, + {0xc3 , 0x30}, + {0xc4 , 0x43}, + {0xc5 , 0x54}, + {0xc6 , 0x65}, + {0xc7 , 0x75}, + {0xc8 , 0x93}, + {0xc9 , 0xB0}, + {0xca , 0xCB}, + {0xcb , 0xE6}, + {0xcc , 0xFF}, + {0xf0 , 0x02}, + {0xf1 , 0x01}, + {0xf2 , 0x01}, + {0xf3 , 0x30}, + {0xf9 , 0x9f}, + {0xfa , 0x78}, + + //--------------------------------------------------------------- + {0xfe , 0x01},// set page1 + + {0x00 , 0xf5}, + {0x02 , 0x1a}, + {0x0a , 0xa0}, + {0x0b , 0x60}, + {0x0c , 0x08}, + {0x0e , 0x4c}, + {0x0f , 0x39}, + {0x11 , 0x3f}, + {0x12 , 0x72}, + {0x13 , 0x13}, + {0x14 , 0x42}, + {0x15 , 0x43}, + {0x16 , 0xc2}, + {0x17 , 0xa8}, + {0x18 , 0x18}, + {0x19 , 0x40}, + {0x1a , 0xd0}, + {0x1b , 0xf5}, + {0x70 , 0x40}, + {0x71 , 0x58}, + {0x72 , 0x30}, + {0x73 , 0x48}, + {0x74 , 0x20}, + {0x75 , 0x60}, + {0x77 , 0x20}, + {0x78 , 0x32}, + {0x30 , 0x03}, + {0x31 , 0x40}, + {0x32 , 0xe0}, + {0x33 , 0xe0}, + {0x34 , 0xe0}, + {0x35 , 0xb0}, + {0x36 , 0xc0}, + {0x37 , 0xc0}, + {0x38 , 0x04}, + {0x39 , 0x09}, + {0x3a , 0x12}, + {0x3b , 0x1C}, + {0x3c , 0x28}, + {0x3d , 0x31}, + {0x3e , 0x44}, + {0x3f , 0x57}, + {0x40 , 0x6C}, + {0x41 , 0x81}, + {0x42 , 0x94}, + {0x43 , 0xA7}, + {0x44 , 0xB8}, + {0x45 , 0xD6}, + {0x46 , 0xEE}, + {0x47 , 0x0d}, + {0xfe , 0x00}, // set page0 + + //-----------Update the registers 2010/07/06-------------// + //Registers of Page0 + {0xfe , 0x00}, // set page0 + {0x10 , 0x26}, + {0x11 , 0x0d}, // fd,modified by mormo 2010/07/06 + {0x1a , 0x2a}, // 1e,modified by mormo 2010/07/06 + + {0x1c , 0x49}, // c1,modified by mormo 2010/07/06 + {0x1d , 0x9a}, // 08,modified by mormo 2010/07/06 + {0x1e , 0x61}, // 60,modified by mormo 2010/07/06 + + {0x3a , 0x20}, + + {0x50 , 0x14}, // 10,modified by mormo 2010/07/06 + {0x53 , 0x80}, + {0x56 , 0x80}, + + {0x8b , 0x20}, //LSC + {0x8c , 0x20}, + {0x8d , 0x20}, + {0x8e , 0x14}, + {0x8f , 0x10}, + {0x90 , 0x14}, + + {0x94 , 0x02}, + {0x95 , 0x07}, + {0x96 , 0xe0}, + + {0xb1 , 0x40}, // YCPT + {0xb2 , 0x40}, + {0xb3 , 0x40}, + {0xb6 , 0xe0}, + + {0xd0 , 0xcb}, // AECT c9,modifed by mormo 2010/07/06 + {0xd3 , 0x48}, // 80,modified by mormor 2010/07/06 + + {0xf2 , 0x02}, + {0xf7 , 0x12}, + {0xf8 , 0x0a}, + + //Registers of Page1 + {0xfe , 0x01},// set page1 + {0x02 , 0x20}, + {0x04 , 0x10}, + {0x05 , 0x08}, + {0x06 , 0x20}, + {0x08 , 0x0a}, + + {0x0e , 0x44}, + {0x0f , 0x32}, + {0x10 , 0x41}, + {0x11 , 0x37}, + {0x12 , 0x22}, + {0x13 , 0x19}, + {0x14 , 0x44}, + {0x15 , 0x44}, + + {0x19 , 0x50}, + {0x1a , 0xd8}, + + {0x32 , 0x10}, + + {0x35 , 0x00}, + {0x36 , 0x80}, + {0x37 , 0x00}, + //-----------Update the registers end---------// + + + {0xfe , 0x00}, // set page0 + {0xd2 , 0x90}, + 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[] = +{ + + 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[]={ + SensorRegVal(0x00,0), + 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[]= +{ + {0x5a, 0x4c}, + {0x5b, 0x40}, + {0x5c, 0x4a}, + {0x22, 0x57}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x22, 0x55}, // Disable AWB + {0x5a, 0x5a}, + {0x5b, 0x42}, + {0x5c, 0x40}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x22, 0x55}, // Disable AWB + {0x5a, 0x50}, + {0x5b, 0x45}, + {0x5c, 0x40}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x22, 0x55}, // Disable AWB + {0x5a, 0x48}, + {0x5b, 0x40}, + {0x5c, 0x5c}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x22, 0x55}, // Disable AWB + {0x5a, 0x40}, + {0x5b, 0x42}, + {0x5c, 0x50}, + 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 + {0xb5, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + {0xb5, 0xf0}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + {0xb5, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0xb5, 0x20}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0xb5, 0x30}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0xb5, 0x40}, + + 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[] = +{ + {0x23,0x00}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x38}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xd2}, + {0xbb,0x28}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x23,0x01}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x50}, + {0xbb,0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x77,0x88}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xc0}, + {0xbb,0xc0}, + 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[]= +{ + {0xd3, 0x30}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + {0xd3, 0x38}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + {0xd3, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + {0xd3, 0x48}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + {0xd3, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + {0xd3, 0x58}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + {0xd3, 0x60}, + 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[]= +{ + {0xb3,0x34}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + {0xb3,0x38}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + {0xb3,0x3d}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + {0xb3,0x40}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + {0xb3,0x44}, + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + {0xb3,0x48}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + {0xb3,0x50}, + + 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[] = +{ + {0xec, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0xec, 0x30}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + + //{0xfe , 0x00}, // set page0 + + //{0x14 , 0x13}, //0x10 + //-------------H_V_Switch(4)---------------// + /* 1: // normal + {0x14 , 0x10}, + 2: // IMAGE_H_MIRROR + {0x14 , 0x11}, + + 3: // IMAGE_V_MIRROR + {0x14 , 0x12}, + + 4: // IMAGE_HV_MIRROR + {0x14 , 0x13},*/ + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x14, &val); + if (err == 0) { + if((val & 0x1) == 0) + err = sensor_write(client, 0x14, (val |0x1)); + else + err = sensor_write(client, 0x14, (val & 0xfe)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + + //{0xfe , 0x00}, // set page0 + + //{0x14 , 0x13}, //0x10 + //-------------H_V_Switch(4)---------------// + /* 1: // normal + {0x14 , 0x10}, + 2: // IMAGE_H_MIRROR + {0x14 , 0x11}, + + 3: // IMAGE_V_MIRROR + {0x14 , 0x12}, + + 4: // IMAGE_HV_MIRROR + {0x14 , 0x13},*/ + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x14, &val); + if (err == 0) { + if((val & 0x2) == 0) + err = sensor_write(client, 0x14, (val |0x2)); + else + err = sensor_write(client, 0x14, (val & 0xfc)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gc0308_old.c b/drivers/media/video/gc0308_old.c new file mode 100755 index 000000000000..7dc2544eacc6 --- /dev/null +++ b/drivers/media/video/gc0308_old.c @@ -0,0 +1,2957 @@ + +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC0308 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0308 +#define SENSOR_ID 0x9b +#define SENSOR_MIN_WIDTH 640//176 +#define SENSOR_MIN_HEIGHT 480//144 +#define SENSOR_MAX_WIDTH_REAL 640 +#define SENSOR_MAX_HEIGHT_REAL 480 +#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_5M) + #define SENSOR_MAX_WIDTH 2592 + #define SENSOR_MAX_HEIGHT 1944 +#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_3M) + #define SENSOR_MAX_WIDTH 2048 + #define SENSOR_MAX_HEIGHT 1536 +#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_2M) + #define SENSOR_MAX_WIDTH 1600 + #define SENSOR_MAX_HEIGHT 1200 +#else + #define SENSOR_MAX_WIDTH SENSOR_MAX_WIDTH_REAL + #define SENSOR_MAX_HEIGHT SENSOR_MAX_HEIGHT_REAL +#endif +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u8 reg; + u8 val; +}; + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_GC0308_USER_DEFINED_SERIES +#include "gc0308_user_series.c" +#else +/* init 640X480 VGA */ +static struct reginfo sensor_init_data[] = +{ + + {0xfe , 0x80}, + + {0xfe , 0x00}, // set page0 + + {0xd2 , 0x10}, // close AEC + {0x22 , 0x55}, // close AWB + + {0x03 , 0x01}, + {0x04 , 0x2c}, + {0x5a , 0x56}, + {0x5b , 0x40}, + {0x5c , 0x4a}, + + {0x22 , 0x57}, // Open AWB + + {0x01 , 0xfa}, + {0x02 , 0x70}, + {0x0f , 0x01}, + + + {0xe2 , 0x00}, //anti-flicker step [11:8] + {0xe3 , 0x64}, //anti-flicker step [7:0] + + {0xe4 , 0x02}, //exp level 1 16.67fps + {0xe5 , 0x58}, + {0xe6 , 0x03}, //exp level 2 12.5fps + {0xe7 , 0x20}, + {0xe8 , 0x04}, //exp level 3 8.33fps + {0xe9 , 0xb0}, + {0xea , 0x09}, //exp level 4 4.00fps + {0xeb , 0xc4}, + + //{0xec , 0x20}, + + {0x05 , 0x00}, + {0x06 , 0x00}, + {0x07 , 0x00}, + {0x08 , 0x00}, + {0x09 , 0x01}, + {0x0a , 0xe8}, + {0x0b , 0x02}, + {0x0c , 0x88}, + {0x0d , 0x02}, + {0x0e , 0x02}, + {0x10 , 0x22}, + {0x11 , 0xfd}, + {0x12 , 0x2a}, + {0x13 , 0x00}, + //{0x14 , 0x10}, + {0x15 , 0x0a}, + {0x16 , 0x05}, + {0x17 , 0x01}, + {0x18 , 0x44}, + {0x19 , 0x44}, + {0x1a , 0x1e}, + {0x1b , 0x00}, + {0x1c , 0xc1}, + {0x1d , 0x08}, + {0x1e , 0x60}, + {0x1f , 0x17}, + + + {0x20 , 0xff}, + {0x21 , 0xf8}, + {0x22 , 0x57}, + {0x24 , 0xa2}, + {0x25 , 0x0f}, + + //output sync_mode + {0x26 , 0x02}, //0x03 20101016 zhj + {0x2f , 0x01}, + {0x30 , 0xf7}, + {0x31 , 0x50}, + {0x32 , 0x00}, + {0x39 , 0x04}, + {0x3a , 0x18}, + {0x3b , 0x20}, + {0x3c , 0x00}, + {0x3d , 0x00}, + {0x3e , 0x00}, + {0x3f , 0x00}, + {0x50 , 0x10}, + {0x53 , 0x82}, + {0x54 , 0x80}, + {0x55 , 0x80}, + {0x56 , 0x82}, + {0x8b , 0x40}, + {0x8c , 0x40}, + {0x8d , 0x40}, + {0x8e , 0x2e}, + {0x8f , 0x2e}, + {0x90 , 0x2e}, + {0x91 , 0x3c}, + {0x92 , 0x50}, + {0x5d , 0x12}, + {0x5e , 0x1a}, + {0x5f , 0x24}, + {0x60 , 0x07}, + {0x61 , 0x15}, + {0x62 , 0x08}, + {0x64 , 0x03}, + {0x66 , 0xe8}, + {0x67 , 0x86}, + {0x68 , 0xa2}, + {0x69 , 0x18}, + {0x6a , 0x0f}, + {0x6b , 0x00}, + {0x6c , 0x5f}, + {0x6d , 0x8f}, + {0x6e , 0x55}, + {0x6f , 0x38}, + {0x70 , 0x15}, + {0x71 , 0x33}, + {0x72 , 0xdc}, + {0x73 , 0x80}, + {0x74 , 0x02}, + {0x75 , 0x3f}, + {0x76 , 0x02}, + {0x77 , 0x36}, + {0x78 , 0x88}, + {0x79 , 0x81}, + {0x7a , 0x81}, + {0x7b , 0x22}, + {0x7c , 0xff}, + {0x93 , 0x48}, + {0x94 , 0x00}, + {0x95 , 0x05}, + {0x96 , 0xe8}, + {0x97 , 0x40}, + {0x98 , 0xf0}, + {0xb1 , 0x38}, + {0xb2 , 0x38}, + {0xbd , 0x38}, + {0xbe , 0x36}, + {0xd0 , 0xc9}, + {0xd1 , 0x10}, + //{0xd2 , 0x90}, + {0xd3 , 0x80}, + {0xd5 , 0xf2}, + {0xd6 , 0x16}, + {0xdb , 0x92}, + {0xdc , 0xa5}, + {0xdf , 0x23}, + {0xd9 , 0x00}, + {0xda , 0x00}, + {0xe0 , 0x09}, + + {0xed , 0x04}, + {0xee , 0xa0}, + {0xef , 0x40}, + {0x80 , 0x03}, + {0x80 , 0x03}, + {0x9F , 0x10}, + {0xA0 , 0x20}, + {0xA1 , 0x38}, + {0xA2 , 0x4E}, + {0xA3 , 0x63}, + {0xA4 , 0x76}, + {0xA5 , 0x87}, + {0xA6 , 0xA2}, + {0xA7 , 0xB8}, + {0xA8 , 0xCA}, + {0xA9 , 0xD8}, + {0xAA , 0xE3}, + {0xAB , 0xEB}, + {0xAC , 0xF0}, + {0xAD , 0xF8}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + {0xc0 , 0x00}, + {0xc1 , 0x10}, + {0xc2 , 0x1C}, + {0xc3 , 0x30}, + {0xc4 , 0x43}, + {0xc5 , 0x54}, + {0xc6 , 0x65}, + {0xc7 , 0x75}, + {0xc8 , 0x93}, + {0xc9 , 0xB0}, + {0xca , 0xCB}, + {0xcb , 0xE6}, + {0xcc , 0xFF}, + {0xf0 , 0x02}, + {0xf1 , 0x01}, + {0xf2 , 0x01}, + {0xf3 , 0x30}, + {0xf9 , 0x9f}, + {0xfa , 0x78}, + + //--------------------------------------------------------------- + {0xfe , 0x01},// set page1 + + {0x00 , 0xf5}, + {0x02 , 0x1a}, + {0x0a , 0xa0}, + {0x0b , 0x60}, + {0x0c , 0x08}, + {0x0e , 0x4c}, + {0x0f , 0x39}, + {0x11 , 0x3f}, + {0x12 , 0x72}, + {0x13 , 0x13}, + {0x14 , 0x42}, + {0x15 , 0x43}, + {0x16 , 0xc2}, + {0x17 , 0xa8}, + {0x18 , 0x18}, + {0x19 , 0x40}, + {0x1a , 0xd0}, + {0x1b , 0xf5}, + {0x70 , 0x40}, + {0x71 , 0x58}, + {0x72 , 0x30}, + {0x73 , 0x48}, + {0x74 , 0x20}, + {0x75 , 0x60}, + {0x77 , 0x20}, + {0x78 , 0x32}, + {0x30 , 0x03}, + {0x31 , 0x40}, + {0x32 , 0xe0}, + {0x33 , 0xe0}, + {0x34 , 0xe0}, + {0x35 , 0xb0}, + {0x36 , 0xc0}, + {0x37 , 0xc0}, + {0x38 , 0x04}, + {0x39 , 0x09}, + {0x3a , 0x12}, + {0x3b , 0x1C}, + {0x3c , 0x28}, + {0x3d , 0x31}, + {0x3e , 0x44}, + {0x3f , 0x57}, + {0x40 , 0x6C}, + {0x41 , 0x81}, + {0x42 , 0x94}, + {0x43 , 0xA7}, + {0x44 , 0xB8}, + {0x45 , 0xD6}, + {0x46 , 0xEE}, + {0x47 , 0x0d}, + {0xfe , 0x00}, // set page0 + + //-----------Update the registers 2010/07/06-------------// + //Registers of Page0 + {0xfe , 0x00}, // set page0 + {0x10 , 0x26}, + {0x11 , 0x0d}, // fd,modified by mormo 2010/07/06 + {0x1a , 0x2a}, // 1e,modified by mormo 2010/07/06 + + {0x1c , 0x49}, // c1,modified by mormo 2010/07/06 + {0x1d , 0x9a}, // 08,modified by mormo 2010/07/06 + {0x1e , 0x61}, // 60,modified by mormo 2010/07/06 + + {0x3a , 0x20}, + + {0x50 , 0x14}, // 10,modified by mormo 2010/07/06 + {0x53 , 0x80}, + {0x56 , 0x80}, + + {0x8b , 0x20}, //LSC + {0x8c , 0x20}, + {0x8d , 0x20}, + {0x8e , 0x14}, + {0x8f , 0x10}, + {0x90 , 0x14}, + + {0x94 , 0x02}, + {0x95 , 0x07}, + {0x96 , 0xe0}, + + {0xb1 , 0x40}, // YCPT + {0xb2 , 0x40}, + {0xb3 , 0x40}, + {0xb6 , 0xe0}, + + {0xd0 , 0xcb}, // AECT c9,modifed by mormo 2010/07/06 + {0xd3 , 0x48}, // 80,modified by mormor 2010/07/06 + + {0xf2 , 0x02}, + {0xf7 , 0x12}, + {0xf8 , 0x0a}, + + //Registers of Page1 + {0xfe , 0x01},// set page1 + {0x02 , 0x20}, + {0x04 , 0x10}, + {0x05 , 0x08}, + {0x06 , 0x20}, + {0x08 , 0x0a}, + + {0x0e , 0x44}, + {0x0f , 0x32}, + {0x10 , 0x41}, + {0x11 , 0x37}, + {0x12 , 0x22}, + {0x13 , 0x19}, + {0x14 , 0x44}, + {0x15 , 0x44}, + + {0x19 , 0x50}, + {0x1a , 0xd8}, + + {0x32 , 0x10}, + + {0x35 , 0x00}, + {0x36 , 0x80}, + {0x37 , 0x00}, + //-----------Update the registers end---------// + + + {0xfe , 0x00}, // set page0 + {0xd2 , 0x90}, + + + //-----------GAMMA Select(3)---------------// + {0x9F , 0x10}, + {0xA0 , 0x20}, + {0xA1 , 0x38}, + {0xA2 , 0x4E}, + {0xA3 , 0x63}, + {0xA4 , 0x76}, + {0xA5 , 0x87}, + {0xA6 , 0xA2}, + {0xA7 , 0xB8}, + {0xA8 , 0xCA}, + {0xA9 , 0xD8}, + {0xAA , 0xE3}, + {0xAB , 0xEB}, + {0xAC , 0xF0}, + {0xAD , 0xF8}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + + /*GC0308_GAMMA_Select, + 1: //smallest gamma curve + {0x9F , 0x0B}, + {0xA0 , 0x16}, + {0xA1 , 0x29}, + {0xA2 , 0x3C}, + {0xA3 , 0x4F}, + {0xA4 , 0x5F}, + {0xA5 , 0x6F}, + {0xA6 , 0x8A}, + {0xA7 , 0x9F}, + {0xA8 , 0xB4}, + {0xA9 , 0xC6}, + {0xAA , 0xD3}, + {0xAB , 0xDD}, + {0xAC , 0xE5}, + {0xAD , 0xF1}, + {0xAE , 0xFA}, + {0xAF , 0xFF}, + + 2: + {0x9F , 0x0E}, + {0xA0 , 0x1C}, + {0xA1 , 0x34}, + {0xA2 , 0x48}, + {0xA3 , 0x5A}, + {0xA4 , 0x6B}, + {0xA5 , 0x7B}, + {0xA6 , 0x95}, + {0xA7 , 0xAB}, + {0xA8 , 0xBF}, + {0xA9 , 0xCE}, + {0xAA , 0xD9}, + {0xAB , 0xE4}, + {0xAC , 0xEC}, + {0xAD , 0xF7}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + + 3: + {0x9F , 0x10}, + {0xA0 , 0x20}, + {0xA1 , 0x38}, + {0xA2 , 0x4E}, + {0xA3 , 0x63}, + {0xA4 , 0x76}, + {0xA5 , 0x87}, + {0xA6 , 0xA2}, + {0xA7 , 0xB8}, + {0xA8 , 0xCA}, + {0xA9 , 0xD8}, + {0xAA , 0xE3}, + {0xAB , 0xEB}, + {0xAC , 0xF0}, + {0xAD , 0xF8}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, + + 4: + {0x9F , 0x14}, + {0xA0 , 0x28}, + {0xA1 , 0x44}, + {0xA2 , 0x5D}, + {0xA3 , 0x72}, + {0xA4 , 0x86}, + {0xA5 , 0x95}, + {0xA6 , 0xB1}, + {0xA7 , 0xC6}, + {0xA8 , 0xD5}, + {0xA9 , 0xE1}, + {0xAA , 0xEA}, + {0xAB , 0xF1}, + {0xAC , 0xF5}, + {0xAD , 0xFB}, + {0xAE , 0xFE}, + {0xAF , 0xFF}, + + 5: //largest gamma curve + {0x9F , 0x15}, + {0xA0 , 0x2A}, + {0xA1 , 0x4A}, + {0xA2 , 0x67}, + {0xA3 , 0x79}, + {0xA4 , 0x8C}, + {0xA5 , 0x9A}, + {0xA6 , 0xB3}, + {0xA7 , 0xC5}, + {0xA8 , 0xD5}, + {0xA9 , 0xDF}, + {0xAA , 0xE8}, + {0xAB , 0xEE}, + {0xAC , 0xF3}, + {0xAD , 0xFA}, + {0xAE , 0xFD}, + {0xAF , 0xFF}, */ + //-----------GAMMA Select End--------------// + + + + + //-------------H_V_Switch(4)---------------// + {0x14 , 0x10}, //0x10 + + /*GC0308_H_V_Switch, + + 1: // normal + {0x14 , 0x10}, + + 2: // IMAGE_H_MIRROR + {0x14 , 0x11}, + + 3: // IMAGE_V_MIRROR + {0x14 , 0x12}, + + 4: // IMAGE_HV_MIRROR + {0x14 , 0x13}, + */ + //-------------H_V_Select End--------------// + +}; + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0x00,0x00} +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0x0, 0x0}, +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + {0x17, 0x13}, + {0x18, 0x01}, + {0x32, 0xbf}, + {0x19, 0x03}, + {0x1a, 0x7b}, + {0x03, 0x0a}, + {0x00,0x00} +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0x00,0x00} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + {0x00,0x00} +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + {0x00,0x00} +}; +#endif +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x00, 0x00} +}; + + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x5a, 0x4c}, + {0x5b, 0x40}, + {0x5c, 0x4a}, + {0x22, 0x57}, + {0x00, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x22, 0x55}, // Disable AWB + {0x5a, 0x5a}, + {0x5b, 0x42}, + {0x5c, 0x40}, + {0x00, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x22, 0x55}, // Disable AWB + {0x5a, 0x50}, + {0x5b, 0x45}, + {0x5c, 0x40}, + {0x00, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x22, 0x55}, // Disable AWB + {0x5a, 0x48}, + {0x5b, 0x40}, + {0x5c, 0x5c}, + {0x00, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x22, 0x55}, // Disable AWB + {0x5a, 0x40}, + {0x5b, 0x42}, + {0x5c, 0x50}, + {0x00, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + {0xb5, 0xe0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + {0xb5, 0xf0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + {0xb5, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + {0xb5, 0x20}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + {0xb5, 0x30}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + {0xb5, 0x40}, + {0x00, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x23,0x00}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x38}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xd2}, + {0xbb,0x28}, + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x23,0x01}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x73,0x00}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x50}, + {0xbb,0xe0}, + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0x7f}, + {0xd2,0x90}, + {0x77,0x88}, + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xc0}, + {0xbb,0xc0}, + {0x00,0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + {0xd3, 0x30}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + {0xd3, 0x38}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + {0xd3, 0x40}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + {0xd3, 0x48}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + {0xd3, 0x50}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + {0xd3, 0x58}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + {0xd3, 0x60}, + {0x00, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + {0xb3,0x34}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + {0xb3,0x38}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + {0xb3,0x3d}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + {0xb3,0x40}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + {0xb3,0x44}, + {0x00, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + {0xb3,0x48}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + {0xb3,0x50}, + {0x00, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + {0xec, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_SceneNight[] = +{ + {0xec, 0x30}, + {0x00, 0x00} +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg & 0xFF; + buf[1] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + //u8 buf[2]; + u8 buf[1]; + struct i2c_msg msg[2]; + + //buf[0] = reg >> 8; + buf[0] = reg; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 1; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +#if 1 +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + + //for(i=0; i < sizeof(sensor_init_data) / 2;i++) + while((regarray[i].reg != 0) || (regarray[i].val != 0)) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + i++; + } + + return 0; +} +#else +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + u8 val_read; + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + err = sensor_read(client, regarray[i].reg, &val_read); + SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); + i++; + } + return 0; +} +#endif + +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int ret; + int i = 0; + + u8 value; + + SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); + for(i=0;ipowerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + int ret; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); */ //delay 5 microseconds + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + //u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } +#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION) + else if (((set_w <= SENSOR_MAX_WIDTH) && (set_h <= SENSOR_MAX_HEIGHT)) ) + { + winseqe_set_addr = sensor_vga; + set_w = SENSOR_MAX_WIDTH_REAL; + set_h = SENSOR_MAX_HEIGHT_REAL; + } +#endif + + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + /* ddl@rock-chips.com : It is query max resolution only. */ + if (mf->reserved[6] == 0xfefe5a5a) { + mf->height = SENSOR_MAX_HEIGHT; + mf->width = SENSOR_MAX_WIDTH; + ret = 0; + goto sensor_try_fmt_end; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } +#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION) + else if (((set_w <= SENSOR_MAX_WIDTH) && (set_h <= SENSOR_MAX_HEIGHT)) ) + { + set_w = SENSOR_MAX_WIDTH_REAL; + set_h = SENSOR_MAX_HEIGHT_REAL; + } +#endif + + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + + mf->colorspace = fmt->colorspace; +sensor_try_fmt_end: + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + { + *value = digitalzoom_total - digitalzoom_cur; + } + + if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + { + *value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += *value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char pid = 0; + int ret; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(50); *///delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &pid); + if (ret != 0) { + SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/gc0309.c b/drivers/media/video/gc0309.c index ddc21d9086f6..31da468af507 100755 --- a/drivers/media/video/gc0309.c +++ b/drivers/media/video/gc0309.c @@ -1,2862 +1,1079 @@ + +#include "generic_sensor.h" + /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GC0309 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309 -#define SENSOR_ID 0xa0 -#define SENSOR_MIN_WIDTH 176 -#define SENSOR_MIN_HEIGHT 144 -#define SENSOR_MAX_WIDTH 640 -#define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -struct reginfo -{ - u8 reg; - u8 val; -}; -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_GC0309_USER_DEFINED_SERIES -#include "gc0309_user_series.c" -#else -/* init SVGA preview */ -static struct reginfo sensor_init_data[] = -{ - /*init registers code.*/ -#if 1 - {0xfe,0x80}, // soft reset - - {0x1a,0x16}, - {0xd2,0x10}, // close AEC - {0x22,0x55}, // close AWB - - {0x5a,0x56}, - {0x5b,0x40}, - {0x5c,0x4a}, - - {0x22,0x57}, - - {0x01,0xfa}, - {0x02,0x70}, - {0x0f,0x01}, - - {0xe2,0x00}, - {0xe3,0x64}, - - {0x03,0x01}, - {0x04,0x2c}, - - {0x05,0x00}, - {0x06,0x00}, - {0x07,0x00}, - {0x08,0x00}, - {0x09,0x01}, - {0x0a,0xe8}, - {0x0b,0x02}, - {0x0c,0x88}, - {0x0d,0x02}, - {0x0e,0x02}, - {0x10,0x22}, - {0x11,0x0d}, - {0x12,0x2a}, - {0x13,0x00}, - {0x14,0x11}, - {0x15,0x0a}, - {0x16,0x05}, - {0x17,0x01}, - - {0x1b,0x03}, - {0x1c,0xc1}, - {0x1d,0x08}, - {0x1e,0x20}, - {0x1f,0x16}, - - {0x20,0xff}, - {0x21,0xf8}, - {0x24,0xa0}, - {0x25,0x0f}, - //output sync_mode - {0x26,0x03}, - {0x2f,0x01}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// grab_t //////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x30,0xf7}, - {0x31,0x40}, - {0x32,0x00}, - {0x39,0x04}, - {0x3a,0x20}, - {0x3b,0x20}, - {0x3c,0x02}, - {0x3d,0x02}, - {0x3e,0x02}, - {0x3f,0x02}, - - //gain - {0x50,0x24}, - - {0x53,0x82}, - {0x54,0x80}, - {0x55,0x80}, - {0x56,0x82}, - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// LSC_t //////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x8b,0x20}, - {0x8c,0x20}, - {0x8d,0x20}, - {0x8e,0x10}, - {0x8f,0x10}, - {0x90,0x10}, - {0x91,0x3c}, - {0x92,0x50}, - {0x5d,0x12}, - {0x5e,0x1a}, - {0x5f,0x24}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// DNDD_t /////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x60,0x07}, - {0x61,0x0e}, - {0x62,0x0c}, - {0x64,0x03}, - {0x66,0xe8}, - {0x67,0x86}, - {0x68,0xa2}, - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// asde_t /////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x69,0x20}, - {0x6a,0x0f}, - {0x6b,0x00}, - {0x6c,0x53}, - {0x6d,0x83}, - {0x6e,0xac}, - {0x6f,0xac}, - {0x70,0x15}, - {0x71,0x33}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// eeintp_t/////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x72,0xdc}, - {0x73,0x80}, - //for high resolution in light scene - {0x74,0x02}, - {0x75,0x3f}, - {0x76,0x02}, - {0x77,0x54}, - {0x78,0x88}, - {0x79,0x81}, - {0x7a,0x81}, - {0x7b,0x22}, - {0x7c,0xff}, - - - ///////////////////////////////////////////////////////////////////// - ///////////////////////////CC_t/////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x93,0x45}, - {0x94,0x00}, - {0x95,0x00}, - {0x96,0x00}, - {0x97,0x45}, - {0x98,0xf0}, - {0x9c,0x00}, - {0x9d,0x03}, - {0x9e,0x00}, - - - - ///////////////////////////////////////////////////////////////////// - ///////////////////////////YCP_t/////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0xb1,0x40}, - {0xb2,0x40}, - {0xb8,0x20}, - {0xbe,0x36}, - {0xbf,0x00}, - ///////////////////////////////////////////////////////////////////// - ///////////////////////////AEC_t/////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0xd0,0xc9}, - {0xd1,0x10}, -// {0xd2,0x90}, - {0xd3,0x80}, - {0xd5,0xf2}, - {0xd6,0x16}, - {0xdb,0x92}, - {0xdc,0xa5}, - {0xdf,0x23}, - {0xd9,0x00}, - {0xda,0x00}, - {0xe0,0x09}, - - {0xec,0x20}, - {0xed,0x04}, - {0xee,0xa0}, - {0xef,0x40}, - - //Y_gamma - {0xc0,0x00}, - {0xc1,0x0B}, - {0xc2,0x15}, - {0xc3,0x27}, - {0xc4,0x39}, - {0xc5,0x49}, - {0xc6,0x5A}, - {0xc7,0x6A}, - {0xc8,0x89}, - {0xc9,0xA8}, - {0xca,0xC6}, - {0xcb,0xE3}, - {0xcc,0xFF}, - - ///////////////////////////////////////////////////////////////// - /////////////////////////// ABS_t /////////////////////////////// - ///////////////////////////////////////////////////////////////// - {0xf0,0x02}, - {0xf1,0x01}, - {0xf2,0x00}, - {0xf3,0x30}, - - ///////////////////////////////////////////////////////////////// - /////////////////////////// Measure Window /////////////////////// - ///////////////////////////////////////////////////////////////// - {0xf7,0x04}, - {0xf8,0x02}, - {0xf9,0x9f}, - {0xfa,0x78}, - -#else - {0xfe,0x80}, // soft reset - - {0x1a,0x16}, - {0xd2,0x10}, // close AEC - {0x22,0x55}, // close AWB - - {0x5a,0x56}, - {0x5b,0x40}, - {0x5c,0x4a}, - - {0x22,0x57}, - - {0x01,0xfa}, - {0x02,0x70}, - {0x0f,0x01}, - - {0xe2,0x00}, - {0xe3,0x64}, - - {0x03,0x01}, - {0x04,0x2c}, - - - {0x05,0x00}, - {0x06,0x00}, - {0x07,0x00}, - {0x08,0x00}, - {0x09,0x01}, - {0x0a,0xe8}, - {0x0b,0x02}, - {0x0c,0x88}, - {0x0d,0x02}, - {0x0e,0x02}, - {0x10,0x22}, - {0x11,0x0d}, - {0x12,0x2a}, - {0x13,0x00}, - - {0x15,0x0a}, - {0x16,0x05}, - {0x17,0x01}, - - {0x1b,0x03}, - {0x1c,0xc1}, - {0x1d,0x08}, - {0x1e,0x20}, - {0x1f,0x16}, - - {0x20,0xff}, - {0x21,0xf8}, - {0x24,0xa2}, - {0x25,0x0f}, - //output sync_mode - {0x26,0x03}, - {0x2f,0x01}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// grab_t //////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x30,0xf7}, - {0x31,0x40}, - {0x32,0x00}, - {0x39,0x04}, - {0x3a,0x20}, - {0x3b,0x20}, - {0x3c,0x02}, - {0x3d,0x02}, - {0x3e,0x02}, - {0x3f,0x02}, - - //gain - {0x50,0x24}, - - {0x53,0x82}, - {0x54,0x80}, - {0x55,0x80}, - {0x56,0x82}, - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// LSC_t //////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x8b,0x20}, - {0x8c,0x20}, - {0x8d,0x20}, - {0x8e,0x10}, - {0x8f,0x10}, - {0x90,0x10}, - {0x91,0x3c}, - {0x92,0x50}, - {0x5d,0x12}, - {0x5e,0x1a}, - {0x5f,0x24}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// DNDD_t /////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x60,0x07}, - {0x61,0x0e}, - {0x62,0x0c}, - {0x64,0x03}, - {0x66,0xe8}, - {0x67,0x86}, - {0x68,0xa2}, - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// asde_t /////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x69,0x20}, - {0x6a,0x0f}, - {0x6b,0x00}, - {0x6c,0x53}, - {0x6d,0x83}, - {0x6e,0xac}, - {0x6f,0xac}, - {0x70,0x15}, - {0x71,0x33}, - ///////////////////////////////////////////////////////////////////// - /////////////////////////// eeintp_t/////////////////////////////// -#endif - {0x23,0x00}, - {0x2d,0x0a}, // 0x08 - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - {0x77,0x54}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00,0x00} -}; - - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - //{0x45 , 0x0f}, //output enable - {0x15 , 0x0a}, //output enable - {0x0,0x0} -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{}; -#endif - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0x24,0xa2}, - {0x00, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x24,0xa0}, - {0x00, 0x00} -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x5a,0x56}, //for AWB can adjust back - {0x5b,0x40}, - {0x5c,0x4a}, - {0x22,0x57}, // Enable AWB - {0x00, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x22,0x55}, // Disable AWB - {0x5a,0x8c}, //WB_manual_gain - {0x5b,0x50}, - {0x5c,0x40}, - {0x00, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x22,0x55}, - {0x5a,0x74}, - {0x5b,0x52}, - {0x5c,0x40}, - {0x00, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_Incandescent[]= -{ - //Incandescent - {0x22,0x55}, - {0x5a,0x48}, - {0x5b,0x40}, - {0x5c,0x5c}, - {0x00, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_Fluorescent[]= -{ - //fluorescent - {0x22,0x55}, - {0x5a,0x40}, - {0x5b,0x42}, - {0x5c,0x50}, - {0x00, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_Incandescent,sensor_WhiteB_Fluorescent, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - - {0x00, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x23,0x00}, - {0x2d,0x0a}, // 0x08 - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - {0x77,0x54}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0xbf}, - {0xd2,0x10}, - {0x73,0x01}, - - {0x51,0x40}, - {0x52,0x40}, - {0xb3,0x60}, - {0xb4,0x40}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0xd0}, - {0xbb,0x28}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x23,0x03}, - {0x2d,0x0a}, - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00, 0x00} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x50}, - {0xbb,0xe0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0xff}, - {0xd2,0x90}, - {0x77,0x88}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0xc0}, - {0xbb,0xc0}, - {0x00, 0x00} -}; - - -static struct reginfo sensor_Effect_Grayscale[]= -{ - {0x23,0x02}, - {0x2d,0x0a}, - {0x20,0xff}, - {0xd2,0x90}, - {0x73,0x00}, - - {0xb3,0x40}, - {0xb4,0x80}, - {0xba,0x00}, - {0xbb,0x00}, - {0x00, 0x00} -}; - -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Grayscale,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - //-3 - -}; - -static struct reginfo sensor_Exposure1[]= -{ - //-2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - //-0.3EV - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - //default - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - // 1 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - // 2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - // 3 - - {0x00, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - - {0x00, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - //Contrast -3 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - //Contrast -2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - // Contrast -1 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - //Contrast 0 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - //Contrast +1 - - {0x00, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - //Contrast +2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - //Contrast +3 - - {0x00, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - - {0x00, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - - {0x00, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ -#if 0 /* ddl@rock-chips.com : */ - {0x3014, 0x04}, - {0x3015, 0x00}, - {0x302e, 0x00}, - {0x302d, 0x00}, - {0x00, 0x00} -#else - {0xec ,0x20}, - {0x20 ,0x7f}, // close cc - {0x3c ,0x02}, - {0x3d ,0x02}, - {0x3e ,0x02}, - {0x3f ,0x02}, - {0x00, 0x00} -#endif -}; - -static struct reginfo sensor_SceneNight[] = -{ -#if 1 - //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk - {0xec ,0x30}, - {0x20 ,0x5f}, // close cc - {0x3c ,0x08}, - {0x3d ,0x08}, - {0x3e ,0x08}, - {0x3f ,0x08}, - {0x00, 0x00} -#else - //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk - {0x300e, 0x34}, - {0x3011, 0x01}, - {0x302c, 0x00}, - {0x3071, 0x00}, - {0x3070, 0x5d}, - {0x301c, 0x05}, - {0x3073, 0x00}, - {0x3072, 0x4d}, - {0x301d, 0x07}, - {0x3014, 0x0c}, - {0x3015, 0x50}, - {0x302e, 0x00}, - {0x302d, 0x00}, -#endif -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 6, .name = "grayscale", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -#if 0 -/* sensor register */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int ret = 0; - - ret = i2c_master_reg8_recv(client, reg, val, 1, CONFIG_SENSOR_I2C_SPEED); - - return (ret > 0)? 0 : ret; -} - -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int ret = 0; - - ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED); - - return (ret > 0)? 0 : ret; -} -#else -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg; - buf[1] = val; - - if (reg == 0xfe) - mdelay(10); - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - u8 buf[1]; - struct i2c_msg msg[2]; - - buf[0] = reg ; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -#endif - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - int j = 0; - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - //mdelay(5); - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; -} -#endif -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - ret = sensor_write(client, 0xfe, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); //delay 5 microseconds - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - if (value == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - //sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } else { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - ret = sensor_write(client, 0xfe, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - if (value == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - SENSOR_TR("chip id:0x%x\n",value); - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GC0309 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309 +#define SENSOR_ID 0xa0 +#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 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + /*init registers code.*/ +#if 1 + {0xfe,0x80}, // soft reset + {0x1a,0x16}, + {0xd2,0x10}, // close AEC + {0x22,0x55}, // close AWB + + {0x5a,0x56}, + {0x5b,0x40}, + {0x5c,0x4a}, + + {0x22,0x57}, + + {0x01,0xfa}, + {0x02,0x70}, + {0x0f,0x01}, + + {0xe2,0x00}, + {0xe3,0x64}, + + {0x03,0x01}, + {0x04,0x2c}, + + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x01}, + {0x0a,0xe8}, + {0x0b,0x02}, + {0x0c,0x88}, + {0x0d,0x02}, + {0x0e,0x02}, + {0x10,0x22}, + {0x11,0x0d}, + {0x12,0x2a}, + {0x13,0x00}, + {0x14,0x13}, + {0x15,0x0a}, + {0x16,0x05}, + {0x17,0x01}, + + {0x1b,0x03}, + {0x1c,0xc1}, + {0x1d,0x08}, + {0x1e,0x20}, + {0x1f,0x16}, + + {0x20,0xff}, + {0x21,0xf8}, + {0x24,0xa2}, + {0x25,0x0f}, + //output sync_mode + {0x26,0x03}, + {0x2f,0x01}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// grab_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x30,0xf7}, + {0x31,0x40}, + {0x32,0x00}, + {0x39,0x04}, + {0x3a,0x20}, + {0x3b,0x20}, + {0x3c,0x02}, + {0x3d,0x02}, + {0x3e,0x02}, + {0x3f,0x02}, + + //gain + {0x50,0x24}, + + {0x53,0x82}, + {0x54,0x80}, + {0x55,0x80}, + {0x56,0x82}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// LSC_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x8b,0x20}, + {0x8c,0x20}, + {0x8d,0x20}, + {0x8e,0x10}, + {0x8f,0x10}, + {0x90,0x10}, + {0x91,0x3c}, + {0x92,0x50}, + {0x5d,0x12}, + {0x5e,0x1a}, + {0x5f,0x24}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x60,0x07}, + {0x61,0x0e}, + {0x62,0x0c}, + {0x64,0x03}, + {0x66,0xe8}, + {0x67,0x86}, + {0x68,0xa2}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// asde_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x69,0x20}, + {0x6a,0x0f}, + {0x6b,0x00}, + {0x6c,0x53}, + {0x6d,0x83}, + {0x6e,0xac}, + {0x6f,0xac}, + {0x70,0x15}, + {0x71,0x33}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// eeintp_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x72,0xdc}, + {0x73,0x80}, + //for high resolution in light scene + {0x74,0x02}, + {0x75,0x3f}, + {0x76,0x02}, + {0x77,0x54}, + {0x78,0x88}, + {0x79,0x81}, + {0x7a,0x81}, + {0x7b,0x22}, + {0x7c,0xff}, + + + ///////////////////////////////////////////////////////////////////// + ///////////////////////////CC_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x93,0x45}, + {0x94,0x00}, + {0x95,0x00}, + {0x96,0x00}, + {0x97,0x45}, + {0x98,0xf0}, + {0x9c,0x00}, + {0x9d,0x03}, + {0x9e,0x00}, + + + + ///////////////////////////////////////////////////////////////////// + ///////////////////////////YCP_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xb1,0x40}, + {0xb2,0x40}, + {0xb8,0x20}, + {0xbe,0x36}, + {0xbf,0x00}, + ///////////////////////////////////////////////////////////////////// + ///////////////////////////AEC_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xd0,0xc9}, + {0xd1,0x10}, + // {0xd2,0x90}, + {0xd3,0x80}, + {0xd5,0xf2}, + {0xd6,0x16}, + {0xdb,0x92}, + {0xdc,0xa5}, + {0xdf,0x23}, + {0xd9,0x00}, + {0xda,0x00}, + {0xe0,0x09}, + + {0xec,0x20}, + {0xed,0x04}, + {0xee,0xa0}, + {0xef,0x40}, + + //Y_gamma + {0xc0,0x00}, + {0xc1,0x0B}, + {0xc2,0x15}, + {0xc3,0x27}, + {0xc4,0x39}, + {0xc5,0x49}, + {0xc6,0x5A}, + {0xc7,0x6A}, + {0xc8,0x89}, + {0xc9,0xA8}, + {0xca,0xC6}, + {0xcb,0xE3}, + {0xcc,0xFF}, + + ///////////////////////////////////////////////////////////////// + /////////////////////////// ABS_t /////////////////////////////// + ///////////////////////////////////////////////////////////////// + {0xf0,0x02}, + {0xf1,0x01}, + {0xf2,0x00}, + {0xf3,0x30}, + + ///////////////////////////////////////////////////////////////// + /////////////////////////// Measure Window /////////////////////// + ///////////////////////////////////////////////////////////////// + {0xf7,0x04}, + {0xf8,0x02}, + {0xf9,0x9f}, + {0xfa,0x78}, + +#else + {0xfe,0x80}, // soft reset + + {0x1a,0x16}, + {0xd2,0x10}, // close AEC + {0x22,0x55}, // close AWB + + {0x5a,0x56}, + {0x5b,0x40}, + {0x5c,0x4a}, + + {0x22,0x57}, + + {0x01,0xfa}, + {0x02,0x70}, + {0x0f,0x01}, + + {0xe2,0x00}, + {0xe3,0x64}, + + {0x03,0x01}, + {0x04,0x2c}, + + + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x01}, + {0x0a,0xe8}, + {0x0b,0x02}, + {0x0c,0x88}, + {0x0d,0x02}, + {0x0e,0x02}, + {0x10,0x22}, + {0x11,0x0d}, + {0x12,0x2a}, + {0x13,0x00}, + + {0x15,0x0a}, + {0x16,0x05}, + {0x17,0x01}, + + {0x1b,0x03}, + {0x1c,0xc1}, + {0x1d,0x08}, + {0x1e,0x20}, + {0x1f,0x16}, + + {0x20,0xff}, + {0x21,0xf8}, + {0x24,0xa2}, + {0x25,0x0f}, + //output sync_mode + {0x26,0x03}, + {0x2f,0x01}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// grab_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x30,0xf7}, + {0x31,0x40}, + {0x32,0x00}, + {0x39,0x04}, + {0x3a,0x20}, + {0x3b,0x20}, + {0x3c,0x02}, + {0x3d,0x02}, + {0x3e,0x02}, + {0x3f,0x02}, + + //gain + {0x50,0x24}, + + {0x53,0x82}, + {0x54,0x80}, + {0x55,0x80}, + {0x56,0x82}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// LSC_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x8b,0x20}, + {0x8c,0x20}, + {0x8d,0x20}, + {0x8e,0x10}, + {0x8f,0x10}, + {0x90,0x10}, + {0x91,0x3c}, + {0x92,0x50}, + {0x5d,0x12}, + {0x5e,0x1a}, + {0x5f,0x24}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x60,0x07}, + {0x61,0x0e}, + {0x62,0x0c}, + {0x64,0x03}, + {0x66,0xe8}, + {0x67,0x86}, + {0x68,0xa2}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// asde_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x69,0x20}, + {0x6a,0x0f}, + {0x6b,0x00}, + {0x6c,0x53}, + {0x6d,0x83}, + {0x6e,0xac}, + {0x6f,0xac}, + {0x70,0x15}, + {0x71,0x33}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// eeintp_t/////////////////////////////// +#endif + {0x23,0x00}, + {0x2d,0x0a}, // 0x08 + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x54}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + 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[] = +{ + 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[]={ + SensorRegVal(0xfe,80), + SensorWaitMs(5), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x00,0), + 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[]= +{ + {0x5a,0x56}, //for AWB can adjust back + {0x5b,0x40}, + {0x5c,0x4a}, + {0x22,0x57}, // Enable AWB + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x22,0x55}, // Disable AWB + {0x5a,0x8c}, //WB_manual_gain + {0x5b,0x50}, + {0x5c,0x40}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x22,0x55}, + {0x5a,0x74}, + {0x5b,0x52}, + {0x5c,0x40}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Incandescent + {0x22,0x55}, + {0x5a,0x48}, + {0x5b,0x40}, + {0x5c,0x5c}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //fluorescent + {0x22,0x55}, + {0x5a,0x40}, + {0x5b,0x42}, + {0x5c,0x50}, + 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[] = +{ + {0x23,0x00}, + {0x2d,0x0a}, // 0x08 + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x54}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xbf}, + {0xd2,0x10}, + {0x73,0x01}, + + {0x51,0x40}, + {0x52,0x40}, + {0xb3,0x60}, + {0xb4,0x40}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xd0}, + {0xbb,0x28}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x23,0x03}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + //Bluish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x50}, + {0xbb,0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + //Greenish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x77,0x88}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xc0}, + {0xbb,0xc0}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Grayscale[]= +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + +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[]= +{ + //-3 + {0xb5, 0xe8}, + {0xd3, 0x38}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + //-2 + {0xb5, 0xf0}, + {0xd3, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + //-1 + {0xb5, 0xf8}, + {0xd3, 0x48}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + //default + {0xb5, 0x00}, + {0xd3, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + // 1 + {0xb5, 0x08}, + {0xd3, 0x58}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + // 2 + {0xb5, 0x10}, + {0xd3, 0x60}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + // 3 + {0xb5, 0x18}, + {0xd3, 0x68}, + 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[] = +{ + {0xec, 0x20}, + {0x20, 0x7f}, // close cc + {0x3c, 0x02}, + {0x3d, 0x02}, + {0x3e, 0x02}, + {0x3f, 0x02}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + {0xec, 0x30}, + {0x20, 0x5f}, // close cc + {0x3c, 0x08}, + {0x3d, 0x08}, + {0x3e, 0x08}, + {0x3f, 0x08}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x14, &val); + if (err == 0) { + if((val & 0x1) == 0) + err = sensor_write(client, 0x14, (val |0x1)); + else + err = sensor_write(client, 0x14, (val & 0xfe)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + SENSOR_DG("flip: %d",flip); + if (flip) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x14, &val); + if (err == 0) { + if((val & 0x2) == 0) + err = sensor_write(client, 0x14, (val |0x2)); + else + err = sensor_write(client, 0x14, (val & 0xfc)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gc0309_old.c b/drivers/media/video/gc0309_old.c new file mode 100755 index 000000000000..ddc21d9086f6 --- /dev/null +++ b/drivers/media/video/gc0309_old.c @@ -0,0 +1,2862 @@ +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC0309 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309 +#define SENSOR_ID 0xa0 +#define SENSOR_MIN_WIDTH 176 +#define SENSOR_MIN_HEIGHT 144 +#define SENSOR_MAX_WIDTH 640 +#define SENSOR_MAX_HEIGHT 480 +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u8 reg; + u8 val; +}; +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_GC0309_USER_DEFINED_SERIES +#include "gc0309_user_series.c" +#else +/* init SVGA preview */ +static struct reginfo sensor_init_data[] = +{ + /*init registers code.*/ +#if 1 + {0xfe,0x80}, // soft reset + + {0x1a,0x16}, + {0xd2,0x10}, // close AEC + {0x22,0x55}, // close AWB + + {0x5a,0x56}, + {0x5b,0x40}, + {0x5c,0x4a}, + + {0x22,0x57}, + + {0x01,0xfa}, + {0x02,0x70}, + {0x0f,0x01}, + + {0xe2,0x00}, + {0xe3,0x64}, + + {0x03,0x01}, + {0x04,0x2c}, + + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x01}, + {0x0a,0xe8}, + {0x0b,0x02}, + {0x0c,0x88}, + {0x0d,0x02}, + {0x0e,0x02}, + {0x10,0x22}, + {0x11,0x0d}, + {0x12,0x2a}, + {0x13,0x00}, + {0x14,0x11}, + {0x15,0x0a}, + {0x16,0x05}, + {0x17,0x01}, + + {0x1b,0x03}, + {0x1c,0xc1}, + {0x1d,0x08}, + {0x1e,0x20}, + {0x1f,0x16}, + + {0x20,0xff}, + {0x21,0xf8}, + {0x24,0xa0}, + {0x25,0x0f}, + //output sync_mode + {0x26,0x03}, + {0x2f,0x01}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// grab_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x30,0xf7}, + {0x31,0x40}, + {0x32,0x00}, + {0x39,0x04}, + {0x3a,0x20}, + {0x3b,0x20}, + {0x3c,0x02}, + {0x3d,0x02}, + {0x3e,0x02}, + {0x3f,0x02}, + + //gain + {0x50,0x24}, + + {0x53,0x82}, + {0x54,0x80}, + {0x55,0x80}, + {0x56,0x82}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// LSC_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x8b,0x20}, + {0x8c,0x20}, + {0x8d,0x20}, + {0x8e,0x10}, + {0x8f,0x10}, + {0x90,0x10}, + {0x91,0x3c}, + {0x92,0x50}, + {0x5d,0x12}, + {0x5e,0x1a}, + {0x5f,0x24}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x60,0x07}, + {0x61,0x0e}, + {0x62,0x0c}, + {0x64,0x03}, + {0x66,0xe8}, + {0x67,0x86}, + {0x68,0xa2}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// asde_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x69,0x20}, + {0x6a,0x0f}, + {0x6b,0x00}, + {0x6c,0x53}, + {0x6d,0x83}, + {0x6e,0xac}, + {0x6f,0xac}, + {0x70,0x15}, + {0x71,0x33}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// eeintp_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x72,0xdc}, + {0x73,0x80}, + //for high resolution in light scene + {0x74,0x02}, + {0x75,0x3f}, + {0x76,0x02}, + {0x77,0x54}, + {0x78,0x88}, + {0x79,0x81}, + {0x7a,0x81}, + {0x7b,0x22}, + {0x7c,0xff}, + + + ///////////////////////////////////////////////////////////////////// + ///////////////////////////CC_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x93,0x45}, + {0x94,0x00}, + {0x95,0x00}, + {0x96,0x00}, + {0x97,0x45}, + {0x98,0xf0}, + {0x9c,0x00}, + {0x9d,0x03}, + {0x9e,0x00}, + + + + ///////////////////////////////////////////////////////////////////// + ///////////////////////////YCP_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xb1,0x40}, + {0xb2,0x40}, + {0xb8,0x20}, + {0xbe,0x36}, + {0xbf,0x00}, + ///////////////////////////////////////////////////////////////////// + ///////////////////////////AEC_t/////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xd0,0xc9}, + {0xd1,0x10}, +// {0xd2,0x90}, + {0xd3,0x80}, + {0xd5,0xf2}, + {0xd6,0x16}, + {0xdb,0x92}, + {0xdc,0xa5}, + {0xdf,0x23}, + {0xd9,0x00}, + {0xda,0x00}, + {0xe0,0x09}, + + {0xec,0x20}, + {0xed,0x04}, + {0xee,0xa0}, + {0xef,0x40}, + + //Y_gamma + {0xc0,0x00}, + {0xc1,0x0B}, + {0xc2,0x15}, + {0xc3,0x27}, + {0xc4,0x39}, + {0xc5,0x49}, + {0xc6,0x5A}, + {0xc7,0x6A}, + {0xc8,0x89}, + {0xc9,0xA8}, + {0xca,0xC6}, + {0xcb,0xE3}, + {0xcc,0xFF}, + + ///////////////////////////////////////////////////////////////// + /////////////////////////// ABS_t /////////////////////////////// + ///////////////////////////////////////////////////////////////// + {0xf0,0x02}, + {0xf1,0x01}, + {0xf2,0x00}, + {0xf3,0x30}, + + ///////////////////////////////////////////////////////////////// + /////////////////////////// Measure Window /////////////////////// + ///////////////////////////////////////////////////////////////// + {0xf7,0x04}, + {0xf8,0x02}, + {0xf9,0x9f}, + {0xfa,0x78}, + +#else + {0xfe,0x80}, // soft reset + + {0x1a,0x16}, + {0xd2,0x10}, // close AEC + {0x22,0x55}, // close AWB + + {0x5a,0x56}, + {0x5b,0x40}, + {0x5c,0x4a}, + + {0x22,0x57}, + + {0x01,0xfa}, + {0x02,0x70}, + {0x0f,0x01}, + + {0xe2,0x00}, + {0xe3,0x64}, + + {0x03,0x01}, + {0x04,0x2c}, + + + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x01}, + {0x0a,0xe8}, + {0x0b,0x02}, + {0x0c,0x88}, + {0x0d,0x02}, + {0x0e,0x02}, + {0x10,0x22}, + {0x11,0x0d}, + {0x12,0x2a}, + {0x13,0x00}, + + {0x15,0x0a}, + {0x16,0x05}, + {0x17,0x01}, + + {0x1b,0x03}, + {0x1c,0xc1}, + {0x1d,0x08}, + {0x1e,0x20}, + {0x1f,0x16}, + + {0x20,0xff}, + {0x21,0xf8}, + {0x24,0xa2}, + {0x25,0x0f}, + //output sync_mode + {0x26,0x03}, + {0x2f,0x01}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// grab_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x30,0xf7}, + {0x31,0x40}, + {0x32,0x00}, + {0x39,0x04}, + {0x3a,0x20}, + {0x3b,0x20}, + {0x3c,0x02}, + {0x3d,0x02}, + {0x3e,0x02}, + {0x3f,0x02}, + + //gain + {0x50,0x24}, + + {0x53,0x82}, + {0x54,0x80}, + {0x55,0x80}, + {0x56,0x82}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// LSC_t //////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x8b,0x20}, + {0x8c,0x20}, + {0x8d,0x20}, + {0x8e,0x10}, + {0x8f,0x10}, + {0x90,0x10}, + {0x91,0x3c}, + {0x92,0x50}, + {0x5d,0x12}, + {0x5e,0x1a}, + {0x5f,0x24}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x60,0x07}, + {0x61,0x0e}, + {0x62,0x0c}, + {0x64,0x03}, + {0x66,0xe8}, + {0x67,0x86}, + {0x68,0xa2}, + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// asde_t /////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x69,0x20}, + {0x6a,0x0f}, + {0x6b,0x00}, + {0x6c,0x53}, + {0x6d,0x83}, + {0x6e,0xac}, + {0x6f,0xac}, + {0x70,0x15}, + {0x71,0x33}, + ///////////////////////////////////////////////////////////////////// + /////////////////////////// eeintp_t/////////////////////////////// +#endif + {0x23,0x00}, + {0x2d,0x0a}, // 0x08 + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x54}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + //{0x45 , 0x0f}, //output enable + {0x15 , 0x0a}, //output enable + {0x0,0x0} +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{}; +#endif + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0x24,0xa2}, + {0x00, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x24,0xa0}, + {0x00, 0x00} +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x5a,0x56}, //for AWB can adjust back + {0x5b,0x40}, + {0x5c,0x4a}, + {0x22,0x57}, // Enable AWB + {0x00, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x22,0x55}, // Disable AWB + {0x5a,0x8c}, //WB_manual_gain + {0x5b,0x50}, + {0x5c,0x40}, + {0x00, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x22,0x55}, + {0x5a,0x74}, + {0x5b,0x52}, + {0x5c,0x40}, + {0x00, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_Incandescent[]= +{ + //Incandescent + {0x22,0x55}, + {0x5a,0x48}, + {0x5b,0x40}, + {0x5c,0x5c}, + {0x00, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_Fluorescent[]= +{ + //fluorescent + {0x22,0x55}, + {0x5a,0x40}, + {0x5b,0x42}, + {0x5c,0x50}, + {0x00, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_Incandescent,sensor_WhiteB_Fluorescent, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + + {0x00, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x23,0x00}, + {0x2d,0x0a}, // 0x08 + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + {0x77,0x54}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xbf}, + {0xd2,0x10}, + {0x73,0x01}, + + {0x51,0x40}, + {0x52,0x40}, + {0xb3,0x60}, + {0xb4,0x40}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xd0}, + {0xbb,0x28}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x23,0x03}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00, 0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x50}, + {0xbb,0xe0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x77,0x88}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0xc0}, + {0xbb,0xc0}, + {0x00, 0x00} +}; + + +static struct reginfo sensor_Effect_Grayscale[]= +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00, 0x00} +}; + +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Grayscale,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + //-3 + +}; + +static struct reginfo sensor_Exposure1[]= +{ + //-2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + //-0.3EV + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + //default + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + // 1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + // 2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + // 3 + + {0x00, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + + {0x00, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + //Contrast -3 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + //Contrast -2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + // Contrast -1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + //Contrast 0 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + //Contrast +1 + + {0x00, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + //Contrast +2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + //Contrast +3 + + {0x00, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + + {0x00, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + + {0x00, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ +#if 0 /* ddl@rock-chips.com : */ + {0x3014, 0x04}, + {0x3015, 0x00}, + {0x302e, 0x00}, + {0x302d, 0x00}, + {0x00, 0x00} +#else + {0xec ,0x20}, + {0x20 ,0x7f}, // close cc + {0x3c ,0x02}, + {0x3d ,0x02}, + {0x3e ,0x02}, + {0x3f ,0x02}, + {0x00, 0x00} +#endif +}; + +static struct reginfo sensor_SceneNight[] = +{ +#if 1 + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + {0xec ,0x30}, + {0x20 ,0x5f}, // close cc + {0x3c ,0x08}, + {0x3d ,0x08}, + {0x3e ,0x08}, + {0x3f ,0x08}, + {0x00, 0x00} +#else + //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk + {0x300e, 0x34}, + {0x3011, 0x01}, + {0x302c, 0x00}, + {0x3071, 0x00}, + {0x3070, 0x5d}, + {0x301c, 0x05}, + {0x3073, 0x00}, + {0x3072, 0x4d}, + {0x301d, 0x07}, + {0x3014, 0x0c}, + {0x3015, 0x50}, + {0x302e, 0x00}, + {0x302d, 0x00}, +#endif +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 6, .name = "grayscale", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +#if 0 +/* sensor register */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret = 0; + + ret = i2c_master_reg8_recv(client, reg, val, 1, CONFIG_SENSOR_I2C_SPEED); + + return (ret > 0)? 0 : ret; +} + +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int ret = 0; + + ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED); + + return (ret > 0)? 0 : ret; +} +#else +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg; + buf[1] = val; + + if (reg == 0xfe) + mdelay(10); + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + u8 buf[1]; + struct i2c_msg msg[2]; + + buf[0] = reg ; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +#endif + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + int j = 0; + char valchk; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + //mdelay(5); + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != 0) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + ret = sensor_write(client, 0xfe, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); //delay 5 microseconds + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + if (value == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + //sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } else { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + ret = sensor_write(client, 0xfe, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(5); //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + if (value == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + SENSOR_TR("chip id:0x%x\n",value); + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + + diff --git a/drivers/media/video/gc0328.c b/drivers/media/video/gc0328.c new file mode 100755 index 000000000000..7e9ed478de32 --- /dev/null +++ b/drivers/media/video/gc0328.c @@ -0,0 +1,994 @@ + +#include "generic_sensor.h" + + +static int debug =1; +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_SENSOR_GC0328 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0328 +#define SENSOR_ID 0x9d +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +/* 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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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; +*/ +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] ={ + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfc , 0x16}, //clock enable + {0xfc , 0x16}, //clock enable + {0xfc , 0x16}, //clock enable + {0xfc , 0x16}, //clock enable + + {0x42 , 0x02}, + + {0xfe , 0x01}, + {0x4c , 0x01}, //AWB Buffer reset + {0xfe , 0x00}, + + {0xfe , 0x00}, + {0x0d , 0x01}, //{8}cis_win_height 486 1e6 + {0x0e , 0xe8}, //{7:0}cis_win_height + {0x0f , 0x02}, //{9:8}cis_win_width 646 286 + {0x10 , 0x88}, //{7:0}cis_win_width + {0x09 , 0x00}, //row_start + {0x0a , 0x00}, + {0x0b , 0x00}, //col_start + {0x0c , 0x00}, + {0x16 , 0x80}, + {0x17 , 0x14}, //[7]hsync_always, [6]close_2_frame_dbrow, [5:4]CFA_seqence, [3:2]dark_CFA_seqence, [1]updown, [0]mirror + {0x19 , 0x06}, //AD Pipe line number + {0x1f , 0xC8}, //txlow + {0x20 , 0x01}, + {0x21 , 0x78}, //68 + {0x22 , 0xb0}, + {0x24 , 0x16}, + {0x26 , 0x01}, + + {0x50 , 0x01}, //crop mode + + //global gain for range + {0x70 , 0x45}, + + //////////////////////////////////////////////// + //////////// BLK ////////////////////// + //////////////////////////////////////////////// + {0x27 , 0x27}, + {0x28 , 0x7F}, //BLK LIMIT + {0x29 , 0x20}, //global offset + {0x33 , 0x1A},//offset_ratio_G1 + {0x34 , 0x1A}, //offset_ratio_R + {0x35 , 0x1A}, + {0x36 , 0x1A}, + {0x37 , 0x20}, + {0x38 , 0x20}, + {0x39 , 0x20}, + {0x3a , 0x20}, + {0x47 , 0x00}, + {0x48 , 0x75},//00 + + + + //////////////////////////////////////////////// + //////////// block enable ///////////// + //////////////////////////////////////////////// + {0x40 , 0x7f}, // + {0x41 , 0x22},// + + + {0x42 , 0xff},// + {0x45 , 0x00}, + {0x44 , 0x02}, + {0x46 , 0x02}, + {0x4b , 0x01}, + {0x50 , 0x01}, //crop mode + + //DN & EEINTP + {0x7e , 0x0a}, // + {0x7f , 0x03}, //c3 //1D DN + {0x81 , 0x15}, + {0x82 , 0x85}, //8f//bilt_base_b + {0x83 , 0x02}, //02 //DN C weight + {0x84 , 0xe5}, + {0x90 , 0xac}, + {0x92 , 0x02}, //5 + {0x94 , 0x05}, + {0x95 , 0x63}, + + + ///////YCP + {0xd1 , 0x38}, + {0xd2 , 0x38}, // cb,cr saturation + {0xdd , 0x54}, + {0xde , 0x38}, //autogray_mode + {0xe4 , 0x88}, + {0xe5 , 0x40}, + {0xd7 , 0x0e}, + //rgb gamma + {0xBF , 0x0E}, + {0xc0 , 0x1C}, + {0xc1 , 0x34}, + {0xc2 , 0x48}, + {0xc3 , 0x5A}, + {0xc4 , 0x6B}, + {0xc5 , 0x7B}, + {0xc6 , 0x95}, + {0xc7 , 0xAB}, + {0xc8 , 0xBF}, + {0xc9 , 0xCE}, + {0xcA , 0xD9}, + {0xcB , 0xE4}, + {0xcC , 0xEC}, + {0xcD , 0xF7}, + {0xcE , 0xFD}, + {0xcF , 0xFF}, + + ///Y gamma + {0xfe , 0x00}, + {0x63 , 0x00}, + {0x64 , 0x05}, + {0x65 , 0x0b}, + {0x66 , 0x19}, + {0x67 , 0x2e}, + {0x68 , 0x40}, + {0x69 , 0x54}, + {0x6a , 0x66}, + {0x6b , 0x86}, + {0x6c , 0xa7}, + {0x6d , 0xc6}, + {0x6e , 0xe4}, + {0x6f , 0xff}, + + //ASDE + {0xfe , 0x01}, + {0x18 , 0x02}, + {0xfe , 0x00}, + {0x97 , 0x30}, //Y offset TH + {0xa4 , 0x10}, //ASDE auto sa slope + {0xa8 , 0x80}, //ASDE LSC SLOPE + {0x9c , 0x60}, //auto Y offset Slope + {0xa2 , 0x23}, + {0xad , 0x01}, //ASDE ee,ddMODE + {0x9c , 0x01}, //ABS manual K + + {0xfe , 0x01}, + {0x9c , 0x00}, //ABS manual K + {0x08 , 0xa0}, + {0x09 , 0xe8}, + + {0x10 , 0x08},//[7]win_mode,[6]show_mode [3]measure_point + + {0x11 , 0x21}, //[7]fix target + {0x12 , 0x10}, + {0x13 , 0x45}, //AEC Y target + {0x15 , 0xfc}, //high range for count + {0x21 , 0xf0}, //c0 //post_gain limit + {0x22 , 0x60}, + {0x23 , 0x30},//20 //dggain max + {0x25 , 0x00}, + {0x24 , 0x14}, //Max index + + + {0xfe , 0x01}, + {0x51 , 0x20}, + {0x52 , 0x4f}, + {0x53 , 0x40}, + {0x54 , 0x9f}, + {0x55 , 0x01}, + {0x56 , 0x18}, //18 + {0x5b , 0x02}, + {0xb1 , 0xdc}, + {0xb2 , 0xdc}, //R2G STAND + {0x7c , 0x71}, //AWB speed,AWB margin + {0x7d , 0x10}, //AWB every N + {0x76 , 0x8f}, //move mode en,Move mode TH + + + {0x50 , 0x80}, + {0x4f , 0x00}, + {0x4d , 0x01}, + {0x4e , 0x02}, + {0x4d , 0x35}, + {0x4e , 0x01}, + {0x4e , 0x01}, + {0x4e , 0x01}, + {0x4d , 0x44}, + {0x4e , 0x04}, + {0x4e , 0x04}, + {0x4e , 0x02}, + {0x4d , 0x53}, + {0x4e , 0x08}, + {0x4e , 0x00}, + {0x4e , 0x04}, + {0x4d , 0x03}, + {0x4e , 0x08}, + {0x4d , 0x72}, + {0x4e , 0x20}, + {0x4e , 0x20}, + {0x4d , 0x83}, + {0x4e , 0x20}, + {0x4d , 0x92}, + {0x4e , 0x40}, + {0x4e , 0x40}, + {0x4f , 0x01}, + {0xfe , 0x00}, //page0 + + {0xad , 0x00}, + + {0xfe , 0x01}, + {0xc0 , 0x11}, + {0xc1 , 0x0b}, + {0xc2 , 0x09}, + {0xc6 , 0x0f}, + {0xc7 , 0x0a}, + {0xc8 , 0x07}, + {0xba , 0x2d}, + {0xbb , 0x1e}, + {0xbc , 0x1e}, + {0xb4 , 0x38}, + {0xb5 , 0x26}, + {0xb6 , 0x23}, + {0xc3 , 0x00}, + {0xc4 , 0x00}, + {0xc5 , 0x00}, + {0xc9 , 0x00}, + {0xca , 0x00}, + {0xcb , 0x00}, + {0xbd , 0x0a}, + {0xbe , 0x00}, + {0xbf , 0x00}, + {0xb7 , 0x04}, + {0xb8 , 0x00}, + {0xb9 , 0x00}, + {0xa8 , 0x08}, + {0xa9 , 0x00}, + {0xaa , 0x00}, + {0xab , 0x07}, + {0xac , 0x00}, + {0xad , 0x07}, + {0xae , 0x0e}, + {0xaf , 0x03}, + {0xb0 , 0x03}, + {0xb1 , 0x0d}, + {0xb2 , 0x00}, + {0xb3 , 0x08}, + {0xa4 , 0x00}, + {0xa5 , 0x00}, + {0xa6 , 0x00}, + {0xa7 , 0x00}, + {0xa1 , 0x3c}, + {0xa2 , 0x50}, + {0xfe , 0x00}, + + {0xB1 , 0x08},// 40 + {0xB2 , 0x02}, + {0xB3 , 0x07}, + {0xB4 , 0xe0}, + {0xB5 , 0x00},// + {0xB6 , 0xf0}, + + {0xf1 , 0x07}, + {0xf1 , 0x07}, + {0xf2 , 0x01}, + + {0x4f , 0x01}, + + + + {0x05, 0x02}, + {0x06, 0x2c}, + {0x07, 0x00}, + {0x08, 0xb8}, + {0xfe, 0x01}, + //GC0328_SET_PAGE1, + {0x29, 0x00}, //anti-flicker step [11:8] + {0x2a, 0x60}, //anti-flicker step [7:0] + + {0x2b, 0x02}, //exp level 0 14.28fps + {0x2c, 0xa0}, + {0x2d, 0x03}, //exp level 1 12.50fps + {0x2e, 0x00}, + {0x2f, 0x03}, //exp level 2 10.00fps + {0x30, 0xc0}, + {0x31, 0x05}, //exp level 3 7.14fps + {0x32, 0x40}, + + {0xfe, 0x00}, + + + //-------------H_V_Switch(4)---------------// + {0x17 , 0x14}, // + + + /*GC0328_H_V_Switch, + + 1: // normal + {0x17 , 0x14}, + + 2: // IMAGE_H_MIRROR + {0x17 , 0x15}, + + 3: // IMAGE_V_MIRROR + {0x17 , 0x16}, + + 4: // IMAGE_HV_MIRROR + {0x17 , 0x17}, + */ + //-------------H_V_Select End--------------// + 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[] = +{ + + 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[]={ + SensorRegVal(0xf0,0), + 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[]= +{ + {0xfe, 0x00}, + {0x77, 0x57}, + {0x78, 0x4d}, + {0x79, 0x45}, + {0x42, 0x57}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0xfe, 0x00}, + {0x42, 0x55}, // Disable AWB + {0x77, 0x8c}, + {0x78, 0x50}, + {0x79, 0x40}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0xfe, 0x00}, + {0x42, 0x55}, // Disable AWB + {0x77, 0x74}, + {0x78, 0x52}, + {0x79, 0x40}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0xfe, 0x00}, + {0x42, 0x55}, // Disable AWB + {0x77, 0x48}, + {0x78, 0x40}, + {0x79, 0x5c}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0xfe, 0x00}, + {0x42, 0x55}, // Disable AWB + {0x77, 0x40}, + {0x78, 0x42}, + {0x79, 0x50}, + 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 + {0xfe, 0x00}, + {0xd5, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + {0xfe, 0x00}, + {0xd5, 0xf0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + {0xfe, 0x00}, + {0xd5, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0xfe, 0x00}, + {0xd5, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0xfe, 0x00}, + {0xd5, 0x30}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0xfe, 0x00}, + {0xd5, 0x40}, + 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[] = +{ + {0x43,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x43,0x02}, + {0xda,0x00}, + {0xdb,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x43,0x02}, + {0xda,0xd0}, + {0xdb,0x28}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x43,0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x423,0x02}, + {0xda,0x50}, + {0xdb,0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x43,0x02}, + + {0xda,0xc0}, + {0xdb,0xc0}, + 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[]= +{ + {0xfe, 0x01}, + {0x13, 0x30}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + {0xfe, 0x01}, + {0x13, 0x38}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + {0xfe, 0x01}, + {0x13, 0x40}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + {0xfe, 0x01}, + {0x13, 0x45}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + {0xfe, 0x01}, + {0x13, 0x50}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + {0xfe, 0x01}, + {0x13, 0x58}, + {0xfe, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + {0xfe, 0x01}, + {0x13, 0x60}, + {0xfe, 0x00}, + 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[]= +{ + {0xb3,0x34}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + {0xb3,0x38}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + {0xb3,0x3d}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + {0xb3,0x40}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + {0xb3,0x44}, + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + {0xb3,0x48}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + {0xb3,0x50}, + + 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[] = +{ + {0xfe, 0x01}, + {0x33, 0x20}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0xfe, 0x01}, + {0x33, 0x30}, + {0xfe, 0x00}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x1) == 0){ + err = sensor_write(client, 0x17, ((val |0x1)+4)); + } + else + err = sensor_write(client, 0x17, ((val & 0xfe)+4)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x2) == 0){ + err = sensor_write(client, 0x17, ((val |0x2)+4)); + } + else { + err = sensor_write(client, 0x17, ((val & 0xfc)+4)); + } + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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){ + return 0; +} + +static int sensor_focus_af_const_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){ + 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) +{ + 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/gc0329.c b/drivers/media/video/gc0329.c index bc5729971701..060d131232ed 100755 --- a/drivers/media/video/gc0329.c +++ b/drivers/media/video/gc0329.c @@ -1,3046 +1,1087 @@ - + +#include "generic_sensor.h" + /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GC0329 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0329 -#define SENSOR_ID 0xc0 //GC0329 ID -#define SENSOR_MIN_WIDTH 640//176 -#define SENSOR_MIN_HEIGHT 480//144 -#define SENSOR_MAX_WIDTH 640 -#define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#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_AntiBanding 0 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 0 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) -struct reginfo -{ - u8 reg; - u8 val; -}; - -/* init 640X480 VGA */ -static struct reginfo sensor_init_data[] = -{ - // TODO: add initial code here - {0xfe, 0x80}, - {0xfe, 0x80}, - {0xfc, 0x16}, - {0xfc, 0x16}, - {0xfc, 0x16}, - {0xfc, 0x16}, - {0xfe, 0x00}, - {0xf0, 0x07}, - {0xf1, 0x01}, - - - - - {0x73, 0x90}, - {0x74, 0x80}, - {0x75, 0x80}, - {0x76, 0x94}, - - {0x42, 0x00}, - {0x77, 0x57}, - {0x78, 0x4d}, - {0x79, 0x45}, - //{0x42, 0xfc}, - - ////////////////////analog//////////////////// - {0x0a, 0x02}, - {0x0c, 0x02}, - {0x17, 0x17}, - {0x19, 0x05}, - {0x1b, 0x24}, - {0x1c, 0x04}, - {0x1e, 0x08}, - {0x1f, 0xc0}, //Analog_mode2//[7:6] comv_r - {0x20, 0x00}, - {0x21, 0x48}, - {0x22, 0xba}, - {0x23, 0x22}, - {0x24, 0x17}, - - ////////////////////blk//////////////////// - {0x26, 0xf7}, - {0x29, 0x80}, - {0x32, 0x04}, - {0x33, 0x20}, - {0x34, 0x20}, - {0x35, 0x20}, - {0x36, 0x20}, - - ////////////////////ISP BLOCK ENABL//////////////////// - {0x40, 0xff}, - {0x41, 0x44}, - {0x42, 0x7e}, - {0x44, 0xa2}, - {0x46, 0x03}, - {0x4b, 0xca}, - {0x4d, 0x01}, - {0x4f, 0x01}, - {0x70, 0x48}, - - //{0xb0, 0x00}, - //{0xbc, 0x00}, - //{0xbd, 0x00}, - //{0xbe, 0x00}, - ////////////////////DNDD//////////////////// - {0x80, 0xe7}, - {0x82, 0x55}, - {0x83, 0x03}, - {0x87, 0x4a}, - - ////////////////////INTPEE//////////////////// - {0x95, 0x45}, - - ////////////////////ASDE//////////////////// - //{0xfe, 0x01}, - //{0x18, 0x22}, - //{0xfe, 0x00); - //{0x9c, 0x0a}, - //{0xa0, 0xaf}, - //{0xa2, 0xff}, - //{0xa4, 0x50}, - //{0xa5, 0x21}, - //{0xa7, 0x35}, - - ////////////////////RGB gamma//////////////////// - //RGB gamma m4' - {0xbf, 0x06}, - {0xc0, 0x14}, - {0xc1, 0x27}, - {0xc2, 0x3b}, - {0xc3, 0x4f}, - {0xc4, 0x62}, - {0xc5, 0x72}, - {0xc6, 0x8d}, - {0xc7, 0xa4}, - {0xc8, 0xb8}, - {0xc9, 0xc9}, - {0xcA, 0xd6}, - {0xcB, 0xe0}, - {0xcC, 0xe8}, - {0xcD, 0xf4}, - {0xcE, 0xFc}, - {0xcF, 0xFF}, - - //////////////////CC/////////////////// - {0xfe, 0x00}, - - {0xb3, 0x44}, - {0xb4, 0xfd}, - {0xb5, 0x02}, - {0xb6, 0xfa}, - {0xb7, 0x48}, - {0xb8, 0xf0}, - - // crop - {0x50, 0x01}, - - ////////////////////YCP//////////////////// - {0xfe, 0x00}, - {0xd1, 0x38}, - {0xd2, 0x38}, - {0xdd, 0x54}, - - ////////////////////AEC//////////////////// - {0xfe, 0x01}, - {0x10, 0x40}, - {0x11, 0x21},//a1 - {0x12, 0x07}, - {0x13, 0x50}, //Y target - {0x17, 0x88}, - {0x21, 0xb0}, - {0x22, 0x48}, - {0x3c, 0x95}, - {0x3d, 0x50}, - {0x3e, 0x48}, - - ////////////////////AWB//////////////////// - {0xfe, 0x01}, - {0x06, 0x16}, - {0x07, 0x06}, - {0x08, 0x98}, - {0x09, 0xee}, - {0x50, 0xfc}, - {0x51, 0x20}, - {0x52, 0x0b}, - {0x53, 0x20}, - {0x54, 0x40}, - {0x55, 0x10}, - {0x56, 0x20}, - //{0x57, 0x40}, - {0x58, 0xa0}, - {0x59, 0x28}, - {0x5a, 0x02}, - {0x5b, 0x63}, - {0x5c, 0x34}, - {0x5d, 0x73}, - {0x5e, 0x11}, - {0x5f, 0x40}, - {0x60, 0x40}, - {0x61, 0xc8}, - {0x62, 0xa0}, - {0x63, 0x40}, - {0x64, 0x50}, - {0x65, 0x98}, - {0x66, 0xfa}, - {0x67, 0x70}, - {0x68, 0x58}, - {0x69, 0x85}, - {0x6a, 0x40}, - {0x6b, 0x39}, - {0x6c, 0x18}, - {0x6d, 0x28}, - {0x6e, 0x41}, - {0x70, 0x02}, - {0x71, 0x00}, - {0x72, 0x10}, - {0x73, 0x40}, - - //{0x74, 0x32}, - //{0x75, 0x40}, - //{0x76, 0x30}, - //{0x77, 0x48}, - //{0x7a, 0x50}, - //{0x7b, 0x20}, - - {0x80, 0x60}, - {0x81, 0x50}, - {0x82, 0x42}, - {0x83, 0x40}, - {0x84, 0x40}, - {0x85, 0x40}, - - {0x74, 0x40}, - {0x75, 0x58}, - {0x76, 0x24}, - {0x77, 0x40}, - {0x78, 0x20}, - {0x79, 0x60}, - {0x7a, 0x58}, - {0x7b, 0x20}, - {0x7c, 0x30}, - {0x7d, 0x35}, - {0x7e, 0x10}, - {0x7f, 0x08}, - - ////////////////////ABS//////////////////// - {0x9c, 0x02}, - {0x9d, 0x20}, - //{0x9f, 0x40}, - - ////////////////////CC-AWB//////////////////// - {0xd0, 0x00}, - {0xd2, 0x2c}, - {0xd3, 0x80}, - - ////////////////////LSC/////////////////// - //// for xuye062d lens setting - {0xfe, 0x01}, - {0xa0, 0x00}, - {0xa1, 0x3c}, - {0xa2, 0x50}, - {0xa3, 0x00}, - {0xa8, 0x0f}, - {0xa9, 0x08}, - {0xaa, 0x00}, - {0xab, 0x04}, - {0xac, 0x00}, - {0xad, 0x07}, - {0xae, 0x0e}, - {0xaf, 0x00}, - {0xb0, 0x00}, - {0xb1, 0x09}, - {0xb2, 0x00}, - {0xb3, 0x00}, - {0xb4, 0x31}, - {0xb5, 0x19}, - {0xb6, 0x24}, - {0xba, 0x3a}, - {0xbb, 0x24}, - {0xbc, 0x2a}, - {0xc0, 0x17}, - {0xc1, 0x13}, - {0xc2, 0x17}, - {0xc6, 0x21}, - {0xc7, 0x1c}, - {0xc8, 0x1c}, - {0xb7, 0x00}, - {0xb8, 0x00}, - {0xb9, 0x00}, - {0xbd, 0x00}, - {0xbe, 0x00}, - {0xbf, 0x00}, - {0xc3, 0x00}, - {0xc4, 0x00}, - {0xc5, 0x00}, - {0xc9, 0x00}, - {0xca, 0x00}, - {0xcb, 0x00}, - {0xa4, 0x00}, - {0xa5, 0x00}, - {0xa6, 0x00}, - {0xa7, 0x00}, - - - {0xfe, 0x00}, - {0x05, 0x00}, - {0x06, 0x6a}, - {0x07, 0x00}, - {0x08, 0x70}, - - {0xfe, 0x01}, - {0x29, 0x00}, - {0x2a, 0x96}, - - {0x2b, 0x02}, - {0x2c, 0x58},//12 fps - {0x2d, 0x02}, - {0x2e, 0x58}, - {0x2f, 0x02},//10 fps - {0x30, 0x58}, - {0x31, 0x07}, - {0x32, 0x08}, - - - - ////////////20120427//////////////// - {0xfe,0x01}, - {0x18,0x22}, - {0x21,0xc0}, - {0x06,0x12}, - {0x08,0x9c}, - {0x51,0x28}, - {0x52,0x10}, - {0x53,0x20}, - {0x54,0x40}, - {0x55,0x16}, - {0x56,0x30}, - {0x58,0x60}, - {0x59,0x08}, - {0x5c,0x35}, - {0x5d,0x72}, - {0x67,0x80}, - {0x68,0x60}, - {0x69,0x90}, - {0x6c,0x30}, - {0x6d,0x60}, - {0x70,0x10}, - - {0xfe,0x00}, - {0x9c,0x0a}, - {0xa0,0xaf}, - {0xa2,0xff}, - {0xa4,0x60}, - {0xa5,0x31}, - {0xa7,0x35}, - {0x42,0xfe}, - {0xd1,0x34}, - {0xd2,0x34}, - {0xfe,0x00}, - - - - - - - - {0xfe, 0x00}, - ////////////////////asde /////////////////// - {0xa0, 0xaf}, - {0xa2, 0xff}, - - {0x44, 0xa2}, // YUV order - {0x00, 0x00}, - -}; -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0x00,0x00} -}; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0x0, 0x0}, -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - - - {0xfe, 0x00}, - {0x05, 0x00}, - {0x06, 0x6a}, - {0x07, 0x00}, - {0x08, 0x70}, - - {0xfe, 0x01}, - {0x29, 0x00}, - {0x2a, 0x96}, - - {0x2b, 0x02}, - {0x2c, 0x58},//12 fps - {0x2d, 0x02}, - {0x2e, 0x58}, - {0x2f, 0x02},//10 fps - {0x30, 0x58}, - {0x31, 0x07}, - {0x32, 0x08}, - {0xfe, 0x00}, - - {0x00,0x00} -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x00,0x00} -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {0x00,0x00} -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - {0x00,0x00} -}; - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x00, 0x00} -}; - - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - - {0x77, 0x57}, - {0x78, 0x4d}, - {0x79, 0x45}, - {0x42, 0xfe}, - {0x00, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K [incandesceny]*/ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x42, 0xfd}, - {0x77, 0x40}, - {0x78, 0x58}, - {0x79, 0x5a}, - {0x00, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K [daylight]*/ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x42, 0xfd}, - {0x77, 0x40}, - {0x78, 0x56}, - {0x79, 0x50}, - {0x00, 0x00} -}; - -/* ClearDay Colour Temperature : 5000K - 6500K [fluorescent]*/ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x42, 0xfd}, - {0x77, 0x40}, - {0x78, 0x58}, - {0x79, 0x5a}, - {0x00, 0x00} -}; - -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x42, 0xfd}, - {0x77, 0x7a}, //WB_manual_gain - {0x78, 0x60}, - {0x79, 0x40}, - {0x00, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - - {0xfe, 0x01}, - {0x13, 0x40}, - {0xfe, 0x00}, - {0xd5, 0xe0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - - {0xfe, 0x01}, - {0x13, 0x48}, - {0xfe, 0x00}, - {0xd5, 0xf0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - - - {0xfe, 0x01}, - {0x13, 0x50}, - {0xfe, 0x00}, - {0xd5, 0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - - {0xfe, 0x01}, - {0x13, 0x58}, - {0xfe, 0x00}, - {0xd5, 0x10}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - - {0xfe, 0x01}, - {0x13, 0x60}, - {0xfe, 0x00}, - {0xd5, 0x20}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - - {0xfe, 0x01}, - {0x13, 0x68}, - {0xfe, 0x00}, - {0xd5, 0x30}, - {0x00, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0xfe, 0x00}, - {0x43, 0x00}, //special_effect - {0x40, 0xff}, //[7:6]gamma - {0x41, 0x22}, //[1]Y_gamma_en - {0x42, 0xff}, //[2]ABS [1]AWB - - {0x95, 0x64}, //Edge effect - {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th - {0x90, 0xbc}, //EEINTP mode 1 - - {0x4f, 0x01}, //AEC_en - {0xd3, 0x40}, //luma_contrast - {0xd4, 0x80}, //contrast_center - {0xd5, 0x00}, //luma_offset - {0xda, 0x00}, //fixed_Cb - {0xdb, 0x00}, //fixed_Cr - - {0xbf, 0x0e}, //RGB gamma - {0xc0, 0x1c}, - {0xc1, 0x34}, - {0xc2, 0x48}, - {0xc3, 0x5a}, - {0xc4, 0x6b}, - {0xc5, 0x7b}, - {0xc6, 0x95}, - {0xc7, 0xab}, - {0xc8, 0xbf}, - {0xc9, 0xce}, - {0xca, 0xd9}, - {0xcb, 0xe4}, - {0xcc, 0xec}, - {0xcd, 0xf7}, - {0xce, 0xfd}, - {0xcf, 0xff}, - - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0xfe, 0x00}, - {0x43, 0x02}, //special_effect - {0x40, 0xff}, //[7:6]gamma - {0x41, 0x22}, //[1]Y_gamma_en - {0x42, 0xff}, //[2]ABS [1]AWB - - {0x95, 0x64}, //Edge effect - {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th - {0x90, 0xbc}, //EEINTP mode 1 - - {0x4f, 0x01}, //AEC_en - {0xd3, 0x40}, //luma_contrast - {0xd4, 0x80}, //contrast_center - {0xd5, 0x00}, //luma_offset - {0xda, 0x00}, //fixed_Cb - {0xdb, 0x00}, //fixed_Cr - - {0xbf, 0x0e}, //RGB gamma - {0xc0, 0x1c}, - {0xc1, 0x34}, - {0xc2, 0x48}, - {0xc3, 0x5a}, - {0xc4, 0x6b}, - {0xc5, 0x7b}, - {0xc6, 0x95}, - {0xc7, 0xab}, - {0xc8, 0xbf}, - {0xc9, 0xce}, - {0xca, 0xd9}, - {0xcb, 0xe4}, - {0xcc, 0xec}, - {0xcd, 0xf7}, - {0xce, 0xfd}, - {0xcf, 0xff}, - - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - - {0xfe, 0x00}, - {0x43, 0x02}, //special_effect - {0x40, 0xff}, //[7:6]gamma - {0x41, 0x22}, //[1]Y_gamma_en - {0x42, 0xff}, //[2]ABS [1]AWB - - {0x95, 0x64}, //Edge effect - {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th - {0x90, 0xbc}, //EEINTP mode 1 - - {0x4f, 0x01}, //AEC_en - {0xd3, 0x40}, //luma_contrast - {0xd4, 0x80}, //contrast_center - {0xd5, 0x00}, //luma_offset - {0xda, 0xd0}, //fixed_Cb - {0xdb, 0x28}, //fixed_Cr - - {0xbf, 0x0e}, //RGB gamma - {0xc0, 0x1c}, - {0xc1, 0x34}, - {0xc2, 0x48}, - {0xc3, 0x5a}, - {0xc4, 0x6b}, - {0xc5, 0x7b}, - {0xc6, 0x95}, - {0xc7, 0xab}, - {0xc8, 0xbf}, - {0xc9, 0xce}, - {0xca, 0xd9}, - {0xcb, 0xe4}, - {0xcc, 0xec}, - {0xcd, 0xf7}, - {0xce, 0xfd}, - {0xcf, 0xff}, - {0x00,0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - {0xfe, 0x00}, - {0x43, 0x01}, //special_effect - {0x40, 0xff}, //[7:6]gamma - {0x41, 0x22}, //[1]Y_gamma_en - {0x42, 0xff}, //[2]ABS [1]AWB - - {0x95, 0x64}, //Edge effect - {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th - {0x90, 0xbc}, //EEINTP mode 1 - - {0x4f, 0x01}, //AEC_en - {0xd3, 0x40}, //luma_contrast - {0xd4, 0x80}, //contrast_center - {0xd5, 0x00}, //luma_offset - {0xda, 0x00}, //fixed_Cb - {0xdb, 0x00}, //fixed_Cr - - {0xbf, 0x0e}, //RGB gamma - {0xc0, 0x1c}, - {0xc1, 0x34}, - {0xc2, 0x48}, - {0xc3, 0x5a}, - {0xc4, 0x6b}, - {0xc5, 0x7b}, - {0xc6, 0x95}, - {0xc7, 0xab}, - {0xc8, 0xbf}, - {0xc9, 0xce}, - {0xca, 0xd9}, - {0xcb, 0xe4}, - {0xcc, 0xec}, - {0xcd, 0xf7}, - {0xce, 0xfd}, - {0xcf, 0xff}, - - {0x00,0x00} -}; - -//SOLARIZE -static struct reginfo sensor_Effect_Bluish[] = -{ - {0xfe, 0x00}, - {0x43, 0x00}, //special_effect - {0x40, 0xff}, //[7:6]gamma - {0x41, 0x22}, //[1]Y_gamma_en - {0x42, 0xff}, //[2]ABS [1]AWB - - {0x95, 0x64}, //Edge effect - {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th - {0x90, 0xbc}, //EEINTP mode 1 - - {0x4f, 0x01}, //AEC_en - {0xd3, 0x40}, //luma_contrast - {0xd4, 0x80}, //contrast_center - {0xd5, 0x00}, //luma_offset - {0xda, 0x00}, //fixed_Cb - {0xdb, 0x00}, //fixed_Cr - - {0xbf, 0x10}, //RGB gamma - {0xc0, 0x20}, - {0xc1, 0x38}, - {0xc2, 0x4e}, - {0xc3, 0x63}, - {0xc4, 0x76}, - {0xc5, 0x87}, - {0xc6, 0xa2}, - {0xc7, 0xb4}, - {0xc8, 0xa8}, - {0xc9, 0x91}, - {0xca, 0x7b}, - {0xcb, 0x66}, - {0xcc, 0x4f}, - {0xcd, 0x39}, - {0xce, 0x24}, - {0xcf, 0x12}, - - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - //Greenish - {0x43,0x02}, - {0xda,0xc0}, - {0xdb,0xc0}, - {0x00,0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0x00, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - - {0x00, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - {0xb3,0x50}, - {0x00, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - - {0x00, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x00, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x00, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - {0xfe, 0x01}, - {0x33, 0x20}, - {0xfe, 0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_SceneNight[] = -{ - {0xfe, 0x01}, - {0x33, 0x30}, - {0xfe, 0x00}, - {0x00, 0x00} -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif - -#if CONFIG_SENSOR_AntiBanding -static struct reginfo sensor_AntiBanding_50HZ[] = -{ - -{0xfe, 0x00}, - {0x05, 0x00}, - {0x06, 0x6a}, - {0x07, 0x00}, - {0x08, 0x70}, - - {0xfe, 0x01}, - {0x29, 0x00}, - {0x2a, 0x96}, - - {0x2b, 0x02}, - {0x2c, 0x58},//12 fps - {0x2d, 0x02}, - {0x2e, 0x58}, - {0x2f, 0x02},//10 fps - {0x30, 0x58}, - {0x31, 0x07}, - {0x32, 0x08}, - - -{0xfe, 0x00}, - - {0x00, 0x00} -}; - -static struct reginfo sensor_AntiBanding_60HZ[] = -{ - {0xfe, 0x00}, - {0x05, 0x00}, - {0x06, 0x6a}, - {0x07, 0x00}, - {0x08, 0x89}, - - {0xfe, 0x01}, - {0x29, 0x00}, - {0x2a, 0x7d}, - - {0x2b, 0x02}, - {0x2c, 0x71},//12 fps - {0x2d, 0x02}, - {0x2e, 0x71}, - {0x2f, 0x02},//10 fps - {0x30, 0x71}, - {0x31, 0x04}, - {0x32, 0xe2}, - - -{0xfe, 0x00}, - - - {0x00, 0x00} -}; -static struct reginfo *sensor_AntibandingSeqe[] = {sensor_AntiBanding_50HZ, sensor_AntiBanding_60HZ,NULL,}; -#endif - -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,}, //{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,} , - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_AntiBanding - { .id = V4L2_CID_ANTIBANDING, .index = 0, .name = "50hz", .reserved = 0,} ,{ .id = V4L2_CID_ANTIBANDING, .index = 1, .name = "60hz", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static const struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_AntiBanding - { - .id = V4L2_CID_ANTIBANDING, - .type = V4L2_CTRL_TYPE_MENU, - .name = "antibanding Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - //{V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int antibanding; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg & 0xFF; - buf[1] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - //u8 buf[2]; - u8 buf[1]; - struct i2c_msg msg[2]; - - //buf[0] = reg >> 8; - buf[0] = reg; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 1; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK - - -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int ret; - int i = 0; - - u8 value; - - for(i=0;ipowerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - int ret; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); */ //delay 5 microseconds - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - #if CONFIG_SENSOR_AntiBanding - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ANTIBANDING); - if (qctrl) - sensor->info_priv.antibanding = qctrl->default_value; - #endif - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - //u8 reg_val; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(10); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -/* -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -*/ -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); -// const struct v4l2_queryctrl *qctrl; -// struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } - else - { /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -#if CONFIG_SENSOR_AntiBanding -static int sensor_set_antibanding(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_AntibandingSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_AntibandingSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - #if CONFIG_SENSOR_AntiBanding - case V4L2_CID_ANTIBANDING: - { - ext_ctrl->value = sensor->info_priv.antibanding; - break; - } - #endif - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_AntiBanding - case V4L2_CID_ANTIBANDING: - { - if (ext_ctrl->value != sensor->info_priv.antibanding) - { - if (sensor_set_antibanding(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.antibanding = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char pid = 0; - int ret; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - SENSOR_TR("power down %s failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(50); *///delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_write(client, 0xfc, 0x16); //before read id should write 0xfc - msleep(20); - ret = sensor_read(client, 0x00, &pid); - if (ret != 0) { - SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - int j = 0; - for(j = 0;j < RK29_CAM_SUPPORT_NUMS;j++){ - if (sensor->sensor_io_request->gpio_res[j].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; - break; - } - } - if(j == RK29_CAM_SUPPORT_NUMS){ - SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } - - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} - -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GC0329 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0329 +#define SENSOR_ID 0xc0 +#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 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + // TODO: add initial code here + {0xfe, 0x80}, + {0xfc, 0x12}, + {0xfc, 0x12}, //[4]Clock_en [2] A25_en [1]D18_en [0]Apwdn + {0xfe, 0x00}, + {0xf0, 0x07}, //vsync_en + {0xf1, 0x01}, //data_en + + {0x73, 0x90}, //R channle gain + {0x74, 0x80}, //G1 channle gain + {0x75, 0x80}, //G2 channle gain + {0x76, 0x94}, //B channle gain + + //{0x42, 0x00}, + //{0x77, 0x57}, + //{0x78, 0x4d}, + //{0x79, 0x45}, + //{0x42, 0xfc}, + + ////////////////////analog//////////////////// + {0xfc, 0x16}, + + {0x0a, 0x00}, //row_start_low + {0x0c, 0x00}, //col_start_low + {0x17, 0x14}, //cisctl_mode1//[7]hsync_always },[6] NA}, [5:4] CFA sequence [3:2]NA, [1]upside_down, [0] mirror + //[3:2]NA [1]upside_down}, [0] mirror + + {0x19, 0x05}, //cisctl_mode3 + {0x1b, 0x24}, //rsh_width + {0x1c, 0x04}, //Tsp_width + {0x1e, 0x00}, //Analog_mode1//[7:6]rsv1},rsv0[5:3] Column bias(coln_r)[1] clk_delay_en + {0x1f, 0xc0}, //Analog_mode2//[7:6] comv_r + {0x20, 0x00}, //Analog_mode3//[6:4] cap_low_r for MPW [3:2] da18_r [1] rowclk_mode [0]adclk_mode + {0x21, 0x48}, //Hrst_rsg//[7] hrst[6:4] da_rsg[3]txhigh_en + {0x23, 0x22}, //ADC_r//[6:5]opa_r [1:0]sRef + {0x24, 0x16}, //PAD_drv//[7:6]NA},[5:4]sync_drv [3:2]data_drv [1:0]pclk_drv + + + ////////////////////blk//////////////////// + {0x26, 0xf7}, + {0x32, 0x04}, + {0x33, 0x20}, + {0x34, 0x20}, + {0x35, 0x20}, + {0x36, 0x20}, + + ////////////////////ISP BLOCK ENABLE//////////////////// + {0x40, 0xff}, + {0x41, 0x00}, + {0x42, 0xfe}, + {0x46, 0x03}, //sync mode + {0x4b, 0xcb}, + {0x4d, 0x01}, + {0x4f, 0x01}, + {0x70, 0x48},//global gain + + //{0xb0, 0x00}, + //{0xbc, 0x00}, + //{0xbd, 0x00}, + //{0xbe, 0x00}, + + ////////////////////DNDD//////////////////// + {0x80, 0xe7}, //[7]auto_en [6]one_pixel [5]two_pixel + {0x82, 0x55}, + {0x87, 0x4a}, + + ////////////////////ASDE//////////////////// + {0xfe, 0x01}, + {0x18, 0x22}, //[7:4]AWB LUMA X [3:0]ASDE LUMA X + {0xfe, 0x00},//ASDE dn b slope + {0x9c, 0x0a}, //ASDE dn b slope + {0xa4, 0x50}, // Auto Sa slope + {0xa5, 0x21}, // [7:4]Saturation limit x10 + {0xa7, 0x35}, //low luma value th + {0xdd, 0x54}, //edge dec sat enable & slopes + {0x95, 0x35}, //Edge effect + + ////////////////////RGB gamma//////////////////// + {0xfe, 0x00}, + {0xbf, 0x06}, + {0xc0, 0x14}, + {0xc1, 0x27}, + {0xc2, 0x3b}, + {0xc3, 0x4f}, + {0xc4, 0x62}, + {0xc5, 0x72}, + {0xc6, 0x8d}, + {0xc7, 0xa4}, + {0xc8, 0xb8}, + {0xc9, 0xc9}, + {0xca, 0xd6}, + {0xcb, 0xe0}, + {0xcc, 0xe8}, + {0xcd, 0xf4}, + {0xce, 0xfc}, + {0xcf, 0xff}, + + //////////////////CC/////////////////// + {0xfe, 0x00}, + {0xb3, 0x44}, + {0xb4, 0xfd}, + {0xb5, 0x02}, + {0xb6, 0xfa}, + {0xb7, 0x48}, + {0xb8, 0xf0}, + + //skin + //{0xb3, 0x3c}, + //{0xb4, 0xFF}, + //{0xb5, 0x03}, + //{0xb6, 0x01}, + //{0xb7, 0x3f}, + //{0xb8, 0xF3}, + + // crop + {0x50, 0x01}, + {0x19, 0x05}, + {0x20, 0x01}, + {0x22, 0xba}, + {0x21, 0x48}, + + ////////////////////YCP//////////////////// + {0xfe, 0x00}, + {0xd1, 0x34}, //saturation Cb + {0xd2, 0x34}, //saturation Cr + + ////////////////////AEC//////////////////// + {0xfe, 0x01}, + {0x10, 0x40}, + {0x11, 0x21},//a1 + {0x12, 0x07}, + {0x13, 0x50}, //Y target + {0x17, 0x88}, + {0x21, 0xb0}, + {0x22, 0x48}, + {0x3c, 0x95}, + {0x3d, 0x50}, + {0x3e, 0x48}, + + ////////////////////AWB//////////////////// + {0xfe, 0x01}, + #if 0 + {0x06, 0x06}, + {0x07, 0x06}, + {0x08, 0xa6}, + {0x09, 0xee}, + {0x50, 0xfc}, + {0x51, 0x28}, + {0x52, 0x10}, + {0x53, 0x1d}, + {0x54, 0x16}, + {0x55, 0x20}, + {0x56, 0x60}, + //{0x57, 0x40}, + {0x58, 0x60}, + {0x59, 0x28}, + {0x5a, 0x02}, + {0x5b, 0x63}, + {0x5c, 0x34}, + {0x5d, 0x73}, + {0x5e, 0x11}, + {0x5f, 0x40}, + {0x60, 0x40}, + {0x61, 0xc8}, + {0x62, 0xa0}, + {0x63, 0x40}, + {0x64, 0x50}, + {0x65, 0x98}, + {0x66, 0xfa}, + {0x67, 0x70}, + {0x68, 0x58}, + {0x69, 0x85}, + {0x6a, 0x40}, + {0x6b, 0x39}, + {0x6c, 0x40}, + {0x6d, 0x80}, + {0x6e, 0x41}, + {0x70, 0x50}, + {0x71, 0x00}, + {0x72, 0x10}, + {0x73, 0x40}, + {0x74, 0x32}, + {0x75, 0x40}, + {0x76, 0x30}, + {0x77, 0x48}, + {0x7a, 0x50}, + {0x7b, 0x20}, + {0x80, 0x4a}, + {0x81, 0x43}, + {0x82, 0x43}, + {0x83, 0x40}, + {0x84, 0x40}, + {0x85, 0x40}, + #elif 1 + {0x06, 0x08}, + {0x07, 0x06}, + {0x08, 0xa6}, + {0x09, 0xee}, + {0x50,0xfc}, //RGB high + {0x51,0x28}, //Y2C diff + {0x52,0x10}, //18 + {0x53,0x08},// //1d //20// + {0x54,0x12}, //16 //30//C inter + {0x55,0x10}, //16 + {0x56,0x10}, //20//60 + {0x58,0x80}, //a0//60//number limit X4 + {0x59,0x08}, //0c //08 //AWB adjust temp curve //0c + {0x5a,0x02}, //01 //03//25//[3:0]light gain range x10 + {0x5b,0x63}, //62 + {0x5c,0x34}, //37 //show and mode [2]big C mode [1]dark mode [0] block move mode + {0x5d,0x73}, //72 //52//AWB margin + {0x5e,0x29}, //11 //20 //11 //19//temp curve_enable + {0x5f,0x40}, //5K gain + {0x60,0x40}, //5K gain + {0x61,0xc8}, //sinT + {0x62,0xa0}, //cosT + {0x63,0x40}, //38//30//AWB X1 cut + {0x64,0x38}, //50 //38 //30 //20 //40 //50 //60//AWB X2 cut + {0x65,0x98}, //a0 //98 //a0//AWB Y1 cut + {0x66,0xfa}, //ea//AWB Y2 cut + {0x67,0x80}, //70 //AWB R gain limit + {0x68,0x60}, //58 //58 //AWB G gain Limit + {0x69,0x90}, //85 //7d //AWB B gain limit + {0x6a,0x40}, + {0x6b,0x39}, + {0x6c,0x28}, //40 + {0x6d,0x28}, //40//80 + {0x6e,0x41}, //outdoor gain limit enable [7]use exp or luma value to adjust outdoor + {0x70,0x10}, //50 //10 + {0x71,0x00}, //when outdoor , add high luma gray pixel weight + {0x72,0x08}, //10 + {0x73,0x40}, //95// when exp < th, outdoor mode open + {0x80,0x70}, //R gain high limit + {0x81,0x58}, //G gain high limit + {0x82,0x42}, //B gain high limit + {0x83,0x40}, //R gain low limit + {0x84,0x40}, //G gain low limit + {0x85,0x40}, //B gain low limit + + #else + {0x06, 0x06}, + {0x07, 0x06}, + {0x08, 0xa6}, + {0x09, 0xee}, + {0x50, 0xfc}, + {0x51, 0x30},//28 + {0x52, 0x20},//10 + {0x53, 0x0b}, // 1d + {0x54, 0x0b},// 16 + {0x55, 0x12},//20 + {0x56, 0x10},//60 + //{0x57, 0x40}, + {0x58, 0x80},//60 + {0x59, 0x28}, + {0x5a, 0x02}, + {0x5b, 0x63}, + {0x5c, 0x37},//34 + {0x5d, 0x72},//73 + {0x5e, 0x11}, + {0x5f, 0x40}, + {0x60, 0x40}, + {0x61, 0xc8}, + {0x62, 0xa0}, + {0x63, 0x40}, + {0x64, 0x60},//50 + {0x65, 0x9c},//98 + {0x66, 0xf0},//fa + {0x67, 0x70}, + {0x68, 0x58}, + {0x69, 0x85}, + {0x6a, 0x40}, + {0x6b, 0x39}, + {0x6c, 0x40}, + {0x6d, 0x40},//80 + {0x6e, 0x41}, + {0x70, 0x10},//50 + {0x71, 0x00}, + {0x72, 0x20},//10 + {0x73, 0x40}, + {0x74, 0x32}, + {0x75, 0x40}, + {0x76, 0x30}, + {0x77, 0x48}, + {0x7a, 0x50}, + {0x7b, 0x20}, + {0x80, 0x70},//4// 4a + {0x81, 0x58},//43 + {0x82, 0x42},//43 + {0x83, 0x40}, + {0x84, 0x40}, + {0x85, 0x40}, + + {0x86, 0x50}, + {0x87, 0x50}, + {0x88, 0xd0}, + {0x88, 0x90}, + #endif + + ////////////////////CC-AWB//////////////////// + {0xd0, 0x00}, + {0xd2, 0x2c}, + {0xd3, 0x80}, + + ///////////////////ABS/////////////////////// + {0x9c, 0x02}, + {0x9d, 0x10}, + + ///////////////////LSC ////////////////////// + //// for xuye062d lens setting + {0xfe, 0x01}, + {0xa0, 0x00}, + {0xa1, 0x3c}, + {0xa2, 0x50}, + {0xa3, 0x00}, + {0xa8, 0x0f}, + {0xa9, 0x08}, + {0xaa, 0x00}, + {0xab, 0x04}, + {0xac, 0x00}, + {0xad, 0x07}, + {0xae, 0x0e}, + {0xaf, 0x00}, + {0xb0, 0x00}, + {0xb1, 0x09}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0x31}, + {0xb5, 0x19}, + {0xb6, 0x24}, + {0xba, 0x3a}, + {0xbb, 0x24}, + {0xbc, 0x2a}, + {0xc0, 0x17}, + {0xc1, 0x13}, + {0xc2, 0x17}, + {0xc6, 0x21}, + {0xc7, 0x1c}, + {0xc8, 0x1c}, + {0xb7, 0x00}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc3, 0x00}, + {0xc4, 0x00}, + {0xc5, 0x00}, + {0xc9, 0x00}, + {0xca, 0x00}, + {0xcb, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x00}, + {0xa7, 0x00}, + + {0xfe, 0x00}, + ////////////////////asde /////////////////// + {0xa0, 0xaf}, + {0xa2, 0xff}, + + {0x44, 0xa2}, // YUV order + + 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[] = +{ + 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[]= +{ + {0x77, 0x57}, + {0x78, 0x4d}, + {0x79, 0x45}, + {0x42, 0xfe}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x42, 0xfc}, + {0x77, 0x8c}, //WB_manual_gain + {0x78, 0x50}, + {0x79, 0x40}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x42, 0xfc}, + {0x77, 0x74}, + {0x78, 0x52}, + {0x79, 0x40}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x42, 0xfc}, + {0x77, 0x40}, + {0x78, 0x42}, + {0x79, 0x50}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x42, 0xfc}, + {0x77, 0x40}, + {0x78, 0x54}, + {0x79, 0x70}, + 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 + + {0xfe, 0x01}, + {0x13, 0x40}, + {0xfe, 0x00}, + {0xd5, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + + {0xfe, 0x01}, + {0x13, 0x48}, + {0xfe, 0x00}, + {0xd5, 0xf0}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + + + {0xfe, 0x01}, + {0x13, 0x50}, + {0xfe, 0x00}, + {0xd5, 0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + + {0xfe, 0x01}, + {0x13, 0x58}, + {0xfe, 0x00}, + {0xd5, 0x10}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + + {0xfe, 0x01}, + {0x13, 0x60}, + {0xfe, 0x00}, + {0xd5, 0x20}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + + {0xfe, 0x01}, + {0x13, 0x68}, + {0xfe, 0x00}, + {0xd5, 0x30}, + + 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[] = +{ + {0x43,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x43,0x02}, + {0xda,0x00}, + {0xdb,0x00}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x43,0x02}, + {0xda,0xd0}, + {0xdb,0x28}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x43,0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x43,0x02}, + {0xda,0x50}, + {0xdb,0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x43,0x02}, + {0xda,0xc0}, + {0xdb,0xc0}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Grayscale[]= +{ + {0x23,0x02}, + {0x2d,0x0a}, + {0x20,0xff}, + {0xd2,0x90}, + {0x73,0x00}, + + {0xb3,0x40}, + {0xb4,0x80}, + {0xba,0x00}, + {0xbb,0x00}, + {0x00,0x00} +}; + +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[]= +{ + //-3 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + //-2 + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + //-1 + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + //default + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + // 1 + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + // 2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + // 3 + 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[] = +{ + {0xfe, 0x01}, + {0x33, 0x20}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0xfe, 0x01}, + {0x33, 0x30}, + {0xfe, 0x00}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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) +{ + char pid = 0; + int ret = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + + /* check if it is an sensor sensor */ + ret = sensor_write(client, 0xfc, 0x16); //before read id should write 0xfc + msleep(20); + ret = sensor_read(client, 0x00, &pid); + if (ret != 0) { + SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + } + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + } + return pid; +} +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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + if (err == 0) { + if((val & 0x1) == 0) + err = sensor_write(client, 0x17, (val |0x1)); + else + err = sensor_write(client, 0x17, (val & 0xfe)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + if (err == 0) { + if((val & 0x2) == 0) + err = sensor_write(client, 0x17, (val |0x2)); + else + err = sensor_write(client, 0x17, (val & 0xfc)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gc0329_old.c b/drivers/media/video/gc0329_old.c new file mode 100755 index 000000000000..bc5729971701 --- /dev/null +++ b/drivers/media/video/gc0329_old.c @@ -0,0 +1,3046 @@ + +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC0329 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0329 +#define SENSOR_ID 0xc0 //GC0329 ID +#define SENSOR_MIN_WIDTH 640//176 +#define SENSOR_MIN_HEIGHT 480//144 +#define SENSOR_MAX_WIDTH 640 +#define SENSOR_MAX_HEIGHT 480 +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#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_AntiBanding 0 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 0 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) +struct reginfo +{ + u8 reg; + u8 val; +}; + +/* init 640X480 VGA */ +static struct reginfo sensor_init_data[] = +{ + // TODO: add initial code here + {0xfe, 0x80}, + {0xfe, 0x80}, + {0xfc, 0x16}, + {0xfc, 0x16}, + {0xfc, 0x16}, + {0xfc, 0x16}, + {0xfe, 0x00}, + {0xf0, 0x07}, + {0xf1, 0x01}, + + + + + {0x73, 0x90}, + {0x74, 0x80}, + {0x75, 0x80}, + {0x76, 0x94}, + + {0x42, 0x00}, + {0x77, 0x57}, + {0x78, 0x4d}, + {0x79, 0x45}, + //{0x42, 0xfc}, + + ////////////////////analog//////////////////// + {0x0a, 0x02}, + {0x0c, 0x02}, + {0x17, 0x17}, + {0x19, 0x05}, + {0x1b, 0x24}, + {0x1c, 0x04}, + {0x1e, 0x08}, + {0x1f, 0xc0}, //Analog_mode2//[7:6] comv_r + {0x20, 0x00}, + {0x21, 0x48}, + {0x22, 0xba}, + {0x23, 0x22}, + {0x24, 0x17}, + + ////////////////////blk//////////////////// + {0x26, 0xf7}, + {0x29, 0x80}, + {0x32, 0x04}, + {0x33, 0x20}, + {0x34, 0x20}, + {0x35, 0x20}, + {0x36, 0x20}, + + ////////////////////ISP BLOCK ENABL//////////////////// + {0x40, 0xff}, + {0x41, 0x44}, + {0x42, 0x7e}, + {0x44, 0xa2}, + {0x46, 0x03}, + {0x4b, 0xca}, + {0x4d, 0x01}, + {0x4f, 0x01}, + {0x70, 0x48}, + + //{0xb0, 0x00}, + //{0xbc, 0x00}, + //{0xbd, 0x00}, + //{0xbe, 0x00}, + ////////////////////DNDD//////////////////// + {0x80, 0xe7}, + {0x82, 0x55}, + {0x83, 0x03}, + {0x87, 0x4a}, + + ////////////////////INTPEE//////////////////// + {0x95, 0x45}, + + ////////////////////ASDE//////////////////// + //{0xfe, 0x01}, + //{0x18, 0x22}, + //{0xfe, 0x00); + //{0x9c, 0x0a}, + //{0xa0, 0xaf}, + //{0xa2, 0xff}, + //{0xa4, 0x50}, + //{0xa5, 0x21}, + //{0xa7, 0x35}, + + ////////////////////RGB gamma//////////////////// + //RGB gamma m4' + {0xbf, 0x06}, + {0xc0, 0x14}, + {0xc1, 0x27}, + {0xc2, 0x3b}, + {0xc3, 0x4f}, + {0xc4, 0x62}, + {0xc5, 0x72}, + {0xc6, 0x8d}, + {0xc7, 0xa4}, + {0xc8, 0xb8}, + {0xc9, 0xc9}, + {0xcA, 0xd6}, + {0xcB, 0xe0}, + {0xcC, 0xe8}, + {0xcD, 0xf4}, + {0xcE, 0xFc}, + {0xcF, 0xFF}, + + //////////////////CC/////////////////// + {0xfe, 0x00}, + + {0xb3, 0x44}, + {0xb4, 0xfd}, + {0xb5, 0x02}, + {0xb6, 0xfa}, + {0xb7, 0x48}, + {0xb8, 0xf0}, + + // crop + {0x50, 0x01}, + + ////////////////////YCP//////////////////// + {0xfe, 0x00}, + {0xd1, 0x38}, + {0xd2, 0x38}, + {0xdd, 0x54}, + + ////////////////////AEC//////////////////// + {0xfe, 0x01}, + {0x10, 0x40}, + {0x11, 0x21},//a1 + {0x12, 0x07}, + {0x13, 0x50}, //Y target + {0x17, 0x88}, + {0x21, 0xb0}, + {0x22, 0x48}, + {0x3c, 0x95}, + {0x3d, 0x50}, + {0x3e, 0x48}, + + ////////////////////AWB//////////////////// + {0xfe, 0x01}, + {0x06, 0x16}, + {0x07, 0x06}, + {0x08, 0x98}, + {0x09, 0xee}, + {0x50, 0xfc}, + {0x51, 0x20}, + {0x52, 0x0b}, + {0x53, 0x20}, + {0x54, 0x40}, + {0x55, 0x10}, + {0x56, 0x20}, + //{0x57, 0x40}, + {0x58, 0xa0}, + {0x59, 0x28}, + {0x5a, 0x02}, + {0x5b, 0x63}, + {0x5c, 0x34}, + {0x5d, 0x73}, + {0x5e, 0x11}, + {0x5f, 0x40}, + {0x60, 0x40}, + {0x61, 0xc8}, + {0x62, 0xa0}, + {0x63, 0x40}, + {0x64, 0x50}, + {0x65, 0x98}, + {0x66, 0xfa}, + {0x67, 0x70}, + {0x68, 0x58}, + {0x69, 0x85}, + {0x6a, 0x40}, + {0x6b, 0x39}, + {0x6c, 0x18}, + {0x6d, 0x28}, + {0x6e, 0x41}, + {0x70, 0x02}, + {0x71, 0x00}, + {0x72, 0x10}, + {0x73, 0x40}, + + //{0x74, 0x32}, + //{0x75, 0x40}, + //{0x76, 0x30}, + //{0x77, 0x48}, + //{0x7a, 0x50}, + //{0x7b, 0x20}, + + {0x80, 0x60}, + {0x81, 0x50}, + {0x82, 0x42}, + {0x83, 0x40}, + {0x84, 0x40}, + {0x85, 0x40}, + + {0x74, 0x40}, + {0x75, 0x58}, + {0x76, 0x24}, + {0x77, 0x40}, + {0x78, 0x20}, + {0x79, 0x60}, + {0x7a, 0x58}, + {0x7b, 0x20}, + {0x7c, 0x30}, + {0x7d, 0x35}, + {0x7e, 0x10}, + {0x7f, 0x08}, + + ////////////////////ABS//////////////////// + {0x9c, 0x02}, + {0x9d, 0x20}, + //{0x9f, 0x40}, + + ////////////////////CC-AWB//////////////////// + {0xd0, 0x00}, + {0xd2, 0x2c}, + {0xd3, 0x80}, + + ////////////////////LSC/////////////////// + //// for xuye062d lens setting + {0xfe, 0x01}, + {0xa0, 0x00}, + {0xa1, 0x3c}, + {0xa2, 0x50}, + {0xa3, 0x00}, + {0xa8, 0x0f}, + {0xa9, 0x08}, + {0xaa, 0x00}, + {0xab, 0x04}, + {0xac, 0x00}, + {0xad, 0x07}, + {0xae, 0x0e}, + {0xaf, 0x00}, + {0xb0, 0x00}, + {0xb1, 0x09}, + {0xb2, 0x00}, + {0xb3, 0x00}, + {0xb4, 0x31}, + {0xb5, 0x19}, + {0xb6, 0x24}, + {0xba, 0x3a}, + {0xbb, 0x24}, + {0xbc, 0x2a}, + {0xc0, 0x17}, + {0xc1, 0x13}, + {0xc2, 0x17}, + {0xc6, 0x21}, + {0xc7, 0x1c}, + {0xc8, 0x1c}, + {0xb7, 0x00}, + {0xb8, 0x00}, + {0xb9, 0x00}, + {0xbd, 0x00}, + {0xbe, 0x00}, + {0xbf, 0x00}, + {0xc3, 0x00}, + {0xc4, 0x00}, + {0xc5, 0x00}, + {0xc9, 0x00}, + {0xca, 0x00}, + {0xcb, 0x00}, + {0xa4, 0x00}, + {0xa5, 0x00}, + {0xa6, 0x00}, + {0xa7, 0x00}, + + + {0xfe, 0x00}, + {0x05, 0x00}, + {0x06, 0x6a}, + {0x07, 0x00}, + {0x08, 0x70}, + + {0xfe, 0x01}, + {0x29, 0x00}, + {0x2a, 0x96}, + + {0x2b, 0x02}, + {0x2c, 0x58},//12 fps + {0x2d, 0x02}, + {0x2e, 0x58}, + {0x2f, 0x02},//10 fps + {0x30, 0x58}, + {0x31, 0x07}, + {0x32, 0x08}, + + + + ////////////20120427//////////////// + {0xfe,0x01}, + {0x18,0x22}, + {0x21,0xc0}, + {0x06,0x12}, + {0x08,0x9c}, + {0x51,0x28}, + {0x52,0x10}, + {0x53,0x20}, + {0x54,0x40}, + {0x55,0x16}, + {0x56,0x30}, + {0x58,0x60}, + {0x59,0x08}, + {0x5c,0x35}, + {0x5d,0x72}, + {0x67,0x80}, + {0x68,0x60}, + {0x69,0x90}, + {0x6c,0x30}, + {0x6d,0x60}, + {0x70,0x10}, + + {0xfe,0x00}, + {0x9c,0x0a}, + {0xa0,0xaf}, + {0xa2,0xff}, + {0xa4,0x60}, + {0xa5,0x31}, + {0xa7,0x35}, + {0x42,0xfe}, + {0xd1,0x34}, + {0xd2,0x34}, + {0xfe,0x00}, + + + + + + + + {0xfe, 0x00}, + ////////////////////asde /////////////////// + {0xa0, 0xaf}, + {0xa2, 0xff}, + + {0x44, 0xa2}, // YUV order + {0x00, 0x00}, + +}; +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0x00,0x00} +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0x0, 0x0}, +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + + + {0xfe, 0x00}, + {0x05, 0x00}, + {0x06, 0x6a}, + {0x07, 0x00}, + {0x08, 0x70}, + + {0xfe, 0x01}, + {0x29, 0x00}, + {0x2a, 0x96}, + + {0x2b, 0x02}, + {0x2c, 0x58},//12 fps + {0x2d, 0x02}, + {0x2e, 0x58}, + {0x2f, 0x02},//10 fps + {0x30, 0x58}, + {0x31, 0x07}, + {0x32, 0x08}, + {0xfe, 0x00}, + + {0x00,0x00} +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0x00,0x00} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + {0x00,0x00} +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + {0x00,0x00} +}; + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x00, 0x00} +}; + + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + + {0x77, 0x57}, + {0x78, 0x4d}, + {0x79, 0x45}, + {0x42, 0xfe}, + {0x00, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K [incandesceny]*/ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x42, 0xfd}, + {0x77, 0x40}, + {0x78, 0x58}, + {0x79, 0x5a}, + {0x00, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K [daylight]*/ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x42, 0xfd}, + {0x77, 0x40}, + {0x78, 0x56}, + {0x79, 0x50}, + {0x00, 0x00} +}; + +/* ClearDay Colour Temperature : 5000K - 6500K [fluorescent]*/ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x42, 0xfd}, + {0x77, 0x40}, + {0x78, 0x58}, + {0x79, 0x5a}, + {0x00, 0x00} +}; + +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x42, 0xfd}, + {0x77, 0x7a}, //WB_manual_gain + {0x78, 0x60}, + {0x79, 0x40}, + {0x00, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + + {0xfe, 0x01}, + {0x13, 0x40}, + {0xfe, 0x00}, + {0xd5, 0xe0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + + {0xfe, 0x01}, + {0x13, 0x48}, + {0xfe, 0x00}, + {0xd5, 0xf0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + + + {0xfe, 0x01}, + {0x13, 0x50}, + {0xfe, 0x00}, + {0xd5, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + + {0xfe, 0x01}, + {0x13, 0x58}, + {0xfe, 0x00}, + {0xd5, 0x10}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + + {0xfe, 0x01}, + {0x13, 0x60}, + {0xfe, 0x00}, + {0xd5, 0x20}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + + {0xfe, 0x01}, + {0x13, 0x68}, + {0xfe, 0x00}, + {0xd5, 0x30}, + {0x00, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0xfe, 0x00}, + {0x43, 0x00}, //special_effect + {0x40, 0xff}, //[7:6]gamma + {0x41, 0x22}, //[1]Y_gamma_en + {0x42, 0xff}, //[2]ABS [1]AWB + + {0x95, 0x64}, //Edge effect + {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th + {0x90, 0xbc}, //EEINTP mode 1 + + {0x4f, 0x01}, //AEC_en + {0xd3, 0x40}, //luma_contrast + {0xd4, 0x80}, //contrast_center + {0xd5, 0x00}, //luma_offset + {0xda, 0x00}, //fixed_Cb + {0xdb, 0x00}, //fixed_Cr + + {0xbf, 0x0e}, //RGB gamma + {0xc0, 0x1c}, + {0xc1, 0x34}, + {0xc2, 0x48}, + {0xc3, 0x5a}, + {0xc4, 0x6b}, + {0xc5, 0x7b}, + {0xc6, 0x95}, + {0xc7, 0xab}, + {0xc8, 0xbf}, + {0xc9, 0xce}, + {0xca, 0xd9}, + {0xcb, 0xe4}, + {0xcc, 0xec}, + {0xcd, 0xf7}, + {0xce, 0xfd}, + {0xcf, 0xff}, + + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0xfe, 0x00}, + {0x43, 0x02}, //special_effect + {0x40, 0xff}, //[7:6]gamma + {0x41, 0x22}, //[1]Y_gamma_en + {0x42, 0xff}, //[2]ABS [1]AWB + + {0x95, 0x64}, //Edge effect + {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th + {0x90, 0xbc}, //EEINTP mode 1 + + {0x4f, 0x01}, //AEC_en + {0xd3, 0x40}, //luma_contrast + {0xd4, 0x80}, //contrast_center + {0xd5, 0x00}, //luma_offset + {0xda, 0x00}, //fixed_Cb + {0xdb, 0x00}, //fixed_Cr + + {0xbf, 0x0e}, //RGB gamma + {0xc0, 0x1c}, + {0xc1, 0x34}, + {0xc2, 0x48}, + {0xc3, 0x5a}, + {0xc4, 0x6b}, + {0xc5, 0x7b}, + {0xc6, 0x95}, + {0xc7, 0xab}, + {0xc8, 0xbf}, + {0xc9, 0xce}, + {0xca, 0xd9}, + {0xcb, 0xe4}, + {0xcc, 0xec}, + {0xcd, 0xf7}, + {0xce, 0xfd}, + {0xcf, 0xff}, + + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + + {0xfe, 0x00}, + {0x43, 0x02}, //special_effect + {0x40, 0xff}, //[7:6]gamma + {0x41, 0x22}, //[1]Y_gamma_en + {0x42, 0xff}, //[2]ABS [1]AWB + + {0x95, 0x64}, //Edge effect + {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th + {0x90, 0xbc}, //EEINTP mode 1 + + {0x4f, 0x01}, //AEC_en + {0xd3, 0x40}, //luma_contrast + {0xd4, 0x80}, //contrast_center + {0xd5, 0x00}, //luma_offset + {0xda, 0xd0}, //fixed_Cb + {0xdb, 0x28}, //fixed_Cr + + {0xbf, 0x0e}, //RGB gamma + {0xc0, 0x1c}, + {0xc1, 0x34}, + {0xc2, 0x48}, + {0xc3, 0x5a}, + {0xc4, 0x6b}, + {0xc5, 0x7b}, + {0xc6, 0x95}, + {0xc7, 0xab}, + {0xc8, 0xbf}, + {0xc9, 0xce}, + {0xca, 0xd9}, + {0xcb, 0xe4}, + {0xcc, 0xec}, + {0xcd, 0xf7}, + {0xce, 0xfd}, + {0xcf, 0xff}, + {0x00,0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + {0xfe, 0x00}, + {0x43, 0x01}, //special_effect + {0x40, 0xff}, //[7:6]gamma + {0x41, 0x22}, //[1]Y_gamma_en + {0x42, 0xff}, //[2]ABS [1]AWB + + {0x95, 0x64}, //Edge effect + {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th + {0x90, 0xbc}, //EEINTP mode 1 + + {0x4f, 0x01}, //AEC_en + {0xd3, 0x40}, //luma_contrast + {0xd4, 0x80}, //contrast_center + {0xd5, 0x00}, //luma_offset + {0xda, 0x00}, //fixed_Cb + {0xdb, 0x00}, //fixed_Cr + + {0xbf, 0x0e}, //RGB gamma + {0xc0, 0x1c}, + {0xc1, 0x34}, + {0xc2, 0x48}, + {0xc3, 0x5a}, + {0xc4, 0x6b}, + {0xc5, 0x7b}, + {0xc6, 0x95}, + {0xc7, 0xab}, + {0xc8, 0xbf}, + {0xc9, 0xce}, + {0xca, 0xd9}, + {0xcb, 0xe4}, + {0xcc, 0xec}, + {0xcd, 0xf7}, + {0xce, 0xfd}, + {0xcf, 0xff}, + + {0x00,0x00} +}; + +//SOLARIZE +static struct reginfo sensor_Effect_Bluish[] = +{ + {0xfe, 0x00}, + {0x43, 0x00}, //special_effect + {0x40, 0xff}, //[7:6]gamma + {0x41, 0x22}, //[1]Y_gamma_en + {0x42, 0xff}, //[2]ABS [1]AWB + + {0x95, 0x64}, //Edge effect + {0x96, 0x82}, //[7:4] edge_max [3:0] edge_th + {0x90, 0xbc}, //EEINTP mode 1 + + {0x4f, 0x01}, //AEC_en + {0xd3, 0x40}, //luma_contrast + {0xd4, 0x80}, //contrast_center + {0xd5, 0x00}, //luma_offset + {0xda, 0x00}, //fixed_Cb + {0xdb, 0x00}, //fixed_Cr + + {0xbf, 0x10}, //RGB gamma + {0xc0, 0x20}, + {0xc1, 0x38}, + {0xc2, 0x4e}, + {0xc3, 0x63}, + {0xc4, 0x76}, + {0xc5, 0x87}, + {0xc6, 0xa2}, + {0xc7, 0xb4}, + {0xc8, 0xa8}, + {0xc9, 0x91}, + {0xca, 0x7b}, + {0xcb, 0x66}, + {0xcc, 0x4f}, + {0xcd, 0x39}, + {0xce, 0x24}, + {0xcf, 0x12}, + + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + //Greenish + {0x43,0x02}, + {0xda,0xc0}, + {0xdb,0xc0}, + {0x00,0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + + {0x00, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + {0xb3,0x50}, + {0x00, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + + {0x00, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + {0xfe, 0x01}, + {0x33, 0x20}, + {0xfe, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_SceneNight[] = +{ + {0xfe, 0x01}, + {0x33, 0x30}, + {0xfe, 0x00}, + {0x00, 0x00} +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif + +#if CONFIG_SENSOR_AntiBanding +static struct reginfo sensor_AntiBanding_50HZ[] = +{ + +{0xfe, 0x00}, + {0x05, 0x00}, + {0x06, 0x6a}, + {0x07, 0x00}, + {0x08, 0x70}, + + {0xfe, 0x01}, + {0x29, 0x00}, + {0x2a, 0x96}, + + {0x2b, 0x02}, + {0x2c, 0x58},//12 fps + {0x2d, 0x02}, + {0x2e, 0x58}, + {0x2f, 0x02},//10 fps + {0x30, 0x58}, + {0x31, 0x07}, + {0x32, 0x08}, + + +{0xfe, 0x00}, + + {0x00, 0x00} +}; + +static struct reginfo sensor_AntiBanding_60HZ[] = +{ + {0xfe, 0x00}, + {0x05, 0x00}, + {0x06, 0x6a}, + {0x07, 0x00}, + {0x08, 0x89}, + + {0xfe, 0x01}, + {0x29, 0x00}, + {0x2a, 0x7d}, + + {0x2b, 0x02}, + {0x2c, 0x71},//12 fps + {0x2d, 0x02}, + {0x2e, 0x71}, + {0x2f, 0x02},//10 fps + {0x30, 0x71}, + {0x31, 0x04}, + {0x32, 0xe2}, + + +{0xfe, 0x00}, + + + {0x00, 0x00} +}; +static struct reginfo *sensor_AntibandingSeqe[] = {sensor_AntiBanding_50HZ, sensor_AntiBanding_60HZ,NULL,}; +#endif + +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,}, //{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,} , + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_AntiBanding + { .id = V4L2_CID_ANTIBANDING, .index = 0, .name = "50hz", .reserved = 0,} ,{ .id = V4L2_CID_ANTIBANDING, .index = 1, .name = "60hz", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static const struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_AntiBanding + { + .id = V4L2_CID_ANTIBANDING, + .type = V4L2_CTRL_TYPE_MENU, + .name = "antibanding Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + //{V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int antibanding; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg & 0xFF; + buf[1] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + //u8 buf[2]; + u8 buf[1]; + struct i2c_msg msg[2]; + + //buf[0] = reg >> 8; + buf[0] = reg; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 1; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK + + +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int ret; + int i = 0; + + u8 value; + + for(i=0;ipowerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + int ret; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); */ //delay 5 microseconds + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + #if CONFIG_SENSOR_AntiBanding + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ANTIBANDING); + if (qctrl) + sensor->info_priv.antibanding = qctrl->default_value; + #endif + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + //u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(10); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +/* +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +*/ +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); +// const struct v4l2_queryctrl *qctrl; +// struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } + else + { /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +#if CONFIG_SENSOR_AntiBanding +static int sensor_set_antibanding(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_AntibandingSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_AntibandingSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + #if CONFIG_SENSOR_AntiBanding + case V4L2_CID_ANTIBANDING: + { + ext_ctrl->value = sensor->info_priv.antibanding; + break; + } + #endif + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_AntiBanding + case V4L2_CID_ANTIBANDING: + { + if (ext_ctrl->value != sensor->info_priv.antibanding) + { + if (sensor_set_antibanding(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.antibanding = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char pid = 0; + int ret; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + SENSOR_TR("power down %s failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(50); *///delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_write(client, 0xfc, 0x16); //before read id should write 0xfc + msleep(20); + ret = sensor_read(client, 0x00, &pid); + if (ret != 0) { + SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK29_CAM_SUPPORT_NUMS;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK29_CAM_SUPPORT_NUMS){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } + + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} + +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/gc2015.c b/drivers/media/video/gc2015.c index 1c3101fd0466..5bbb99349418 100755 --- a/drivers/media/video/gc2015.c +++ b/drivers/media/video/gc2015.c @@ -1,3095 +1,1097 @@ + +#include "generic_sensor.h" /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GC2015 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015 -#define SENSOR_ID 0x2005 -#define SENSOR_MIN_WIDTH 640 -#define SENSOR_MIN_HEIGHT 480 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800//1024 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600//768 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -struct reginfo -{ - u8 reg; - u8 val; -}; - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_GC2015_USER_DEFINED_SERIES -#include "gc2015_user_series.c" -#else -/* init SVGA preview */ -static struct reginfo sensor_init_data[] = - -{ - {0xfe, 0x80}, //soft reset - {0xfe, 0x80}, //soft reset - {0xfe, 0x80}, //soft reset - - {0xfe, 0x00}, //page0 - {0x45, 0x00}, //output_disable - - ////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////preview capture switch ///////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////// - //preview - {0x02, 0x01}, //preview mode - {0x2a, 0xca}, //[7]col_binning, 0x[6]even skip - {0x48, 0x40}, //manual_gain - - //////////////////////////////////////////////////////////////////////// - ////////////////////////// preview LSC ///////////////////////////////// - //////////////////////////////////////////////////////////////////////// - {0xfe, 0x01}, //page1 - {0xb0, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select - {0xb1, 0x46}, //P_LSC_red_b2 - {0xb2, 0x40}, //P_LSC_green_b2 - {0xb3, 0x40}, //P_LSC_blue_b2 - {0xb4, 0x24}, //P_LSC_red_b4 - {0xb5, 0x20}, //P_LSC_green_b4 - {0xb6, 0x22}, //P_LSC_blue_b4 - {0xb7, 0x00}, //P_LSC_compensate_b2 - {0xb8, 0x80}, //P_LSC_row_center, 0x344, 0x (1200/2-344)/2=128, 0x, 0x - {0xb9, 0x80}, //P_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 - - - //////////////////////////////////////////////////////////////////////// - ////////////////////////// capture LSC ///////////////////////////////// - //////////////////////////////////////////////////////////////////////// - {0xba, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select - {0xbb, 0x46}, //C_LSC_red_b2 - {0xbc, 0x40}, //C_LSC_green_b2 - {0xbd, 0x40}, //C_LSC_blue_b2 - {0xbe, 0x24}, //C_LSC_red_b4 - {0xbf, 0x20}, //C_LSC_green_b4 - {0xc0, 0x22}, //C_LSC_blue_b4 - {0xc1, 0x00}, //C_Lsc_compensate_b2 - {0xc2, 0x80}, //C_LSC_row_center, 0x344, 0x (1200/2-344)/2=128 - {0xc3, 0x80}, //C_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 - {0xfe, 0x00}, //page0 - - //////////////////////////////////////////////////////////////////////// - ////////////////////////// analog configure /////////////////////////// - //////////////////////////////////////////////////////////////////////// - {0xfe, 0x00}, //page0 - {0x29, 0x00}, //cisctl mode 1 - {0x2b, 0x06}, //cisctl mode 3 - {0x32, 0x1c}, //analog mode 1 - {0x33, 0x0f}, //analog mode 2 - {0x34, 0x30}, //[6:4]da_rsg - - {0x35, 0x88}, //Vref_A25 - {0x37, 0x16}, //Drive Current - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// ISP Related ///////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0x40, 0xff}, - {0x41, 0x20}, //[5]skin_detectionenable[2]auto_gray, 0x[1]y_gamma - {0x42, 0xf6}, //[7]auto_sa[6]auto_ee[5]auto_dndd[4]auto_lsc[3]na[2]abs, 0x[1]awb - {0x4b, 0xe8}, //[1]AWB_gain_mode, 0x1:atpregain0:atpostgain - {0x4d, 0x03}, //[1]inbf_en - {0x4f, 0x01}, //AEC enable - - //////////////////////////////////////////////////////////////////// - /////////////////////////// BLK ////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x63, 0x77}, //BLK mode 1 - {0x66, 0x00}, //BLK global offset - {0x6d, 0x00}, - {0x6e, 0x1a}, //BLK offset submode,offset R - {0x6f, 0x20}, - {0x70, 0x1a}, - {0x71, 0x20}, - {0x73, 0x00}, - {0x77, 0x80}, - {0x78, 0x80}, - {0x79, 0x90}, - - //////////////////////////////////////////////////////////////////// - /////////////////////////// DNDD /////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x80, 0x07}, //[7]dn_inc_or_dec [4]zero_weight_mode[3]share [2]c_weight_adap [1]dn_lsc_mode [0]dn_b - {0x82, 0x0c}, //DN lilat b base - {0x83, 0x03}, - - //////////////////////////////////////////////////////////////////// - /////////////////////////// EEINTP //////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x8a, 0x7c}, - {0x8c, 0x02}, - {0x8e, 0x02}, - {0x8f, 0x45}, - - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// CC_t //////////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0xb0, 0x40}, // 0x48 - {0xb1, 0xfe}, - {0xb2, 0x00}, - {0xb3, 0xf0}, - {0xb4, 0x50}, - {0xb5, 0xf8}, - {0xb6, 0x00}, - {0xb7, 0x00}, - {0xb8, 0x00}, - - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// GAMMA /////////////////////////////////// - ///////////////////////////////////////////////////////////////////// - //RGB_GAMMA - {0xbf, 0x08}, - {0xc0, 0x1e}, - {0xc1, 0x33}, - {0xc2, 0x47}, - {0xc3, 0x59}, - {0xc4, 0x68}, - {0xc5, 0x74}, - {0xc6, 0x86}, - {0xc7, 0x97}, - {0xc8, 0xA5}, - {0xc9, 0xB1}, - {0xca, 0xBd}, - {0xcb, 0xC8}, - {0xcc, 0xD3}, - {0xcd, 0xE4}, - {0xce, 0xF4}, - {0xcf, 0xff}, - - /*{0xbf, 0x06}, - {0xc0, 0x1f}, - {0xc1, 0x38}, - {0xc2, 0x4c}, - {0xc3, 0x5b}, - {0xc4, 0x6b}, - {0xc5, 0x76}, - {0xc6, 0x8b}, - {0xc7, 0x9b}, - {0xc8, 0xac}, - {0xc9, 0xbb}, - {0xca, 0xc7}, - {0xcb, 0xd2}, - {0xcc, 0xdb}, - {0xcd, 0xea}, - {0xce, 0xf5}, - {0xcf, 0xff}, */ - - ///////////////////////////////////////////////////////////////////// - /////////////////////////// YCP_t /////////////////////////////////// - ///////////////////////////////////////////////////////////////////// - {0xd1, 0x40}, //saturation 38 - {0xd2, 0x40}, //saturation 38 - - {0xd3, 0x46}, // 2011-08-11 kim add - - {0xde, 0x21}, //auto_gray - - //////////////////////////////////////////////////////////////////// - /////////////////////////// ASDE /////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x98, 0x3a}, - {0x99, 0x60}, - {0x9b, 0x00}, - {0x9f, 0x12}, - {0xa1, 0x80}, - {0xa2, 0x21}, - - {0xfe, 0x01}, //page1 - {0xc5, 0x10}, - {0xc6, 0xff}, - {0xc7, 0xff}, - {0xc8, 0xff}, - - //////////////////////////////////////////////////////////////////// - /////////////////////////// AEC //////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x10, 0x09}, //AEC mode 1 - {0x11, 0x92}, //[7]fix target // 0xb2 2011-08-11 kim - {0x12, 0x20}, - {0x13, 0x78}, // 0x78 2011-08-11 kim - {0x17, 0x00}, - {0x1c, 0x96}, - {0x1d, 0x04}, // sunlight step - {0x1e, 0x11}, - {0x21, 0xc0}, //max_post_gain - {0x22, 0x40}, //max_pre_gain // 0x60 2011-08-11 kim - {0x2d, 0x06}, //P_N_AEC_exp_level_1[12:8] - {0x2e, 0x00}, //P_N_AEC_exp_level_1[7:0] - {0x1e, 0x32}, - {0x33, 0x00}, //[6:5]max_exp_level [4:0]min_exp_level - {0x34, 0x04}, // min exp - - //////////////////////////////////////////////////////////////////// - /////////////////////////// Measure Window ///////////////////////// - //////////////////////////////////////////////////////////////////// - {0x06, 0x07}, - {0x07, 0x03}, - {0x08, 0x64}, - {0x09, 0x4a}, - - //////////////////////////////////////////////////////////////////// - /////////////////////////// AWB //////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x57, 0x40}, //number limit - {0x5d, 0x44}, // - {0x5c, 0x35}, //show mode,close dark_mode - {0x5e, 0x29}, //close color temp - {0x5f, 0x50}, - {0x60, 0x50}, - {0x65, 0xc0}, - //////////////////////////////////////////////////////////////////// - /////////////////////////// ABS //////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0x80, 0x82}, - {0x81, 0x00}, - - {0x82, 0x03}, /// - - {0x83, 0x10}, //ABS Y stretch limit - {0xfe, 0x00}, - //////////////////////////////////////////////////////////////////// - /////////////////////////// OUT //////////////////////////////////// - //////////////////////////////////////////////////////////////////// - {0xfe, 0x00}, - //crop - {0x50, 0x01}, - {0x51, 0x00}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x02}, - {0x56, 0x58}, - {0x57, 0x03}, - {0x58, 0x20}, - - {0x44, 0xa0}, //YUV sequence - {0x45, 0x0f}, //output enable - {0x46, 0x02}, //sync mode - -/* {0xbF, 0x0B}, - {0xc0, 0x16}, - {0xc1, 0x29}, - {0xc2, 0x3C}, - {0xc3, 0x4F}, - {0xc4, 0x5F}, - {0xc5, 0x6F}, - {0xc6, 0x8A}, - {0xc7, 0x9F}, - {0xc8, 0xB4}, - {0xc9, 0xC6}, - {0xcA, 0xD3}, - {0xcB, 0xDD}, - {0xcC, 0xE5}, - {0xcD, 0xF1}, - {0xcE, 0xFA}, - {0xcF, 0xFF},*/ - - {0x05, 0x01},//HB - {0x06, 0xc1}, - {0x07, 0x00},//VB - {0x08, 0x40}, - - {0xfe, 0x01}, - {0x29, 0x00},//Anti Step 128 - {0x2a, 0x80}, - - {0x2b, 0x05},//Level_0 10.00fps - {0x2c, 0x00}, - {0x2d, 0x06},//Level_1 8.33fps - {0x2e, 0x00}, - {0x2f, 0x08},//Level_2 6.25fps - {0x30, 0x00}, - {0x31, 0x09},//Level_3 5.55fps - {0x32, 0x00}, - {0x33, 0x20}, - {0xfe, 0x00}, - -//--------------------Updated By Mormo 2011/08/08 Start --------------------// - {0xfe, 0x00}, - {0x32, 0x34}, - {0x34, 0x00}, -//--------------------Updated By Mormo 2011/08/08 End ---------------------// - {0x7d, 0x80}, // - {0x7e, 0x80}, - {0x7f, 0x84}, - - {0x0,0x0} - -}; - -/* 1600X1200 UXGA capture */ -static struct reginfo sensor_uxga[] = -{ - {0xfe, 0x00}, - - {0x48, 0x80}, // 68 - - {0x4f, 0x00}, // aec off - - {0x02, 0x00}, - {0x2a, 0x0a}, - - //subsample 1/1 - {0x59, 0x11}, - {0x5a, 0x06}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e , 0x00}, - {0x5f, 0x00}, - {0x60, 0x00}, - {0x61, 0x00}, - {0x62, 0x00}, - - //crop - {0x50, 0x01}, - {0x51, 0x00}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x04}, - {0x56, 0xb0}, - {0x57, 0x06}, - {0x58, 0x40}, - {0x0,0x0} -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0xfe, 0x00}, - - {0x48, 0x80}, // 68 - - {0x4f, 0x00}, // aec off - - {0x02, 0x00}, - {0x2a, 0x0a}, - - //subsample 1/1 - {0x59, 0x11}, - {0x5a, 0x06}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e , 0x00}, - {0x5f, 0x00}, - {0x60, 0x00}, - {0x61, 0x00}, - {0x62, 0x00}, - - //crop - {0x50, 0x01}, - {0x51, 0x00}, - {0x52, 0x00}, - {0x53, 0x00}, - {0x54, 0x00}, - {0x55, 0x04}, - {0x56, 0x00}, - {0x57, 0x05}, - {0x58, 0x00}, - {0x0, 0x0} -}; -/*1024*768*/ -static struct reginfo sensor_xga[] = -{ - {0xfe, 0x00}, - - {0x48, 0x80}, // 68 - - {0x4f, 0x00}, // aec off - - {0x02, 0x00}, - {0x2a, 0x0a}, - //subsample 1600x1200 to 1066x800 - {0x59 , 0x33},//out window - {0x5a , 0x06}, - {0x5b , 0x00}, - {0x5c , 0x00}, - {0x5d , 0x00}, - {0x5e , 0x01}, - {0x5f , 0x00}, - {0x60 , 0x00}, - {0x61 , 0x00}, - {0x62 , 0x01}, - - {0x50 , 0x01},//out window - {0x51 , 0x00}, - {0x52 , 0x10}, - {0x53 , 0x00}, - {0x54 , 0x14}, - {0x55 , 0x03}, - {0x56 , 0x00},// 768 - {0x57 , 0x04}, - {0x58 , 0x00},//1024 - {0x0, 0x0} -}; -/* 800X600 SVGA,30fps*/ -static struct reginfo sensor_svga[] = -{ - {0xfe, 0x00}, - - {0x48, 0x40}, - {0x4f, 0x01}, // aec on - - {0x02, 0x01}, - {0x2a, 0xca}, - - //subsample 1/1 - {0x59, 0x11}, - {0x5a, 0x06}, - {0x5b, 0x00}, - {0x5c, 0x00}, - {0x5d, 0x00}, - {0x5e , 0x00}, - {0x5f, 0x00}, - {0x60, 0x00}, - {0x61, 0x00}, - {0x62, 0x00}, - - {0x50 , 0x01},//out window - {0x51 , 0x00}, - {0x52 , 0x00}, - {0x53 , 0x00}, - {0x54 , 0x00}, - {0x55 , 0x02}, - {0x56 , 0x58},// 600 - {0x57 , 0x03}, - {0x58 , 0x20},//800 - {0x0,0x0} -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - - - {0xfe, 0x00}, - - {0x48, 0x40}, - {0x4f, 0x01}, // aec on - - {0x02, 0x01}, - {0x2a, 0xca}, - //subsample 4/5 - - {0x59 , 0x55},//out window - {0x5a , 0x06}, - {0x5b , 0x00}, - {0x5c , 0x00}, - {0x5d , 0x01}, - {0x5e , 0x23}, - {0x5f , 0x00}, - {0x60 , 0x00}, - {0x61 , 0x01}, - {0x62 , 0x23}, - - {0x50 , 0x01},//out window - {0x51 , 0x00}, - {0x52 , 0x00}, - {0x53 , 0x00}, - {0x54 , 0x00}, - {0x55 , 0x01}, - {0x56 , 0xe0},// 480 - {0x57 , 0x02}, - {0x58 , 0x80},//640 - {0x45 , 0x0f}, //output enable - {0x0,0x0} -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{}; -#endif -#if 0 -/* 160X120 QQVGA*/ -static struct reginfo ov2655_qqvga[] = -{ - {0x00, 0x00}, -}; - - - -static struct reginfo ov2655_Sharpness_auto[] = -{ - - {0x00, 0x00}, -}; - -static struct reginfo ov2655_Sharpness1[] = -{ - - {0x00, 0x00}, -}; - -static struct reginfo ov2655_Sharpness2[][3] = -{ - //Sharpness 2 - - {0x00, 0x00}, -}; - -static struct reginfo ov2655_Sharpness3[] = -{ - //default - - {0x00, 0x00}, -}; -static struct reginfo ov2655_Sharpness4[]= -{ - //Sharpness 4 - - {0x00, 0x00}, -}; - -static struct reginfo ov2655_Sharpness5[] = -{ - //Sharpness 5 - - {0x00, 0x00}, -}; -#endif - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - - {0x00, 0x00} -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x42,0x76}, - {0x00, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - - {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF - {0x7a , 0x8c}, //AWB_R_gain - {0x7b , 0x50}, //AWB_G_gain - {0x7c , 0x40}, //AWB_B_gain - {0x00, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF - {0x7a , 0x74}, //AWB_R_gain - {0x7b , 0x52}, //AWB_G_gain - {0x7c , 0x40}, //AWB_B_gain - {0x00, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF - {0x7a , 0x48}, //AWB_R_gain - {0x7b , 0x40}, //AWB_G_gain - {0x7c , 0x5c}, //AWB_B_gain - {0x00, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF - {0x7a , 0x40}, //AWB_R_gain - {0x7b , 0x54}, //AWB_G_gain - {0x7c , 0x70}, //AWB_B_gain - {0x00, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - - {0xfe, 0x01}, - {0x13, 0x68}, //AEC_target_Y - {0xfe, 0x00}, - {0xd5, 0xe0},// Luma_offset - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - {0xfe, 0x01}, - {0x13, 0x70}, //AEC_target_Y - {0xfe, 0x00}, - {0xd5, 0xf0},// Luma_offset - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - - {0xfe, 0x01}, - {0x13, 0x78}, //AEC_target_Y 48 - {0xfe, 0x00}, - {0xd5, 0x00},// Luma_offset c0 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - {0xfe, 0x01}, - {0x13, 0x80}, //AEC_target_Y - {0xfe, 0x00}, - {0xd5, 0x10},// Luma_offset - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - {0xfe, 0x01}, - {0x13, 0x88}, //AEC_target_Y - {0xfe, 0x00}, - {0xd5, 0x20},// Luma_offset - - {0x00, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - {0xfe, 0x01}, - {0x13, 0x90}, //AEC_target_Y - {0xfe, 0x00}, - {0xd5, 0x30},// Luma_offset - {0x00, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - - {0x43, 0x00}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x43, 0x02}, - {0xda, 0x50}, - {0xdb, 0xe0}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x43, 0x02}, - {0xda, 0xd0}, - {0xdb, 0x28}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x43, 0x01}, - //{0xda, 0xc0}, - //{0xdb, 0xc0}, - {0x00, 0x00} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x43, 0x02}, - {0xda, 0x00}, - {0xdb, 0x00}, - - {0x00, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x43, 0x02}, - {0xda, 0xc0}, - {0xdb, 0xc0}, - {0x00, 0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - //-3 - -}; - -static struct reginfo sensor_Exposure1[]= -{ - //-2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - //-0.3EV - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - //default - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - // 1 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - // 2 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - // 3 - - {0x00, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - - {0x00, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - - {0x00, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - //Contrast -3 - {0xfe, 0x00}, - {0xd3, 0x2c}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - //Contrast -2 - {0xfe, 0x00}, - {0xd3, 0x30}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - // Contrast -1 - {0xfe, 0x00}, - {0xd3, 0x38}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - //Contrast 0 - {0xfe, 0x00}, - {0xd3, 0x40}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - //Contrast +1 - {0xfe, 0x00}, - {0xd3, 0x48}, - {0x00, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - //Contrast +2 - {0xfe, 0x00}, - {0xd3, 0x50}, - {0x00, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - //Contrast +3 - {0xfe, 0x00}, - {0xd3, 0x58}, - {0x00, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0x29 , 0x01}, - {0x00, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0x29 , 0x01}, - {0x00, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x29 , 0x02}, - {0x00, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x29 , 0x00}, - {0x00, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - /* ddl@rock-chips.com : */ - {0xfe, 0x01}, - {0x33, 0x00}, - {0xfe, 0x00}, - - {0x00, 0x00} - -}; - -static struct reginfo sensor_SceneNight[] = -{ - - //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk - {0xfe, 0x01}, - {0x33, 0x20}, - {0xfe, 0x00}, - {0x00, 0x00} - -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); -static int sensor_write(struct i2c_client *client, u8 reg, u8 val); -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val); - - -static u16 GC2015_read_shutter(struct i2c_client *client); // add 2011-08-11 kim -static void GC2015_set_shutter(struct i2c_client *client, u16 shutter); // add 2011-08-11 kim - - -////// add 2011-08-11 kim -static u16 GC2015_read_shutter(struct i2c_client *client) -{ - u8 temp_reg1, temp_reg2; - u16 shutter; - - /* Backup the preview mode last shutter & sensor gain. */ - sensor_read(client, 0x03, &temp_reg1); - sensor_read(client, 0x04, &temp_reg2); - - shutter = (temp_reg1 << 8) | (temp_reg2 & 0xFF); - - return shutter; -} /* GC2015_read_shutter */ - -static void GC2015_set_shutter(struct i2c_client *client, u16 shutter) -{ - u16 temp_reg; - - temp_reg = shutter * 10 / 20; //// - - /*Set Shutter start*/ - if(temp_reg < 1) temp_reg = 1; - sensor_write(client ,0x03 , (temp_reg>>8)&0xff); - sensor_write(client ,0x04 , temp_reg&0xff); - /*Set Shutter end*/ -} -//////// end add kim - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -#if 0 -/* sensor register */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int ret = 0; - - ret = i2c_master_reg8_recv(client, reg, val, 1, CONFIG_SENSOR_I2C_SPEED); - - return (ret > 0)? 0 : ret; -} - -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int ret = 0; - - ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED); - - return (ret > 0)? 0 : ret; -} -#else -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg; - buf[1] = val; - - if (reg == 0xfe) - mdelay(20); - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - u8 buf[1]; - struct i2c_msg msg[2]; - - buf[0] = reg ; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -#endif - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; - #if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; - #endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - //mdelay(5); - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; -} -#endif -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - ret = sensor_write(client, 0xfe, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); //delay 5 microseconds - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x01, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - u32 gc2015_shutter; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800-32; - set_h = 600; - } - else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) - { - gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim - - winseqe_set_addr = sensor_xga; - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim - - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - - gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim - - winseqe_set_addr = sensor_uxga; - set_w = 1600-32; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - - if(set_w >= 1024) GC2015_set_shutter(client, gc2015_shutter); // add 2011-08-11 kim - - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800-32; - set_h = 600; - } - else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) - { - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - set_w = 1600-32; - set_h = 1200; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid=0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - ret = sensor_write(client, 0xfe, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x00, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x01, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GC2015 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015 +#define SENSOR_ID 0x2005 +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + u16 shutter; + +}; + +/* +* 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[] ={ + {0xfe, 0x80}, //soft reset + {0xfe, 0x80}, //soft reset + {0xfe, 0x80}, //soft reset + + {0xfe, 0x00}, //page0 + {0x45, 0x00}, //output_disable + + ////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////preview capture switch ///////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + //preview + {0x02, 0x01}, //preview mode + {0x2a, 0xca}, //[7]col_binning, 0x[6]even skip + {0x48, 0x40}, //manual_gain + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// preview LSC ///////////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xfe, 0x01}, //page1 + {0xb0, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select + {0xb1, 0x46}, //P_LSC_red_b2 + {0xb2, 0x40}, //P_LSC_green_b2 + {0xb3, 0x40}, //P_LSC_blue_b2 + {0xb4, 0x24}, //P_LSC_red_b4 + {0xb5, 0x20}, //P_LSC_green_b4 + {0xb6, 0x22}, //P_LSC_blue_b4 + {0xb7, 0x00}, //P_LSC_compensate_b2 + {0xb8, 0x80}, //P_LSC_row_center, 0x344, 0x (1200/2-344)/2=128, 0x, 0x + {0xb9, 0x80}, //P_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 + + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// capture LSC ///////////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xba, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select + {0xbb, 0x46}, //C_LSC_red_b2 + {0xbc, 0x40}, //C_LSC_green_b2 + {0xbd, 0x40}, //C_LSC_blue_b2 + {0xbe, 0x24}, //C_LSC_red_b4 + {0xbf, 0x20}, //C_LSC_green_b4 + {0xc0, 0x22}, //C_LSC_blue_b4 + {0xc1, 0x00}, //C_Lsc_compensate_b2 + {0xc2, 0x80}, //C_LSC_row_center, 0x344, 0x (1200/2-344)/2=128 + {0xc3, 0x80}, //C_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 + {0xfe, 0x00}, //page0 + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// analog configure /////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xfe, 0x00}, //page0 + {0x29, 0x00}, //cisctl mode 1 + {0x2b, 0x06}, //cisctl mode 3 + {0x32, 0x1c}, //analog mode 1 + {0x33, 0x0f}, //analog mode 2 + {0x34, 0x30}, //[6:4]da_rsg + + {0x35, 0x88}, //Vref_A25 + {0x37, 0x16}, //Drive Current + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// ISP Related ///////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x40, 0xff}, + {0x41, 0x20}, //[5]skin_detectionenable[2]auto_gray, 0x[1]y_gamma + {0x42, 0xf6}, //[7]auto_sa[6]auto_ee[5]auto_dndd[4]auto_lsc[3]na[2]abs, 0x[1]awb + {0x4b, 0xe8}, //[1]AWB_gain_mode, 0x1:atpregain0:atpostgain + {0x4d, 0x03}, //[1]inbf_en + {0x4f, 0x01}, //AEC enable + + //////////////////////////////////////////////////////////////////// + /////////////////////////// BLK ////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x63, 0x77}, //BLK mode 1 + {0x66, 0x00}, //BLK global offset + {0x6d, 0x00}, + {0x6e, 0x1a}, //BLK offset submode,offset R + {0x6f, 0x20}, + {0x70, 0x1a}, + {0x71, 0x20}, + {0x73, 0x00}, + {0x77, 0x80}, + {0x78, 0x80}, + {0x79, 0x90}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD /////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x80, 0x07}, //[7]dn_inc_or_dec [4]zero_weight_mode[3]share [2]c_weight_adap [1]dn_lsc_mode [0]dn_b + {0x82, 0x0c}, //DN lilat b base + {0x83, 0x03}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// EEINTP //////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x8a, 0x7c}, + {0x8c, 0x02}, + {0x8e, 0x02}, + {0x8f, 0x45}, + + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// CC_t //////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xb0, 0x40}, // 0x48 + {0xb1, 0xfe}, + {0xb2, 0x00}, + {0xb3, 0xf0}, + {0xb4, 0x50}, + {0xb5, 0xf8}, + {0xb6, 0x00}, + {0xb7, 0x00}, + {0xb8, 0x00}, + + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// GAMMA /////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + //RGB_GAMMA + {0xbf, 0x08}, + {0xc0, 0x1e}, + {0xc1, 0x33}, + {0xc2, 0x47}, + {0xc3, 0x59}, + {0xc4, 0x68}, + {0xc5, 0x74}, + {0xc6, 0x86}, + {0xc7, 0x97}, + {0xc8, 0xA5}, + {0xc9, 0xB1}, + {0xca, 0xBd}, + {0xcb, 0xC8}, + {0xcc, 0xD3}, + {0xcd, 0xE4}, + {0xce, 0xF4}, + {0xcf, 0xff}, + + /*{0xbf, 0x06}, + {0xc0, 0x1f}, + {0xc1, 0x38}, + {0xc2, 0x4c}, + {0xc3, 0x5b}, + {0xc4, 0x6b}, + {0xc5, 0x76}, + {0xc6, 0x8b}, + {0xc7, 0x9b}, + {0xc8, 0xac}, + {0xc9, 0xbb}, + {0xca, 0xc7}, + {0xcb, 0xd2}, + {0xcc, 0xdb}, + {0xcd, 0xea}, + {0xce, 0xf5}, + {0xcf, 0xff}, */ + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// YCP_t /////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xd1, 0x40}, //saturation 38 + {0xd2, 0x40}, //saturation 38 + + {0xd3, 0x46}, // 2011-08-11 kim add + + {0xde, 0x21}, //auto_gray + + //////////////////////////////////////////////////////////////////// + /////////////////////////// ASDE /////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x98, 0x3a}, + {0x99, 0x60}, + {0x9b, 0x00}, + {0x9f, 0x12}, + {0xa1, 0x80}, + {0xa2, 0x21}, + + {0xfe, 0x01}, //page1 + {0xc5, 0x10}, + {0xc6, 0xff}, + {0xc7, 0xff}, + {0xc8, 0xff}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// AEC //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x10, 0x09}, //AEC mode 1 + {0x11, 0x92}, //[7]fix target // 0xb2 2011-08-11 kim + {0x12, 0x20}, + {0x13, 0x78}, // 0x78 2011-08-11 kim + {0x17, 0x00}, + {0x1c, 0x96}, + {0x1d, 0x04}, // sunlight step + {0x1e, 0x11}, + {0x21, 0xc0}, //max_post_gain + {0x22, 0x40}, //max_pre_gain // 0x60 2011-08-11 kim + {0x2d, 0x06}, //P_N_AEC_exp_level_1[12:8] + {0x2e, 0x00}, //P_N_AEC_exp_level_1[7:0] + {0x1e, 0x32}, + {0x33, 0x00}, //[6:5]max_exp_level [4:0]min_exp_level + {0x34, 0x04}, // min exp + + //////////////////////////////////////////////////////////////////// + /////////////////////////// Measure Window ///////////////////////// + //////////////////////////////////////////////////////////////////// + {0x06, 0x07}, + {0x07, 0x03}, + {0x08, 0x64}, + {0x09, 0x4a}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// AWB //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x57, 0x40}, //number limit + {0x5d, 0x44}, // + {0x5c, 0x35}, //show mode,close dark_mode + {0x5e, 0x29}, //close color temp + {0x5f, 0x50}, + {0x60, 0x50}, + {0x65, 0xc0}, + //////////////////////////////////////////////////////////////////// + /////////////////////////// ABS //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x80, 0x82}, + {0x81, 0x00}, + + {0x82, 0x03}, /// + + {0x83, 0x10}, //ABS Y stretch limit + {0xfe, 0x00}, + //////////////////////////////////////////////////////////////////// + /////////////////////////// OUT //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0xfe, 0x00}, + //crop + {0x50, 0x01}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x02}, + {0x56, 0x58}, + {0x57, 0x03}, + {0x58, 0x20}, + + {0x44, 0xa0}, //YUV sequence + {0x45, 0x0f}, //output enable + {0x46, 0x02}, //sync mode + + /* {0xbF, 0x0B}, + {0xc0, 0x16}, + {0xc1, 0x29}, + {0xc2, 0x3C}, + {0xc3, 0x4F}, + {0xc4, 0x5F}, + {0xc5, 0x6F}, + {0xc6, 0x8A}, + {0xc7, 0x9F}, + {0xc8, 0xB4}, + {0xc9, 0xC6}, + {0xcA, 0xD3}, + {0xcB, 0xDD}, + {0xcC, 0xE5}, + {0xcD, 0xF1}, + {0xcE, 0xFA}, + {0xcF, 0xFF},*/ + + {0x05, 0x01},//HB + {0x06, 0xc1}, + {0x07, 0x00},//VB + {0x08, 0x40}, + + {0xfe, 0x01}, + {0x29, 0x00},//Anti Step 128 + {0x2a, 0x80}, + + {0x2b, 0x05},//Level_0 10.00fps + {0x2c, 0x00}, + {0x2d, 0x06},//Level_1 8.33fps + {0x2e, 0x00}, + {0x2f, 0x08},//Level_2 6.25fps + {0x30, 0x00}, + {0x31, 0x09},//Level_3 5.55fps + {0x32, 0x00}, + {0x33, 0x20}, + {0xfe, 0x00}, + + //--------------------Updated By Mormo 2011/08/08 Start --------------------// + {0xfe, 0x00}, + {0x32, 0x34}, + {0x34, 0x00}, + //--------------------Updated By Mormo 2011/08/08 End ---------------------// + {0x7d, 0x80}, // + {0x7e, 0x80}, + {0x7f, 0x84}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0xfe, 0x00}, + + {0x48, 0x80}, // 68 + + {0x4f, 0x00}, // aec off + + {0x02, 0x00}, + {0x2a, 0x0a}, + + //subsample 1/1 + {0x59, 0x11}, + {0x5a, 0x06}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e , 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + + //crop + {0x50, 0x01}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x04}, + {0x56, 0xb0}, + {0x57, 0x06}, + {0x58, 0x40}, + 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[] = +{ + {0xfe, 0x00}, + + {0x48, 0x40}, + {0x4f, 0x01}, // aec on + + {0x02, 0x01}, + {0x2a, 0xca}, + + //subsample 1/1 + {0x59, 0x11}, + {0x5a, 0x06}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e , 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + + {0x50 , 0x01},//out window + {0x51 , 0x00}, + {0x52 , 0x00}, + {0x53 , 0x00}, + {0x54 , 0x00}, + {0x55 , 0x02}, + {0x56 , 0x58},// 600 + {0x57 , 0x03}, + {0x58 , 0x20},//800 + 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[]={ + SensorRegVal(0xfe,80), + SensorWaitMs(5), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x00,0), + SensorRegVal(0x01,0), + 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[]= +{ + {0x42,0x76}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x8c}, //AWB_R_gain + {0x7b , 0x50}, //AWB_G_gain + {0x7c , 0x40}, //AWB_B_gain + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x74}, //AWB_R_gain + {0x7b , 0x52}, //AWB_G_gain + {0x7c , 0x40}, //AWB_B_gain + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x48}, //AWB_R_gain + {0x7b , 0x40}, //AWB_G_gain + {0x7c , 0x5c}, //AWB_B_gain + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x40}, //AWB_R_gain + {0x7b , 0x54}, //AWB_G_gain + {0x7c , 0x70}, //AWB_B_gain + 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 + + {0xfe, 0x01}, + {0x13, 0x68}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0xe0},// Luma_offset + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + {0xfe, 0x01}, + {0x13, 0x70}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0xf0},// Luma_offset + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + + {0xfe, 0x01}, + {0x13, 0x78}, //AEC_target_Y 48 + {0xfe, 0x00}, + {0xd5, 0x00},// Luma_offset c0 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0xfe, 0x01}, + {0x13, 0x80}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x10},// Luma_offset + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0xfe, 0x01}, + {0x13, 0x88}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x20},// Luma_offset + + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0xfe, 0x01}, + {0x13, 0x90}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x30},// Luma_offset + + 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[] = +{ + {0x43, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x43, 0x02}, + {0xda, 0x50}, + {0xdb, 0xe0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x43, 0x02}, + {0xda, 0xd0}, + {0xdb, 0x28}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x43, 0x01}, + //{0xda, 0xc0}, + //{0xdb, 0xc0}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x43, 0x02}, + {0xda, 0x00}, + {0xdb, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x43, 0x02}, + {0xda, 0xc0}, + {0xdb, 0xc0}, + 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[]= +{ + //Contrast -3 + {0xfe, 0x00}, + {0xd3, 0x2c}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + //Contrast -2 + {0xfe, 0x00}, + {0xd3, 0x30}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + // Contrast -1 + {0xfe, 0x00}, + {0xd3, 0x38}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + //Contrast 0 + {0xfe, 0x00}, + {0xd3, 0x40}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + //Contrast +1 + {0xfe, 0x00}, + {0xd3, 0x48}, + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + //Contrast +2 + {0xfe, 0x00}, + {0xd3, 0x50}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + //Contrast +3 + {0xfe, 0x00}, + {0xd3, 0x58}, + + 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[] = +{ + {0xfe, 0x01}, + {0x33, 0x00}, + {0xfe, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + {0xfe, 0x01}, + {0x33, 0x20}, + {0xfe, 0x00}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//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} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +static u16 GC2015_read_shutter(struct i2c_client *client); // add 2011-08-11 kim +static void GC2015_set_shutter(struct i2c_client *client, u16 shutter); // add 2011-08-11 kim + + +////// add 2011-08-11 kim +static u16 GC2015_read_shutter(struct i2c_client *client) +{ + u8 temp_reg1, temp_reg2; + u16 shutter; + + /* Backup the preview mode last shutter & sensor gain. */ + sensor_read(client, 0x03, &temp_reg1); + sensor_read(client, 0x04, &temp_reg2); + + shutter = (temp_reg1 << 8) | (temp_reg2 & 0xFF); + + return shutter; +} /* GC2015_read_shutter */ + +static void GC2015_set_shutter(struct i2c_client *client, u16 shutter) +{ + u16 temp_reg; + + temp_reg = shutter * 10 / 20; //// + + /*Set Shutter start*/ + if(temp_reg < 1) temp_reg = 1; + sensor_write(client ,0x03 , (temp_reg>>8)&0xff); + sensor_write(client ,0x04 , temp_reg&0xff); + /*Set Shutter end*/ +} +//////// end add kim +/* +********************************************************** +* 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 0; +} +/* +* 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) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + spsensor->shutter= GC2015_read_shutter(client); // add 2011-08-11 kim + + return 0; +} +/* +* 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) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + if(mf->width >=1024) + GC2015_set_shutter(client, spsensor->shutter); // add 2011-08-11 kim + 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x29, &val); + if (err == 0) { + if((val & 0x1) == 0) + err = sensor_write(client, 0x29, (val |0x1)); + else + err = sensor_write(client, 0x29, (val & 0xfe)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x29, &val); + if (err == 0) { + if((val & 0x2) == 0) + err = sensor_write(client, 0x29, (val |0x2)); + else + err = sensor_write(client, 0x29, (val & 0xfc)); + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gc2015_old.c b/drivers/media/video/gc2015_old.c new file mode 100755 index 000000000000..1c3101fd0466 --- /dev/null +++ b/drivers/media/video/gc2015_old.c @@ -0,0 +1,3095 @@ +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC2015 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015 +#define SENSOR_ID 0x2005 +#define SENSOR_MIN_WIDTH 640 +#define SENSOR_MIN_HEIGHT 480 +#define SENSOR_MAX_WIDTH 1600 +#define SENSOR_MAX_HEIGHT 1200 +#define SENSOR_INIT_WIDTH 800//1024 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 600//768 +#define SENSOR_INIT_WINSEQADR sensor_svga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u8 reg; + u8 val; +}; + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_GC2015_USER_DEFINED_SERIES +#include "gc2015_user_series.c" +#else +/* init SVGA preview */ +static struct reginfo sensor_init_data[] = + +{ + {0xfe, 0x80}, //soft reset + {0xfe, 0x80}, //soft reset + {0xfe, 0x80}, //soft reset + + {0xfe, 0x00}, //page0 + {0x45, 0x00}, //output_disable + + ////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////preview capture switch ///////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + //preview + {0x02, 0x01}, //preview mode + {0x2a, 0xca}, //[7]col_binning, 0x[6]even skip + {0x48, 0x40}, //manual_gain + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// preview LSC ///////////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xfe, 0x01}, //page1 + {0xb0, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select + {0xb1, 0x46}, //P_LSC_red_b2 + {0xb2, 0x40}, //P_LSC_green_b2 + {0xb3, 0x40}, //P_LSC_blue_b2 + {0xb4, 0x24}, //P_LSC_red_b4 + {0xb5, 0x20}, //P_LSC_green_b4 + {0xb6, 0x22}, //P_LSC_blue_b4 + {0xb7, 0x00}, //P_LSC_compensate_b2 + {0xb8, 0x80}, //P_LSC_row_center, 0x344, 0x (1200/2-344)/2=128, 0x, 0x + {0xb9, 0x80}, //P_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 + + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// capture LSC ///////////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xba, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select + {0xbb, 0x46}, //C_LSC_red_b2 + {0xbc, 0x40}, //C_LSC_green_b2 + {0xbd, 0x40}, //C_LSC_blue_b2 + {0xbe, 0x24}, //C_LSC_red_b4 + {0xbf, 0x20}, //C_LSC_green_b4 + {0xc0, 0x22}, //C_LSC_blue_b4 + {0xc1, 0x00}, //C_Lsc_compensate_b2 + {0xc2, 0x80}, //C_LSC_row_center, 0x344, 0x (1200/2-344)/2=128 + {0xc3, 0x80}, //C_LSC_col_center, 0x544, 0x (1600/2-544)/2=128 + {0xfe, 0x00}, //page0 + + //////////////////////////////////////////////////////////////////////// + ////////////////////////// analog configure /////////////////////////// + //////////////////////////////////////////////////////////////////////// + {0xfe, 0x00}, //page0 + {0x29, 0x00}, //cisctl mode 1 + {0x2b, 0x06}, //cisctl mode 3 + {0x32, 0x1c}, //analog mode 1 + {0x33, 0x0f}, //analog mode 2 + {0x34, 0x30}, //[6:4]da_rsg + + {0x35, 0x88}, //Vref_A25 + {0x37, 0x16}, //Drive Current + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// ISP Related ///////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0x40, 0xff}, + {0x41, 0x20}, //[5]skin_detectionenable[2]auto_gray, 0x[1]y_gamma + {0x42, 0xf6}, //[7]auto_sa[6]auto_ee[5]auto_dndd[4]auto_lsc[3]na[2]abs, 0x[1]awb + {0x4b, 0xe8}, //[1]AWB_gain_mode, 0x1:atpregain0:atpostgain + {0x4d, 0x03}, //[1]inbf_en + {0x4f, 0x01}, //AEC enable + + //////////////////////////////////////////////////////////////////// + /////////////////////////// BLK ////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x63, 0x77}, //BLK mode 1 + {0x66, 0x00}, //BLK global offset + {0x6d, 0x00}, + {0x6e, 0x1a}, //BLK offset submode,offset R + {0x6f, 0x20}, + {0x70, 0x1a}, + {0x71, 0x20}, + {0x73, 0x00}, + {0x77, 0x80}, + {0x78, 0x80}, + {0x79, 0x90}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// DNDD /////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x80, 0x07}, //[7]dn_inc_or_dec [4]zero_weight_mode[3]share [2]c_weight_adap [1]dn_lsc_mode [0]dn_b + {0x82, 0x0c}, //DN lilat b base + {0x83, 0x03}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// EEINTP //////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x8a, 0x7c}, + {0x8c, 0x02}, + {0x8e, 0x02}, + {0x8f, 0x45}, + + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// CC_t //////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xb0, 0x40}, // 0x48 + {0xb1, 0xfe}, + {0xb2, 0x00}, + {0xb3, 0xf0}, + {0xb4, 0x50}, + {0xb5, 0xf8}, + {0xb6, 0x00}, + {0xb7, 0x00}, + {0xb8, 0x00}, + + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// GAMMA /////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + //RGB_GAMMA + {0xbf, 0x08}, + {0xc0, 0x1e}, + {0xc1, 0x33}, + {0xc2, 0x47}, + {0xc3, 0x59}, + {0xc4, 0x68}, + {0xc5, 0x74}, + {0xc6, 0x86}, + {0xc7, 0x97}, + {0xc8, 0xA5}, + {0xc9, 0xB1}, + {0xca, 0xBd}, + {0xcb, 0xC8}, + {0xcc, 0xD3}, + {0xcd, 0xE4}, + {0xce, 0xF4}, + {0xcf, 0xff}, + + /*{0xbf, 0x06}, + {0xc0, 0x1f}, + {0xc1, 0x38}, + {0xc2, 0x4c}, + {0xc3, 0x5b}, + {0xc4, 0x6b}, + {0xc5, 0x76}, + {0xc6, 0x8b}, + {0xc7, 0x9b}, + {0xc8, 0xac}, + {0xc9, 0xbb}, + {0xca, 0xc7}, + {0xcb, 0xd2}, + {0xcc, 0xdb}, + {0xcd, 0xea}, + {0xce, 0xf5}, + {0xcf, 0xff}, */ + + ///////////////////////////////////////////////////////////////////// + /////////////////////////// YCP_t /////////////////////////////////// + ///////////////////////////////////////////////////////////////////// + {0xd1, 0x40}, //saturation 38 + {0xd2, 0x40}, //saturation 38 + + {0xd3, 0x46}, // 2011-08-11 kim add + + {0xde, 0x21}, //auto_gray + + //////////////////////////////////////////////////////////////////// + /////////////////////////// ASDE /////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x98, 0x3a}, + {0x99, 0x60}, + {0x9b, 0x00}, + {0x9f, 0x12}, + {0xa1, 0x80}, + {0xa2, 0x21}, + + {0xfe, 0x01}, //page1 + {0xc5, 0x10}, + {0xc6, 0xff}, + {0xc7, 0xff}, + {0xc8, 0xff}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// AEC //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x10, 0x09}, //AEC mode 1 + {0x11, 0x92}, //[7]fix target // 0xb2 2011-08-11 kim + {0x12, 0x20}, + {0x13, 0x78}, // 0x78 2011-08-11 kim + {0x17, 0x00}, + {0x1c, 0x96}, + {0x1d, 0x04}, // sunlight step + {0x1e, 0x11}, + {0x21, 0xc0}, //max_post_gain + {0x22, 0x40}, //max_pre_gain // 0x60 2011-08-11 kim + {0x2d, 0x06}, //P_N_AEC_exp_level_1[12:8] + {0x2e, 0x00}, //P_N_AEC_exp_level_1[7:0] + {0x1e, 0x32}, + {0x33, 0x00}, //[6:5]max_exp_level [4:0]min_exp_level + {0x34, 0x04}, // min exp + + //////////////////////////////////////////////////////////////////// + /////////////////////////// Measure Window ///////////////////////// + //////////////////////////////////////////////////////////////////// + {0x06, 0x07}, + {0x07, 0x03}, + {0x08, 0x64}, + {0x09, 0x4a}, + + //////////////////////////////////////////////////////////////////// + /////////////////////////// AWB //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x57, 0x40}, //number limit + {0x5d, 0x44}, // + {0x5c, 0x35}, //show mode,close dark_mode + {0x5e, 0x29}, //close color temp + {0x5f, 0x50}, + {0x60, 0x50}, + {0x65, 0xc0}, + //////////////////////////////////////////////////////////////////// + /////////////////////////// ABS //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0x80, 0x82}, + {0x81, 0x00}, + + {0x82, 0x03}, /// + + {0x83, 0x10}, //ABS Y stretch limit + {0xfe, 0x00}, + //////////////////////////////////////////////////////////////////// + /////////////////////////// OUT //////////////////////////////////// + //////////////////////////////////////////////////////////////////// + {0xfe, 0x00}, + //crop + {0x50, 0x01}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x02}, + {0x56, 0x58}, + {0x57, 0x03}, + {0x58, 0x20}, + + {0x44, 0xa0}, //YUV sequence + {0x45, 0x0f}, //output enable + {0x46, 0x02}, //sync mode + +/* {0xbF, 0x0B}, + {0xc0, 0x16}, + {0xc1, 0x29}, + {0xc2, 0x3C}, + {0xc3, 0x4F}, + {0xc4, 0x5F}, + {0xc5, 0x6F}, + {0xc6, 0x8A}, + {0xc7, 0x9F}, + {0xc8, 0xB4}, + {0xc9, 0xC6}, + {0xcA, 0xD3}, + {0xcB, 0xDD}, + {0xcC, 0xE5}, + {0xcD, 0xF1}, + {0xcE, 0xFA}, + {0xcF, 0xFF},*/ + + {0x05, 0x01},//HB + {0x06, 0xc1}, + {0x07, 0x00},//VB + {0x08, 0x40}, + + {0xfe, 0x01}, + {0x29, 0x00},//Anti Step 128 + {0x2a, 0x80}, + + {0x2b, 0x05},//Level_0 10.00fps + {0x2c, 0x00}, + {0x2d, 0x06},//Level_1 8.33fps + {0x2e, 0x00}, + {0x2f, 0x08},//Level_2 6.25fps + {0x30, 0x00}, + {0x31, 0x09},//Level_3 5.55fps + {0x32, 0x00}, + {0x33, 0x20}, + {0xfe, 0x00}, + +//--------------------Updated By Mormo 2011/08/08 Start --------------------// + {0xfe, 0x00}, + {0x32, 0x34}, + {0x34, 0x00}, +//--------------------Updated By Mormo 2011/08/08 End ---------------------// + {0x7d, 0x80}, // + {0x7e, 0x80}, + {0x7f, 0x84}, + + {0x0,0x0} + +}; + +/* 1600X1200 UXGA capture */ +static struct reginfo sensor_uxga[] = +{ + {0xfe, 0x00}, + + {0x48, 0x80}, // 68 + + {0x4f, 0x00}, // aec off + + {0x02, 0x00}, + {0x2a, 0x0a}, + + //subsample 1/1 + {0x59, 0x11}, + {0x5a, 0x06}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e , 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + + //crop + {0x50, 0x01}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x04}, + {0x56, 0xb0}, + {0x57, 0x06}, + {0x58, 0x40}, + {0x0,0x0} +}; + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0xfe, 0x00}, + + {0x48, 0x80}, // 68 + + {0x4f, 0x00}, // aec off + + {0x02, 0x00}, + {0x2a, 0x0a}, + + //subsample 1/1 + {0x59, 0x11}, + {0x5a, 0x06}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e , 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + + //crop + {0x50, 0x01}, + {0x51, 0x00}, + {0x52, 0x00}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x04}, + {0x56, 0x00}, + {0x57, 0x05}, + {0x58, 0x00}, + {0x0, 0x0} +}; +/*1024*768*/ +static struct reginfo sensor_xga[] = +{ + {0xfe, 0x00}, + + {0x48, 0x80}, // 68 + + {0x4f, 0x00}, // aec off + + {0x02, 0x00}, + {0x2a, 0x0a}, + //subsample 1600x1200 to 1066x800 + {0x59 , 0x33},//out window + {0x5a , 0x06}, + {0x5b , 0x00}, + {0x5c , 0x00}, + {0x5d , 0x00}, + {0x5e , 0x01}, + {0x5f , 0x00}, + {0x60 , 0x00}, + {0x61 , 0x00}, + {0x62 , 0x01}, + + {0x50 , 0x01},//out window + {0x51 , 0x00}, + {0x52 , 0x10}, + {0x53 , 0x00}, + {0x54 , 0x14}, + {0x55 , 0x03}, + {0x56 , 0x00},// 768 + {0x57 , 0x04}, + {0x58 , 0x00},//1024 + {0x0, 0x0} +}; +/* 800X600 SVGA,30fps*/ +static struct reginfo sensor_svga[] = +{ + {0xfe, 0x00}, + + {0x48, 0x40}, + {0x4f, 0x01}, // aec on + + {0x02, 0x01}, + {0x2a, 0xca}, + + //subsample 1/1 + {0x59, 0x11}, + {0x5a, 0x06}, + {0x5b, 0x00}, + {0x5c, 0x00}, + {0x5d, 0x00}, + {0x5e , 0x00}, + {0x5f, 0x00}, + {0x60, 0x00}, + {0x61, 0x00}, + {0x62, 0x00}, + + {0x50 , 0x01},//out window + {0x51 , 0x00}, + {0x52 , 0x00}, + {0x53 , 0x00}, + {0x54 , 0x00}, + {0x55 , 0x02}, + {0x56 , 0x58},// 600 + {0x57 , 0x03}, + {0x58 , 0x20},//800 + {0x0,0x0} +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + + + {0xfe, 0x00}, + + {0x48, 0x40}, + {0x4f, 0x01}, // aec on + + {0x02, 0x01}, + {0x2a, 0xca}, + //subsample 4/5 + + {0x59 , 0x55},//out window + {0x5a , 0x06}, + {0x5b , 0x00}, + {0x5c , 0x00}, + {0x5d , 0x01}, + {0x5e , 0x23}, + {0x5f , 0x00}, + {0x60 , 0x00}, + {0x61 , 0x01}, + {0x62 , 0x23}, + + {0x50 , 0x01},//out window + {0x51 , 0x00}, + {0x52 , 0x00}, + {0x53 , 0x00}, + {0x54 , 0x00}, + {0x55 , 0x01}, + {0x56 , 0xe0},// 480 + {0x57 , 0x02}, + {0x58 , 0x80},//640 + {0x45 , 0x0f}, //output enable + {0x0,0x0} +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{}; +#endif +#if 0 +/* 160X120 QQVGA*/ +static struct reginfo ov2655_qqvga[] = +{ + {0x00, 0x00}, +}; + + + +static struct reginfo ov2655_Sharpness_auto[] = +{ + + {0x00, 0x00}, +}; + +static struct reginfo ov2655_Sharpness1[] = +{ + + {0x00, 0x00}, +}; + +static struct reginfo ov2655_Sharpness2[][3] = +{ + //Sharpness 2 + + {0x00, 0x00}, +}; + +static struct reginfo ov2655_Sharpness3[] = +{ + //default + + {0x00, 0x00}, +}; +static struct reginfo ov2655_Sharpness4[]= +{ + //Sharpness 4 + + {0x00, 0x00}, +}; + +static struct reginfo ov2655_Sharpness5[] = +{ + //Sharpness 5 + + {0x00, 0x00}, +}; +#endif + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + + {0x00, 0x00} +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x42,0x76}, + {0x00, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x8c}, //AWB_R_gain + {0x7b , 0x50}, //AWB_G_gain + {0x7c , 0x40}, //AWB_B_gain + {0x00, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x74}, //AWB_R_gain + {0x7b , 0x52}, //AWB_G_gain + {0x7c , 0x40}, //AWB_B_gain + {0x00, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x48}, //AWB_R_gain + {0x7b , 0x40}, //AWB_G_gain + {0x7c , 0x5c}, //AWB_B_gain + {0x00, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF + {0x7a , 0x40}, //AWB_R_gain + {0x7b , 0x54}, //AWB_G_gain + {0x7c , 0x70}, //AWB_B_gain + {0x00, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + + {0xfe, 0x01}, + {0x13, 0x68}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0xe0},// Luma_offset + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + {0xfe, 0x01}, + {0x13, 0x70}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0xf0},// Luma_offset + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + + {0xfe, 0x01}, + {0x13, 0x78}, //AEC_target_Y 48 + {0xfe, 0x00}, + {0xd5, 0x00},// Luma_offset c0 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + {0xfe, 0x01}, + {0x13, 0x80}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x10},// Luma_offset + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + {0xfe, 0x01}, + {0x13, 0x88}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x20},// Luma_offset + + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + {0xfe, 0x01}, + {0x13, 0x90}, //AEC_target_Y + {0xfe, 0x00}, + {0xd5, 0x30},// Luma_offset + {0x00, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + + {0x43, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x43, 0x02}, + {0xda, 0x50}, + {0xdb, 0xe0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x43, 0x02}, + {0xda, 0xd0}, + {0xdb, 0x28}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x43, 0x01}, + //{0xda, 0xc0}, + //{0xdb, 0xc0}, + {0x00, 0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x43, 0x02}, + {0xda, 0x00}, + {0xdb, 0x00}, + + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x43, 0x02}, + {0xda, 0xc0}, + {0xdb, 0xc0}, + {0x00, 0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + //-3 + +}; + +static struct reginfo sensor_Exposure1[]= +{ + //-2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + //-0.3EV + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + //default + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + // 1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + // 2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + // 3 + + {0x00, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + + {0x00, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + //Contrast -3 + {0xfe, 0x00}, + {0xd3, 0x2c}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + //Contrast -2 + {0xfe, 0x00}, + {0xd3, 0x30}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + // Contrast -1 + {0xfe, 0x00}, + {0xd3, 0x38}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + //Contrast 0 + {0xfe, 0x00}, + {0xd3, 0x40}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + //Contrast +1 + {0xfe, 0x00}, + {0xd3, 0x48}, + {0x00, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + //Contrast +2 + {0xfe, 0x00}, + {0xd3, 0x50}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + //Contrast +3 + {0xfe, 0x00}, + {0xd3, 0x58}, + {0x00, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0x29 , 0x01}, + {0x00, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0x29 , 0x01}, + {0x00, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x29 , 0x02}, + {0x00, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x29 , 0x00}, + {0x00, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + /* ddl@rock-chips.com : */ + {0xfe, 0x01}, + {0x33, 0x00}, + {0xfe, 0x00}, + + {0x00, 0x00} + +}; + +static struct reginfo sensor_SceneNight[] = +{ + + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + {0xfe, 0x01}, + {0x33, 0x20}, + {0xfe, 0x00}, + {0x00, 0x00} + +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); +static int sensor_write(struct i2c_client *client, u8 reg, u8 val); +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val); + + +static u16 GC2015_read_shutter(struct i2c_client *client); // add 2011-08-11 kim +static void GC2015_set_shutter(struct i2c_client *client, u16 shutter); // add 2011-08-11 kim + + +////// add 2011-08-11 kim +static u16 GC2015_read_shutter(struct i2c_client *client) +{ + u8 temp_reg1, temp_reg2; + u16 shutter; + + /* Backup the preview mode last shutter & sensor gain. */ + sensor_read(client, 0x03, &temp_reg1); + sensor_read(client, 0x04, &temp_reg2); + + shutter = (temp_reg1 << 8) | (temp_reg2 & 0xFF); + + return shutter; +} /* GC2015_read_shutter */ + +static void GC2015_set_shutter(struct i2c_client *client, u16 shutter) +{ + u16 temp_reg; + + temp_reg = shutter * 10 / 20; //// + + /*Set Shutter start*/ + if(temp_reg < 1) temp_reg = 1; + sensor_write(client ,0x03 , (temp_reg>>8)&0xff); + sensor_write(client ,0x04 , temp_reg&0xff); + /*Set Shutter end*/ +} +//////// end add kim + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +#if 0 +/* sensor register */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret = 0; + + ret = i2c_master_reg8_recv(client, reg, val, 1, CONFIG_SENSOR_I2C_SPEED); + + return (ret > 0)? 0 : ret; +} + +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int ret = 0; + + ret = i2c_master_reg8_send(client, reg, &val, 1, CONFIG_SENSOR_I2C_SPEED); + + return (ret > 0)? 0 : ret; +} +#else +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg; + buf[1] = val; + + if (reg == 0xfe) + mdelay(20); + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + u8 buf[1]; + struct i2c_msg msg[2]; + + buf[0] = reg ; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +#endif + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; + #if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; + #endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + //mdelay(5); + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != 0) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret,pid = 0; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + ret = sensor_write(client, 0xfe, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); //delay 5 microseconds + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x01, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + u32 gc2015_shutter; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800-32; + set_h = 600; + } + else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) + { + gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim + + winseqe_set_addr = sensor_xga; + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim + + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + + gc2015_shutter = GC2015_read_shutter(client); // add 2011-08-11 kim + + winseqe_set_addr = sensor_uxga; + set_w = 1600-32; + set_h = 1200; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + + if(set_w >= 1024) GC2015_set_shutter(client, gc2015_shutter); // add 2011-08-11 kim + + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800-32; + set_h = 600; + } + else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) + { + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + set_w = 1600-32; + set_h = 1200; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret,pid=0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + ret = sensor_write(client, 0xfe, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(5); //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x00, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x01, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/gc2035.c b/drivers/media/video/gc2035.c index 68bd09274fc4..b66ba80eeeeb 100755 --- a/drivers/media/video/gc2035.c +++ b/drivers/media/video/gc2035.c @@ -1,25 +1,13 @@ -/* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -28,90 +16,79 @@ module_param(debug, int, S_IRUGO|S_IWUSR); if (debug >= level) \ printk(KERN_WARNING fmt , ## arg); } while (0) -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ +/* Sensor Driver Configuration Begin */ #define SENSOR_NAME RK29_CAM_SENSOR_GC2035 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035 #define SENSOR_ID 0x2035 -#define SENSOR_MIN_WIDTH 800 -#define SENSOR_MIN_HEIGHT 600 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 +#define SENSOR_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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) +#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 -struct reginfo +struct sensor_parameter { - u8 reg; - u8 val; -}; + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; }; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + u16 shutter; + +}; -/* init 352X288 SVGA */ -static struct reginfo sensor_init_data[] ={ +/* +* 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[] = +{ {0xfe , 0x80}, {0xfe , 0x80}, {0xfe , 0x80}, @@ -788,15 +765,10 @@ static struct reginfo sensor_init_data[] ={ {0x47 , 0x09}, #endif - - {0x00,0x00}, + SensorEnd }; - - - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ {0xfe , 0x00}, @@ -820,23 +792,18 @@ static struct reginfo sensor_uxga[] = {0x97 , 0x06}, {0x98 , 0x40}, - {0x00 , 0x00}, + SensorEnd }; - - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - - {0x00,0x00}, +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + SensorEnd }; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ {0xfe , 0x00}, {0xb6 , 0x03}, {0xf7 , 0x15}, @@ -859,2408 +826,615 @@ static struct reginfo sensor_svga[] = {0x96 , 0x58}, {0x97 , 0x03}, {0x98 , 0x20}, - {0x00,0x00}, + SensorEnd }; - - - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - - - {0x00 , 0x00}, +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + SensorEnd }; -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x00,0x00}, +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd }; -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - - {0x00,0x00}, +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0xfe,80), + SensorWaitMs(5), + SensorEnd }; -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - - {0x00,0x00}, +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0xf0,0), + SensorRegVal(0xf1,0), + SensorEnd }; - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - - {0x00,0x00}, -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x00,0x00}, -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[]= { - {0xfe, 0x00}, {0xb3, 0x61}, {0xb4, 0x40}, {0xb5, 0x61}, {0x82, 0xfe}, - {0x00,0x00}, + SensorEnd }; /* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= { - {0xfe, 0x00}, {0x82, 0xfc}, {0xb3, 0x58}, {0xb4, 0x40}, {0xb5, 0x50}, - {0x00,0x00}, + SensorEnd }; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= { - //Sunny - {0xfe, 0x00}, - {0x82, 0xfc}, - {0xb3, 0x78}, - {0xb4, 0x40}, - {0xb5, 0x50}, - {0x00,0x00}, + //Sunny + {0x82, 0xfc}, + {0xb3, 0x58}, + {0xb4, 0x40}, + {0xb5, 0x50}, + SensorEnd }; /* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= { - //Office - {0xfe, 0x00}, - {0x82, 0xfc}, - {0xb3, 0x50}, - {0xb4, 0x40}, - {0xb5, 0xa8}, - {0x00,0x00}, + //Office + {0x82, 0xfc}, + {0xb3, 0x50}, + {0xb4, 0x40}, + {0xb5, 0xa8}, + SensorEnd }; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= { - //Home - {0xfe, 0x00}, - {0x82, 0xfc}, - {0xb3, 0xa0}, - {0xb4, 0x45}, - {0xb5, 0x40}, - {0x00, 0x00}, + //Home + {0x82, 0xfc}, + {0xb3, 0xa0}, + {0xb4, 0x45}, + {0xb5, 0x40}, + SensorEnd }; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, }; -#endif -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= +static struct rk_sensor_reg sensor_Brightness0[]= { - // Brightness -2 - + // Brightness -2 + {0xfe, 0x01}, - {0x13, 0x70}, + {0x13, 0x40}, {0xfe, 0x02}, {0xd5, 0xe0}, - {0x00, 0x00}, + SensorEnd }; -static struct reginfo sensor_Brightness1[]= +static struct rk_sensor_reg sensor_Brightness1[]= { - // Brightness -1 - + // Brightness -1 + {0xfe, 0x01}, - {0x13, 0x78}, + {0x13, 0x48}, {0xfe, 0x02}, {0xd5, 0xf0}, - {0x00, 0x00} + + SensorEnd }; -static struct reginfo sensor_Brightness2[]= +static struct rk_sensor_reg sensor_Brightness2[]= { - // Brightness 0 - + // Brightness 0 + {0xfe, 0x01}, - {0x13, 0x80}, + {0x13, 0x58}, {0xfe, 0x02}, {0xd5, 0x00}, - {0x00, 0x00} + + SensorEnd }; -static struct reginfo sensor_Brightness3[]= +static struct rk_sensor_reg sensor_Brightness3[]= { - // Brightness +1 + // Brightness +1 {0xfe, 0x01}, - {0x13, 0x88}, + {0x13, 0x60}, {0xfe, 0x02}, {0xd5, 0x10}, - {0x00, 0x00} + + SensorEnd }; -static struct reginfo sensor_Brightness4[]= +static struct rk_sensor_reg sensor_Brightness4[]= { - // Brightness +2 + // Brightness +2 {0xfe, 0x01}, - {0x13, 0x90}, + {0x13, 0x68}, {0xfe, 0x02}, {0xd5, 0x20}, - {0x00, 0x00} + + SensorEnd }; -static struct reginfo sensor_Brightness5[]= +static struct rk_sensor_reg sensor_Brightness5[]= { - // Brightness +3 + // Brightness +3 {0xfe, 0x01}, - {0x13, 0x98}, + {0x13, 0x78}, {0xfe, 0x02}, {0xd5, 0x30}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, }; -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = +static struct rk_sensor_reg sensor_Effect_Normal[] = { {0xfe, 0x00}, {0x83, 0xe0}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Effect_WandB[] = +static struct rk_sensor_reg sensor_Effect_WandB[] = { {0xfe, 0x00}, {0x83, 0x12}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Effect_Sepia[] = +static struct rk_sensor_reg sensor_Effect_Sepia[] = { {0xfe, 0x00}, {0x83, 0x82}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Effect_Negative[] = +static struct rk_sensor_reg sensor_Effect_Negative[] = { - //Negative + //Negative {0xfe, 0x00}, {0x83, 0x01}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Effect_Bluish[] = +static struct rk_sensor_reg sensor_Effect_Bluish[] = { - // Bluish + // Bluish {0xfe, 0x00}, {0x83, 0x62}, - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Effect_Green[] = +static struct rk_sensor_reg sensor_Effect_Green[] = { - // Greenish + // Greenish {0xfe, 0x00}, {0x83, 0x52}, - {0x00, 0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, + SensorEnd }; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - //-3 - - {0x00, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - //-2 - - {0x00, 0x00} +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 reginfo sensor_Exposure2[]= +static struct rk_sensor_reg sensor_Exposure0[]= { - //-0.3EV - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure3[]= +static struct rk_sensor_reg sensor_Exposure1[]= { - //default - - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure4[]= +static struct rk_sensor_reg sensor_Exposure2[]= { - // 1 - - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure5[]= +static struct rk_sensor_reg sensor_Exposure3[]= { - // 2 - - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure6[]= +static struct rk_sensor_reg sensor_Exposure4[]= { - // 3 - - {0x00, 0x00} + SensorEnd }; -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= +static struct rk_sensor_reg sensor_Exposure5[]= { - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Saturation1[]= +static struct rk_sensor_reg sensor_Exposure6[]= { - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Saturation2[]= -{ - {0x00, 0x00} +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, }; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= +static struct rk_sensor_reg sensor_Saturation0[]= { - //Contrast -3 - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast1[]= +static struct rk_sensor_reg sensor_Saturation1[]= { - //Contrast -2 - {0x00, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast2[]= +static struct rk_sensor_reg sensor_Saturation2[]= { - // Contrast -1 - {0x00, 0x00} + SensorEnd }; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; -static struct reginfo sensor_Contrast3[]= +static struct rk_sensor_reg sensor_Contrast0[]= { - //Contrast 0 - {0x00, 0x00} -}; + //Contrast -3 -static struct reginfo sensor_Contrast4[]= -{ - //Contrast +1 - {0x00, 0x00} + SensorEnd }; - -static struct reginfo sensor_Contrast5[]= +static struct rk_sensor_reg sensor_Contrast1[]= { - //Contrast +2 - {0x00, 0x00} + //Contrast -2 + + SensorEnd }; -static struct reginfo sensor_Contrast6[]= +static struct rk_sensor_reg sensor_Contrast2[]= { - - //Contrast +3 - {0x00, 0x00} + // Contrast -1 -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, + SensorEnd }; -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= +static struct rk_sensor_reg sensor_Contrast3[]= { - {0x17 , 0x14}, - {0x00 , 0x00} -}; + //Contrast 0 -static struct reginfo sensor_MirrorOff[]= -{ - {0x17 , 0x15}, - {0x00 , 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x17 , 0x16}, - {0x00 , 0x00} + SensorEnd }; -static struct reginfo sensor_FlipOff[]= +static struct rk_sensor_reg sensor_Contrast4[]= { - {0x17 , 0x17}, - {0x00 , 0x00} + //Contrast +1 + + SensorEnd }; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = + +static struct rk_sensor_reg sensor_Contrast5[]= { -{0xfe,0x01}, -{0x3e,0x40}, -{0xfe,0x00}, + //Contrast +2 -{0x00,0x00} + SensorEnd }; -static struct reginfo sensor_SceneNight[] = +static struct rk_sensor_reg sensor_Contrast6[]= { -{0xfe,0x01}, -{0x3e,0x60}, -{0xfe,0x00}, -{0x00,0x00} + //Contrast +3 + SensorEnd }; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, }; - -static struct reginfo sensor_Zoom1[] = +static struct rk_sensor_reg sensor_SceneAuto[] = { - {0x0, 0x0}, + {0xfe,0x01}, + + {0x3e,0x40}, + {0xfe,0x00}, + SensorEnd }; -static struct reginfo sensor_Zoom2[] = +static struct rk_sensor_reg sensor_SceneNight[] = { - {0x0, 0x0}, + {0xfe,0x01}, + + {0x3e,0x60}, + {0xfe,0x00}, + SensorEnd }; +static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = +static struct rk_sensor_reg sensor_Zoom0[] = { - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif + SensorEnd }; -static struct v4l2_queryctrl sensor_controls[] = +static struct rk_sensor_reg sensor_Zoom1[] = { - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif + SensorEnd }; -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = +static struct rk_sensor_reg sensor_Zoom2[] = { - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), + SensorEnd }; -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) +static struct rk_sensor_reg sensor_Zoom3[] = { - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} + SensorEnd }; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = { - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; }; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = { - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg; - buf[1] = val; - - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); +}; - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } +//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} +}; +static struct soc_camera_ops sensor_ops; - return err; -} -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +/* +********************************************************** +* 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) { - int err,cnt; - u8 buf[1]; - struct i2c_msg msg[2]; - - buf[0] = reg ; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; + + return 0; } - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) { - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; + + 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) +{ + char value; + unsigned int pid=0,shutter,temp_reg; + if(mf->width == 1600 && mf->height == 1200){ + sensor_write(client, 0xfe, 0x00); + sensor_write(client, 0xb6, 0x02); + + + sensor_read(client, 0x03, &value); + pid |= (value << 8); + sensor_read(client, 0x04, &value); + pid |= (value & 0xff); + shutter=pid; + + + temp_reg= shutter /2; // 2 + + if(temp_reg < 1) temp_reg = 1; + + + sensor_write(client, 0x03, ((temp_reg>>8)&0xff)); + sensor_write(client, 0x04, (temp_reg&0xff)); + } -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; + return 0; } -#endif -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +/* +* 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) { - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - + return 0; } -static int sensor_init(struct v4l2_subdev *sd, u32 val) +static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0xf0, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0xf1, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - - - mdelay(300); - - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; + return 0; } - -static int sensor_deactivate(struct i2c_client *client) +static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) { - struct soc_camera_device *icd = client->dev.platform_data; - - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { - } - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - return 0; } - -static struct reginfo sensor_power_down_sequence[]= +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) { - - {0x00,0x00} -}; + return 0; +} static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) { - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; + //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) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) { - return 0; -} + SENSOR_DG("Resume"); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; + return 0; - return soc_camera_apply_sensor_flags(icl, flags); } - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +static int sensor_mirror_cb (struct i2c_client *client, int mirror) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x1) == 0){ + err = sensor_write(client, 0x17, ((val |0x1)+4)); + } + else + err = sensor_write(client, 0x17, ((val & 0xfe)+4)); + } + } else { + //do nothing + } + return err; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +/* +* 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) { - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +static int sensor_flip_cb(struct i2c_client *client, int flip) { - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } + char val; + int err = 0; - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static unsigned int shutter_h,shutter_l; -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - int ret1; - - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; -#if 1 -char value; -unsigned int pid=0,shutter,temp_reg; - -#endif - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + SENSOR_DG("flip: %d",flip); + if (flip) { + + sensor_write(client, 0xfe, 0); + err = sensor_read(client, 0x17, &val); + val-=4; + if (err == 0) { + if((val & 0x2) == 0){ + err = sensor_write(client, 0x17, ((val |0x2)+4)); + } + else { + err = sensor_write(client, 0x17, ((val & 0xfc)+4)); + } } + } else { + //do nothing } - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - - if ((winseqe_set_addr == sensor_svga)||(winseqe_set_addr == sensor_vga) ) - { - sensor_write(client, 0xb6, 0x00); // AEC ON - sensor_write(client, 0x03, shutter_h); - sensor_write(client, 0x04, shutter_l); - msleep(50); - printk("set preview for rewrite 0x03"); - - } - ret |= sensor_write_array(client, winseqe_set_addr); -#if 1 - if (winseqe_set_addr == sensor_uxga) - { - sensor_write(client, 0xfe, 0x00); - sensor_write(client, 0xb6, 0x02); // AEC OFF - sensor_read(client, 0x03, &value); - shutter_h=value; - pid |= (value << 8); - sensor_read(client, 0x04, &value); - shutter_l=value; - pid |= (value & 0xff); - shutter=pid; - temp_reg= shutter /2; - if(temp_reg < 1) temp_reg = 1; - sensor_write(client, 0x03, ((temp_reg>>8)&0xff)); - sensor_write(client, 0x04, (temp_reg&0xff)); - } -#endif - - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - msleep(600); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - msleep(100); //james added -sensor_s_fmt_end: - return ret; + return err; } - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - set_w = 1600; - set_h = 1200; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +/* +* 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) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gc2035 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; } -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client){ + return 0; } -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; +static int sensor_focus_af_single_usr_cb(struct i2c_client *client){ + return 0; } -#endif -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; +static int sensor_focus_af_near_usr_cb(struct i2c_client *client){ + return 0; } - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; +static int sensor_focus_af_far_usr_cb(struct i2c_client *client){ + return 0; } -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){ + return 0; } -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } +static int sensor_focus_af_const_usr_cb(struct i2c_client *client){ + return 0; } - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0xf0, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0xf1, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; +static int sensor_focus_af_close_usr_cb(struct i2c_client *client){ + return 0; } -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); -#if CONFIG_SENSOR_Flash - int i; -#endif - int ret = 0; - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + return 0; } -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - *code = sensor_colour_fmts[index].code; +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){ return 0; } -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) +/* +* 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) { - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; + return; } -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ - return 0; -} +sensor_init_parameters_default_code(); -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; +sensor_v4l2_struct_initialization(); -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} +sensor_probe_default_code(); -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} +sensor_remove_default_code(); -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); +sensor_driver_default_module_code(); -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/gc2035_old.c b/drivers/media/video/gc2035_old.c new file mode 100755 index 000000000000..68bd09274fc4 --- /dev/null +++ b/drivers/media/video/gc2035_old.c @@ -0,0 +1,3267 @@ +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GC2035 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035 +#define SENSOR_ID 0x2035 +#define SENSOR_MIN_WIDTH 800 +#define SENSOR_MIN_HEIGHT 600 +#define SENSOR_MAX_WIDTH 1600 +#define SENSOR_MAX_HEIGHT 1200 +#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 600 +#define SENSOR_INIT_WINSEQADR sensor_svga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u8 reg; + u8 val; +}; + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc + +/* init 352X288 SVGA */ +static struct reginfo sensor_init_data[] ={ + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfe , 0x80}, + {0xfc , 0x06}, + {0xf2 , 0x00}, + {0xf3 , 0x00}, + {0xf4 , 0x00}, + {0xf5 , 0x00}, + {0xf9 , 0xfe}, //[0] pll enable + {0xfa , 0x00}, + {0xf6 , 0x00}, + {0xf7 , 0x15}, //pll enable + + {0xf8 , 0x85}, + {0xfe , 0x00}, + {0x82 , 0x00}, + {0xb3 , 0x60}, + {0xb4 , 0x40}, + {0xb5 , 0x60}, + + {0x03 , 0x02}, + {0x04 , 0x80}, + + //////////measure window /////////// + {0xfe , 0x00}, + {0xec , 0x06},//04 + {0xed , 0x06},//04 + {0xee , 0x62},//60 + {0xef , 0x92},//90 + + ///////////analog///////////// + {0x0a , 0x00}, //row start + {0x0c , 0x00}, //col start + {0x0d , 0x04}, + {0x0e , 0xc0}, + {0x0f , 0x06}, //Window setting + {0x10 , 0x58}, + {0x17 , 0x14}, //[0]mirror [1]flip + + + {0x18 , 0x0e}, //sdark 4 row in even frame?? + {0x19 , 0x0c}, //AD pipe number + + /* + /// ë´Ì ÏÖÏó + {0x18 , 0x0a}, //sdark 4 row in even frame?? + {0x19 , 0x0a}, //AD pipe number + */ + + {0x1a , 0x01}, //CISCTL mode4 + {0x1b , 0x8b}, + {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias + {0x1f , 0x08}, //[3] tx-low en// + {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en + {0x21 , 0x0f}, //[6:4]rsg + {0x22 , 0xf0}, //[3:0]vref + {0x23 , 0xc3}, //f3//ADC_r + {0x24 , 0x17}, //pad drive 16 + + //AEC + {0xfe , 0x01}, + {0x11 , 0x20},//AEC_out_slope , 0x + {0x1f , 0xc0},//max_post_gain + {0x20 , 0x60},//max_pre_gain + {0x47 , 0x30},//AEC_outdoor_th + {0x0b , 0x10},// + {0x13 , 0x75},//y_target + {0xfe , 0x00}, + + + {0x05 , 0x01},//hb + {0x06 , 0x11}, + {0x07 , 0x00},//vb + {0x08 , 0x50}, + {0xfe , 0x01}, + {0x27 , 0x00},//step + {0x28 , 0xa0}, + {0x29 , 0x05},//level1 + {0x2a , 0x00}, + {0x2b , 0x05},//level2 + {0x2c , 0x00}, + {0x2d , 0x06},//6e8//level3 + {0x2e , 0xe0}, + {0x2f , 0x0a},//level4 + {0x30 , 0x00}, + {0x3e , 0x40}, + {0xfe , 0x00}, + {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x + {0xb6 , 0x03}, //AEC enable + {0xfe , 0x00}, + + /////////BLK////// + {0x3f , 0x00}, //prc close + {0x40 , 0x77},// + {0x42 , 0x7f}, + {0x43 , 0x30}, + {0x5c , 0x08}, + {0x5e , 0x20}, + {0x5f , 0x20}, + {0x60 , 0x20}, + {0x61 , 0x20}, + {0x62 , 0x20}, + {0x63 , 0x20}, + {0x64 , 0x20}, + {0x65 , 0x20}, + + ///block//////////// + {0x80 , 0xff}, + {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug + {0x87 , 0x90}, //[7]middle gamma + {0x84 , 0x00}, //output put foramat + {0x86 , 0x07}, //02 //sync plority + {0x8b , 0xbc}, + {0xb0 , 0x80}, //globle gain + {0xc0 , 0x40},//Yuv bypass + + //////lsc///////////// + {0xfe , 0x01}, + {0xc2 , 0x38}, + {0xc3 , 0x25}, + {0xc4 , 0x21}, + {0xc8 , 0x19}, + {0xc9 , 0x12}, + {0xca , 0x0e}, + {0xbc , 0x43}, + {0xbd , 0x18}, + {0xbe , 0x1b}, + {0xb6 , 0x40}, + {0xb7 , 0x2e}, + {0xb8 , 0x26}, + {0xc5 , 0x05}, + {0xc6 , 0x03}, + {0xc7 , 0x04}, + {0xcb , 0x00}, + {0xcc , 0x00}, + {0xcd , 0x00}, + {0xbf , 0x14}, + {0xc0 , 0x22}, + {0xc1 , 0x1b}, + {0xb9 , 0x00}, + {0xba , 0x05}, + {0xbb , 0x05}, + {0xaa , 0x35}, + {0xab , 0x33}, + {0xac , 0x33}, + {0xad , 0x25}, + {0xae , 0x22}, + {0xaf , 0x27}, + {0xb0 , 0x1d}, + {0xb1 , 0x20}, + {0xb2 , 0x22}, + {0xb3 , 0x14}, + {0xb4 , 0x15}, + {0xb5 , 0x16}, + {0xd0 , 0x00}, + {0xd2 , 0x07}, + {0xd3 , 0x08}, + {0xd8 , 0x00}, + {0xda , 0x13}, + {0xdb , 0x17}, + {0xdc , 0x00}, + {0xde , 0x0a}, + {0xdf , 0x08}, + {0xd4 , 0x00}, + {0xd6 , 0x00}, + {0xd7 , 0x0c}, + {0xa4 , 0x00}, + {0xa5 , 0x00}, + {0xa6 , 0x00}, + {0xa7 , 0x00}, + {0xa8 , 0x00}, + {0xa9 , 0x00}, + {0xa1 , 0x80}, + {0xa2 , 0x80}, + + //////////cc////////////// + {0xfe , 0x02}, + {0xc0 , 0x01}, + {0xc1 , 0x40}, //Green_cc for d + {0xc2 , 0xfc}, + {0xc3 , 0x05}, + {0xc4 , 0xec}, + {0xc5 , 0x42}, + {0xc6 , 0xf8}, + {0xc7 , 0x40},//for cwf + {0xc8 , 0xf8}, + {0xc9 , 0x06}, + {0xca , 0xfd}, + {0xcb , 0x3e}, + {0xcc , 0xf3}, + {0xcd , 0x36},//for A + {0xce , 0xf6}, + {0xcf , 0x04}, + {0xe3 , 0x0c}, + {0xe4 , 0x44}, + {0xe5 , 0xe5}, + {0xfe , 0x00}, + + ///////awb start //////////////// + //AWB clear + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x10}, // 10 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x20}, // 20 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, // 30 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x40}, // 40 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x50}, // 50 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x60}, // 60 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x70}, // 70 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x80}, // 80 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0x90}, // 90 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xa0}, // a0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xb0}, // b0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xc0}, // c0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4d , 0xd0}, // d0 + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4e , 0x00}, + {0x4f , 0x01}, + /////// awb value//////// + {0xfe , 0x01}, + {0x4f , 0x00}, + {0x4d , 0x30}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x40}, + {0x4e , 0x00}, + {0x4e , 0x80}, + {0x4e , 0x80}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4e , 0x02}, + {0x4d , 0x53}, + {0x4e , 0x08}, + {0x4e , 0x04}, + {0x4d , 0x62}, + {0x4e , 0x10}, + {0x4d , 0x72}, + {0x4e , 0x20}, + {0x4f , 0x01}, + + /////awb//// + {0xfe , 0x01}, + {0x50 , 0x88},//c0//[6]green mode + {0x52 , 0x40}, + {0x54 , 0x60}, + {0x56 , 0x06}, + {0x57 , 0x20}, //pre adjust + {0x58 , 0x01}, + {0x5b , 0x02}, //AWB_gain_delta + {0x61 , 0xaa},//R/G stand + {0x62 , 0xaa},//R/G stand + {0x71 , 0x00}, + {0x74 , 0x10}, //0x//AWB_C_max + {0x77 , 0x08}, // 0x//AWB_p2_x + {0x78 , 0xfd}, //AWB_p2_y + {0x86 , 0x30}, + {0x87 , 0x00}, + {0x88 , 0x04},//06 , 0x//[1]dark mode + {0x8a , 0xc0},//awb move mode + {0x89 , 0x75}, + {0x84 , 0x08}, //0x//auto_window + {0x8b , 0x00}, // 0x//awb compare luma + {0x8d , 0x70}, //awb gain limit R + {0x8e , 0x70},//G + {0x8f , 0xf4},//B + {0xfe , 0x00}, + {0x82 , 0x02},//awb_en + /////////awb end ///////////// + + ///==========asde + {0xfe , 0x01}, + {0x21 , 0xbf}, + {0xfe , 0x02}, + {0xa4 , 0x00},// + {0xa5 , 0x40}, //lsc_th + {0xa2 , 0xa0}, //lsc_dec_slope + {0xa6 , 0x80}, //dd_th + {0xa7 , 0x80}, //ot_th + {0xab , 0x31}, // + {0xa9 , 0x6f}, // + {0xb0 , 0x99}, //0x//edge effect slope low + {0xb1 , 0x34},//edge effect slope low + {0xb3 , 0x80}, //saturation dec slope + {0xde , 0xb6}, // + {0x38 , 0x0f}, // + {0x39 , 0x60}, // + {0xfe , 0x00}, + {0x81 , 0x26}, + {0xfe , 0x02}, + {0x83 , 0x00},// + {0x84 , 0x45},// + ////////////YCP////////// + {0xd1 , 0x38},//saturation_cb + {0xd2 , 0x38},//saturation_Cr + {0xd3 , 0x40},//contrast ? + {0xd4 , 0x80},//contrast center + {0xd5 , 0x00},//luma_offset + {0xdc , 0x30}, + {0xdd , 0xb8},//edge_sa_g,b + {0xfe , 0x00}, + ///////dndd/////////// + {0xfe , 0x02}, + {0x88 , 0x15},//dn_b_base + {0x8c , 0xf6}, //[2]b_in_dark_inc + {0x89 , 0x03}, //dn_c_weight + ////////EE /////////// + {0xfe , 0x02}, + {0x90 , 0x6c},// EEINTP mode1 + {0x97 , 0x45},// edge effect + ////==============RGB Gamma + {0xfe , 0x02}, + {0x15 , 0x0a}, + {0x16 , 0x12}, + {0x17 , 0x19}, + {0x18 , 0x1f}, + {0x19 , 0x2c}, + {0x1a , 0x38}, + {0x1b , 0x42}, + {0x1c , 0x4e}, + {0x1d , 0x63}, + {0x1e , 0x76}, + {0x1f , 0x87}, + {0x20 , 0x96}, + {0x21 , 0xa2}, + {0x22 , 0xb8}, + {0x23 , 0xca}, + {0x24 , 0xd8}, + {0x25 , 0xe3}, + {0x26 , 0xf0}, + {0x27 , 0xf8}, + {0x28 , 0xfd}, + {0x29 , 0xff}, + + ///=================y gamma + {0xfe , 0x02}, + {0x2b , 0x00}, + {0x2c , 0x04}, + {0x2d , 0x09}, + {0x2e , 0x18}, + {0x2f , 0x27}, + {0x30 , 0x37}, + {0x31 , 0x49}, + {0x32 , 0x5c}, + {0x33 , 0x7e}, + {0x34 , 0xa0}, + {0x35 , 0xc0}, + {0x36 , 0xe0}, + {0x37 , 0xff}, + /////1600x1200size// + {0xfe , 0x00},// + {0x90 , 0x01}, //0x//crop enable + {0x95 , 0x04}, //0x//1600x1200 + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + + {0xfe , 0x03}, + {0x42 , 0x40}, + {0x43 , 0x06}, //output buf width + {0x41 , 0x02}, // Pclk_polarity + {0x40 , 0x40}, //00 + {0x17 , 0x00}, //widv + {0xfe , 0x00}, + ////output DVP///// + {0xfe , 0x00}, + {0xb6 , 0x03}, + {0xf7 , 0x15}, + + {0xc8 , 0x00},//close scaler + {0x99 , 0x22},// 1/2 subsample + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 ,0x00}, + + {0x90 , 0x01}, //crop enable + {0x94 , 0x02}, + {0x95 , 0x02}, + {0x96 , 0x58}, + {0x97 , 0x03}, + {0x98 , 0x20}, + {0xfe , 0x00}, + {0x82 , 0xfe}, // fe + {0xf2 , 0x70}, + {0xf3 , 0xff}, + {0xf4 , 0x00}, + {0xf5 , 0x30}, + + #if 0 + ///////// re zao/// + {0xfe,0x00}, + {0x22,0xd0}, + {0xfe,0x01}, + {0x21,0xff}, + {0xfe,0x02}, + {0x8a,0x33}, + {0x8c,0x76}, + {0x8d,0x85}, + {0xa6,0xf0}, + {0xae,0x9f}, + {0xa2,0x90}, + {0xa5,0x40}, + {0xa7,0x30}, + {0xb0,0x88}, + {0x38,0x0b}, + {0x39,0x30}, + {0xfe,0x00}, + {0x87,0xb0}, + + //// small RGB gamma//// + {0xfe , 0x02}, + {0x15 , 0x0b}, + {0x16 , 0x0e}, + {0x17 , 0x10}, + {0x18 , 0x12}, + {0x19 , 0x19}, + {0x1a , 0x21}, + {0x1b , 0x29}, + {0x1c , 0x31}, + {0x1d , 0x41}, + {0x1e , 0x50}, + {0x1f , 0x5f}, + {0x20 , 0x6d}, + {0x21 , 0x79}, + {0x22 , 0x91}, + {0x23 , 0xa5}, + {0x24 , 0xb9}, + {0x25 , 0xc9}, + {0x26 , 0xe1}, + {0x27 , 0xee}, + {0x28 , 0xf7}, + {0x29 , 0xff}, + + ////dark sun///// + {0xfe , 0x02}, + {0x40 , 0x06}, + {0x41 , 0x23}, + {0x42 , 0x3f}, + {0x43 , 0x06}, + {0x44 , 0x00}, + {0x45 , 0x00}, + {0x46 , 0x14}, + {0x47 , 0x09}, + + #endif + + {0x00,0x00}, +}; + + + +/* 1600X1200 UXGA */ +static struct reginfo sensor_uxga[] = +{ + + + {0xfe , 0x00}, + {0xc8 , 0x00}, + {0xf7 , 0x17}, + + {0x99 , 0x11}, // disable sambsample + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 , 0x00}, + + {0x90 , 0x01}, + {0x95 , 0x04}, + {0x96 , 0xb0}, + {0x97 , 0x06}, + {0x98 , 0x40}, + + {0x00 , 0x00}, + + +}; + + + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + + {0x00,0x00}, +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0xfe , 0x00}, + {0xb6 , 0x03}, + {0xf7 , 0x15}, + + {0xc8 , 0x00},//close scaler + {0x99 , 0x22},// 1/2 subsample + {0x9a , 0x06}, + {0x9b , 0x00}, + {0x9c , 0x00}, + {0x9d , 0x00}, + {0x9e , 0x00}, + {0x9f , 0x00}, + {0xa0 , 0x00}, + {0xa1 , 0x00}, + {0xa2 , 0x00}, + + {0x90 , 0x01}, //crop enable + {0x94 , 0x02}, + {0x95 , 0x02}, + {0x96 , 0x58}, + {0x97 , 0x03}, + {0x98 , 0x20}, + {0x00,0x00}, +}; + + + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + + + {0x00 , 0x00}, +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0x00,0x00}, +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + + + {0x00,0x00}, +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + + {0x00,0x00}, +}; + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + + {0x00,0x00}, +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x00,0x00}, +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0xfe, 0x00}, + {0xb3, 0x61}, + {0xb4, 0x40}, + {0xb5, 0x61}, + {0x82, 0xfe}, + {0x00,0x00}, +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x58}, + {0xb4, 0x40}, + {0xb5, 0x50}, + {0x00,0x00}, +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x78}, + {0xb4, 0x40}, + {0xb5, 0x50}, + {0x00,0x00}, +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0x50}, + {0xb4, 0x40}, + {0xb5, 0xa8}, + {0x00,0x00}, + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0xfe, 0x00}, + {0x82, 0xfc}, + {0xb3, 0xa0}, + {0xb4, 0x45}, + {0xb5, 0x40}, + {0x00, 0x00}, +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + + {0xfe, 0x01}, + {0x13, 0x70}, + {0xfe, 0x02}, + {0xd5, 0xe0}, + {0x00, 0x00}, +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + + {0xfe, 0x01}, + {0x13, 0x78}, + {0xfe, 0x02}, + {0xd5, 0xf0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + + {0xfe, 0x01}, + {0x13, 0x80}, + {0xfe, 0x02}, + {0xd5, 0x00}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + {0xfe, 0x01}, + {0x13, 0x88}, + {0xfe, 0x02}, + {0xd5, 0x10}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + {0xfe, 0x01}, + {0x13, 0x90}, + {0xfe, 0x02}, + {0xd5, 0x20}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + {0xfe, 0x01}, + {0x13, 0x98}, + {0xfe, 0x02}, + {0xd5, 0x30}, + + {0x00, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0xfe, 0x00}, + {0x83, 0xe0}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0xfe, 0x00}, + {0x83, 0x12}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0xfe, 0x00}, + {0x83, 0x82}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0xfe, 0x00}, + {0x83, 0x01}, + {0x00, 0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0xfe, 0x00}, + {0x83, 0x62}, + {0x00, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0xfe, 0x00}, + {0x83, 0x52}, + {0x00, 0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + //-3 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + //-2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + //-0.3EV + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + //default + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + // 1 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + // 2 + + {0x00, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + // 3 + + {0x00, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0x00, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0x00, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + //Contrast -3 + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + //Contrast -2 + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + // Contrast -1 + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + //Contrast 0 + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + //Contrast +1 + {0x00, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + //Contrast +2 + {0x00, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + + //Contrast +3 + {0x00, 0x00} + +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0x17 , 0x14}, + {0x00 , 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0x17 , 0x15}, + {0x00 , 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x17 , 0x16}, + {0x00 , 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x17 , 0x17}, + {0x00 , 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ +{0xfe,0x01}, +{0x3e,0x40}, +{0xfe,0x00}, + +{0x00,0x00} +}; + +static struct reginfo sensor_SceneNight[] = +{ +{0xfe,0x01}, +{0x3e,0x60}, +{0xfe,0x00}, +{0x00,0x00} + +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg; + buf[1] = val; + + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + u8 buf[1]; + struct i2c_msg msg[2]; + + buf[0] = reg ; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} + +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != 0) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret,pid = 0; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0xf0, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0xf1, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data); + + + mdelay(300); + + + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static unsigned int shutter_h,shutter_l; +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + int ret1; + + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; +#if 1 +char value; +unsigned int pid=0,shutter,temp_reg; + +#endif + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + winseqe_set_addr = sensor_uxga; + set_w = 1600; + set_h = 1200; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + + if ((winseqe_set_addr == sensor_svga)||(winseqe_set_addr == sensor_vga) ) + { + sensor_write(client, 0xb6, 0x00); // AEC ON + sensor_write(client, 0x03, shutter_h); + sensor_write(client, 0x04, shutter_l); + msleep(50); + printk("set preview for rewrite 0x03"); + + } + ret |= sensor_write_array(client, winseqe_set_addr); +#if 1 + if (winseqe_set_addr == sensor_uxga) + { + sensor_write(client, 0xfe, 0x00); + sensor_write(client, 0xb6, 0x02); // AEC OFF + sensor_read(client, 0x03, &value); + shutter_h=value; + pid |= (value << 8); + sensor_read(client, 0x04, &value); + shutter_l=value; + pid |= (value & 0xff); + shutter=pid; + temp_reg= shutter /2; + if(temp_reg < 1) temp_reg = 1; + sensor_write(client, 0x03, ((temp_reg>>8)&0xff)); + sensor_write(client, 0x04, (temp_reg&0xff)); + } +#endif + + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + msleep(100); //james added +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + set_w = 1600; + set_h = 1200; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gc2035 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret,pid = 0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0xf0, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0xf1, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); +#if CONFIG_SENSOR_Flash + int i; +#endif + int ret = 0; + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + + + diff --git a/drivers/media/video/generic_sensor.c b/drivers/media/video/generic_sensor.c new file mode 100755 index 000000000000..60ece285291e --- /dev/null +++ b/drivers/media/video/generic_sensor.c @@ -0,0 +1,1387 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define CAMMODULE_NAME "rk_cam_sensor" + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_NAME_STRING() sensor->dev_name + +#undef SENSOR_TR +#undef SENSOR_DG +#define SENSOR_TR(format, ...) printk(KERN_ERR "%s(%s:%d): " format"\n", SENSOR_NAME_STRING(),CAMMODULE_NAME,__LINE__, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, "%s(%s:%d): "format"\n", SENSOR_NAME_STRING(),CAMMODULE_NAME,__LINE__,## __VA_ARGS__) + + +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +static const struct rk_sensor_datafmt *generic_sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt, + int n); + +int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val){ + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xffff; + tmp_reg.val_mask = 0xff; + tmp_reg.reg = reg; + tmp_reg.val = val; + return generic_sensor_write(client, &tmp_reg); +} +int sensor_write_reg2val2(struct i2c_client *client, u16 reg,u16 val){ + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xffff; + tmp_reg.val_mask = 0xffff; + tmp_reg.reg = reg; + tmp_reg.val = val; + return generic_sensor_write(client, &tmp_reg); +} +int sensor_write_reg1val1(struct i2c_client *client, u8 reg,u8 val){ + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xff; + tmp_reg.val_mask = 0xff; + tmp_reg.reg = reg; + tmp_reg.val = val; + return generic_sensor_write(client, &tmp_reg); +} +int sensor_write_reg1val2(struct i2c_client *client, u8 reg,u16 val){ + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xff; + tmp_reg.val_mask = 0xffff; + tmp_reg.reg = reg; + tmp_reg.val = val; + return generic_sensor_write(client, &tmp_reg); +} +int sensor_write_reg0val0(struct i2c_client *client, u8 reg,u16 val) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_TR("SENSOR_REGISTER_LEN and SENSOR_VALUE_LEN is 0, please use generic_sensor_write directly!"); + return -1; +} +/* sensor register write */ +int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_reg) +{ + int err,cnt = 0,i; + u8 buf[6]; + struct i2c_msg msg[1]; + u32 i2c_speed; + struct generic_sensor *sensor = to_generic_sensor(client); + + i2c_speed = sensor->info_priv.gI2c_speed; + + err = 0; + switch(sensor_reg->reg){ + case SEQCMD_WAIT_MS: + if (in_atomic()) + mdelay(sensor_reg->val); + else + msleep(sensor_reg->val); + break; + case SEQCMD_WAIT_US: + udelay(sensor_reg->val); + break; + default: + cnt=0; + for (i=2; i>=0; i--) { + if(((sensor_reg->reg_mask) & (0xff<<(i*8)))) { + buf[cnt++] = ((sensor_reg->reg)>>(i*8))&0xff; + } + } + for (i=2; i>=0; i--) { + if(((sensor_reg->val_mask) & (0xff<<(i*8)))) { + buf[cnt++] = ((sensor_reg->val)>>(i*8))&0xff; + } + } + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + msg->len = cnt; + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + err = 0; + goto write_end; + } else { + SENSOR_TR("write reg(0x%x, val:0x%x) failed, try to write again!",sensor_reg->reg, sensor_reg->val); + udelay(10); + } + } + + } + +write_end: + return err; +} + +/* sensor register write buffer */ +int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size) +{ + int err=0,cnt = 0,i; + struct i2c_msg msg[1]; + struct generic_sensor *sensor = to_generic_sensor(client); + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->scl_rate = sensor->info_priv.gI2c_speed; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; + msg->len = buf_size; + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + err = 0; + goto write_end; + } else { + SENSOR_TR("generic_sensor_writebuf failed!"); + udelay(10); + } + } + + +write_end: + return err; +} +int sensor_read_reg1val1(struct i2c_client *client, u8 reg,u8* val){ + + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xff; + tmp_reg.val_mask = 0xff; + tmp_reg.reg = reg; + tmp_reg.val = 0; + if(generic_sensor_read(client, &tmp_reg)==0){ + *val = (u8)(tmp_reg.val & tmp_reg.val_mask); + }else{ + return -1; + } + return 0; +} +int sensor_read_reg2val1(struct i2c_client *client, u16 reg,u8* val){ + + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xffff; + tmp_reg.val_mask = 0xff; + tmp_reg.reg = reg; + tmp_reg.val = 0; + if(generic_sensor_read(client, &tmp_reg)==0){ + *val = (u8)(tmp_reg.val & tmp_reg.val_mask); + }else{ + return -1; + } + return 0; +} +int sensor_read_reg2val2(struct i2c_client *client, u16 reg,u16* val){ + + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xffff; + tmp_reg.val_mask = 0xffff; + tmp_reg.reg = reg; + tmp_reg.val = 0; + if(generic_sensor_read(client, &tmp_reg)==0){ + *val = (u16)(tmp_reg.val & tmp_reg.val_mask); + }else{ + return -1; + } + return 0; +} +int sensor_read_reg1val2(struct i2c_client *client, u8 reg,u16* val){ + + struct rk_sensor_reg tmp_reg; + + tmp_reg.reg_mask = 0xff; + tmp_reg.val_mask = 0xffff; + tmp_reg.reg = reg; + tmp_reg.val = 0; + if(generic_sensor_read(client, &tmp_reg)==0){ + *val = (u16)(tmp_reg.val & tmp_reg.val_mask); + }else{ + return -1; + } + return 0; +} +int sensor_read_reg0val0(struct i2c_client *client, u8 reg,u16 val) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_TR("SENSOR_REGISTER_LEN and SENSOR_VALUE_LEN is 0, please use generic_sensor_read directly!"); + return -1; +} +/* sensor register read */ +int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_reg) +{ + int err,cnt = 0,i,bytes; + u8 buf_reg[3]; + u8 buf_val[3]; + struct i2c_msg msg[2]; + u32 i2c_speed; + struct generic_sensor *sensor = to_generic_sensor(client); + + i2c_speed = sensor->info_priv.gI2c_speed; + + cnt=0; + for (i=2; i>=0; i--) { + if((sensor_reg->reg_mask) & (0xff<<(i*8))) { + buf_reg[cnt++] = ((sensor_reg->reg)>>(i*8))&0xff; + } + } + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf_reg; + msg[0].scl_rate = 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[0].len = cnt; + + cnt=0; + for (i=2; i>=0; i--) { + if((sensor_reg->val_mask) & (0xff<<(i*8))) { + cnt++; + } + } + memset(buf_val,0x00,sizeof(buf_val)); + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf_val; + msg[1].len = cnt; + msg[1].scl_rate = 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 = 1; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + if (err >= 0) { + sensor_reg->val=0; + bytes = 0x00; + for (i=2; i>=0; i--) { + if((sensor_reg->val_mask) & (0xff<<(i*8))) { + sensor_reg->val |= (buf_val[bytes++]<<(i*8)); + } + } + err = 0; + goto read_end; + } else { + SENSOR_TR("read reg(0x%x val:0x%x) failed, try to read again!",sensor_reg->reg, sensor_reg->val); + udelay(10); + } + } +read_end: + return err; +} + +/* write a array of registers */ + int generic_sensor_write_array(struct i2c_client *client, struct rk_sensor_reg *regarray) +{ + int err = 0, cnt; + int i = 0; + bool streamchk; +#if CONFIG_SENSOR_I2C_RDWRCHK + struct rk_sensor_reg check_reg; +#endif + struct generic_sensor *sensor = to_generic_sensor(client); + + if (regarray[0].reg == SEQCMD_STREAMCHK) { + streamchk = true; + i = 1; + } else { + streamchk = false; + i = 0; + } + + cnt = 0; + while ((regarray[i].reg != SEQCMD_END) && (regarray[i].reg != SEQCMD_INTERPOLATION)) + { + if (streamchk) { + if (sensor->info_priv.stream == false) { + err = -1; + SENSOR_DG("sensor is stream off, write array terminated!"); + break; + } + } + + if((sensor->info_priv.gReg_mask != 0) /*&& (regarray[i].reg_mask != 0)*/) + regarray[i].reg_mask = sensor->info_priv.gReg_mask; + if((sensor->info_priv.gVal_mask != 0) /* && (regarray[i].val_mask != 0)*/) + regarray[i].val_mask = sensor->info_priv.gVal_mask; + err = generic_sensor_write(client, &(regarray[i])); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("write failed current reg:0x%x, Write array again !",regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("write array failed!"); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + check_reg.reg_mask = regarray[i].reg_mask; + check_reg.val_mask = regarray[i].val_mask; + check_reg.reg = regarray[i].reg; + check_reg.val =0; + generic_sensor_read(client, &check_reg); + if (check_reg.val!= regarray[i].val) + SENSOR_TR("Reg:0x%x write(0x%x, 0x%x) fail", regarray[i].reg, regarray[i].val, check_reg.val ); + #endif + } + + i++; + } + + +sensor_write_array_end: + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK +int generic_sensor_readchk_array(struct i2c_client *client, struct rk_sensor_reg *regarray) +{ + int cnt; + int i = 0; + struct rk_sensor_reg check_reg; + struct generic_sensor *sensor = to_generic_sensor(client); + + cnt = 0; + while (regarray[i].reg != SEQCMD_END) + { + check_reg.reg_mask = regarray[i].reg_mask; + check_reg.val_mask = regarray[i].val_mask; + check_reg.reg = regarray[i].reg; + check_reg.val =0; + generic_sensor_read(client, &check_reg); + if (check_reg.val!= regarray[i].val) + SENSOR_TR("Reg:0x%x write(0x%x, 0x%x) fail", regarray[i].reg, regarray[i].val, check_reg.val ); + + i++; + } + return 0; +} +#endif + +int generic_sensor_get_max_min_res(struct rk_sensor_sequence* res_array,int num,struct rk_sensor_seq_info * max_real_res, + struct rk_sensor_seq_info * max_res,struct rk_sensor_seq_info *min_res){ + int array_index = 0,err = 0; + + max_real_res->w = max_res->w = 0; + max_real_res->h = max_res->h =0; + min_res->w = min_res->h = 10000; + if(!res_array || num <=0){ + printk("resolution array not valid"); + err = -1; + goto get_end; + } + + //serch min_res + while(array_index data && res_array->data[0].reg != SEQCMD_END){ + if(res_array->gSeq_info.w < min_res->w ||res_array->gSeq_info.h < min_res->h){ + memcpy(min_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info)); + } + if((res_array->gSeq_info.w > max_real_res->w ||res_array->gSeq_info.h > max_real_res->h) + && (res_array->data[0].reg != SEQCMD_INTERPOLATION)){ + memcpy(max_real_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info)); + } + if((res_array->gSeq_info.w > max_res->w ||res_array->gSeq_info.h > max_res->h) + && (res_array->data[0].reg == SEQCMD_INTERPOLATION)){ + memcpy(max_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info)); + } + } + + array_index++; + res_array++; + + } + if((max_res->w < max_real_res->w) || (max_res->h < max_real_res->h)){ + max_res->w = max_real_res->w; + max_res->h = max_real_res->h; + } + printk("min_w = %d,min_h = %d ,max_real_w = %d,max_real_h = %d,max_w = %d,max_h =%d\n", + min_res->w,min_res->h,max_real_res->w,max_real_res->h,max_res->w,max_res->h); + err = 0; +get_end: + return err; +} + + +// return value: -1 means erro; others means res_array array index +//se_w & set_h have been set to between MAX and MIN +static int sensor_try_fmt(struct i2c_client *client,unsigned int *set_w,unsigned int *set_h){ + int array_index = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + struct rk_sensor_sequence* res_array = sensor->info_priv.sensor_series; + int num = sensor->info_priv.num_series; + int tmp_w = 10000,tmp_h = 10000,tmp_index = -1; + int resolution_diff_min=10000*10000,resolution_diff; + + while(array_index < num) { + if ((res_array->data) && (res_array->data[0].reg != SEQCMD_END)) { + + if(res_array->property == SEQUENCE_INIT) { + tmp_index = array_index; + array_index++; + res_array++; + continue; + } + + resolution_diff = abs(res_array->gSeq_info.w*res_array->gSeq_info.h - (*set_w)*(*set_h)); + if (resolution_diffgSeq_info.w; + tmp_h = res_array->gSeq_info.h; + tmp_index = array_index; + + resolution_diff_min = resolution_diff; + } + + } + array_index++; + res_array++; + } + *set_w = tmp_w; + *set_h = tmp_h; + //only has the init array + if((tmp_w == 10000) && (tmp_index != -1)){ + SENSOR_TR("have not other series meet the requirement except init_serie,array_index = %d",tmp_index); + *set_w = sensor->info_priv.sensor_series[tmp_index].gSeq_info.w; + *set_h = sensor->info_priv.sensor_series[tmp_index].gSeq_info.h; + goto try_end; + } + if((*set_w > sensor->info_priv.max_real_res.w) || (*set_h > sensor->info_priv.max_real_res.h)){ + SENSOR_DG("it is a interpolation resolution!(%dx%d:%dx%d)",sensor->info_priv.max_real_res.w + ,sensor->info_priv.max_real_res.h,*set_w,*set_h); + *set_w = sensor->info_priv.max_real_res.w; + *set_h = sensor->info_priv.max_real_res.h; + //find the max_real_res index + res_array = sensor->info_priv.sensor_series; + array_index = 0; + tmp_index = -1; + while(array_index < num){ + if((res_array->data) && (res_array->data[0].reg != SEQCMD_END) && (*set_w ==res_array->gSeq_info.w) && (*set_h ==res_array->gSeq_info.h)){ + if((res_array->property != SEQUENCE_INIT)){ + tmp_index = array_index; + break; + }else{ + tmp_index = array_index; + } + } + array_index++; + res_array++ ; + } + + } +try_end: + return tmp_index; +} +int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + const struct rk_sensor_datafmt *fmt; + int ret = 0; + unsigned int set_w,set_h,ori_w,ori_h; + + ori_w = mf->width; + ori_h = mf->height; + + fmt = generic_sensor_find_datafmt(mf->code, sensor->info_priv.datafmt, + sensor->info_priv.num_datafmt); + if (fmt == NULL) { + fmt = &(sensor->info_priv.curfmt); + mf->code = fmt->code; + } + /* ddl@rock-chips.com : It is query max resolution only. */ + if (mf->reserved[6] == 0xfefe5a5a) { + mf->height = sensor->info_priv.max_res.h ; + mf->width = sensor->info_priv.max_res.w; + ret = 0; + SENSOR_DG("Query resolution: %dx%d",mf->width, mf->height); + goto generic_sensor_try_fmt_end; + } + //use this to filter unsupported resolutions + if (sensor->sensor_cb.sensor_try_fmt_cb_th){ + ret = sensor->sensor_cb.sensor_try_fmt_cb_th(client, mf); + if(ret < 0) + goto generic_sensor_try_fmt_end; + } + if (mf->height > sensor->info_priv.max_res.h) + mf->height = sensor->info_priv.max_res.h; + else if (mf->height < sensor->info_priv.min_res.h) + mf->height = sensor->info_priv.min_res.h; + + if (mf->width > sensor->info_priv.max_res.w) + mf->width = sensor->info_priv.max_res.w; + else if (mf->width < sensor->info_priv.min_res.w) + mf->width = sensor->info_priv.min_res.w; + set_w = mf->width; + set_h = mf->height; + ret = sensor_try_fmt(client,&set_w,&set_h); + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + SENSOR_DG("%dx%d is the closest for %dx%d",ori_w,ori_h,set_w,set_h); +generic_sensor_try_fmt_end: + return ret; +} + +int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival){ + int err = 0,index_tmp; + unsigned int set_w,set_h; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + + if (fival->height > sensor->info_priv.max_res.h|| fival->width > sensor->info_priv.max_res.w){ + SENSOR_TR("this resolution(%dx%d) isn't support!",fival->width,fival->height); + err = -1; + goto enum_frameintervals_end; + } + set_w = fival->width; + set_h = fival->height; + index_tmp = sensor_try_fmt(client,&set_w,&set_h); + fival->discrete.denominator = sensor->info_priv.sensor_series[index_tmp].gSeq_info.fps; + fival->discrete.numerator = 1000; + fival->reserved[1] = (set_w<<16)|set_h; + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + + SENSOR_DG("%dx%d(real:%dx%d) framerate: %d",fival->width,fival->height,set_w,set_h,fival->discrete.denominator); +enum_frameintervals_end: + return err; +} + +static enum hrtimer_restart generic_flash_off_func(struct hrtimer *timer){ + struct rk_flash_timer *fps_timer = container_of(timer, struct rk_flash_timer, timer); + + generic_sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + return 0; +} +/* Find a data format by a pixel code in an array */ +static const struct rk_sensor_datafmt *generic_sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series) { + int ret = 0; + struct generic_sensor *sensor = to_generic_sensor(client); + + + if (sensor->sensor_cb.sensor_softreset_cb) + sensor->sensor_cb.sensor_softreset_cb(client,series); + + /* soft reset */ + ret = generic_sensor_write_array(client,series); + if (ret != 0) { + SENSOR_TR("soft reset failed\n"); + ret = -ENODEV; + } + msleep(1); + return ret; + +} +int generic_sensor_check_id(struct i2c_client *client, struct rk_sensor_reg *series) +{ + int ret,pid = 0,i; + struct generic_sensor *sensor = to_generic_sensor(client); + + if (sensor->sensor_cb.sensor_check_id_cb) + pid = sensor->sensor_cb.sensor_check_id_cb(client,series); + + /* check if it is an sensor sensor */ + while (series->reg != SEQCMD_END) { + + pid <<= 8; + + if (sensor->info_priv.gReg_mask != 0x00) + series->reg_mask = sensor->info_priv.gReg_mask; + if (sensor->info_priv.gVal_mask != 0x00) + series->val_mask = sensor->info_priv.gVal_mask; + + ret = generic_sensor_read(client, series); + if (ret != 0) { + SENSOR_TR("read chip id failed"); + ret = -ENODEV; + goto check_end; + } + + pid |= series->val; + series++; + } + + SENSOR_DG("pid = 0x%x", pid); + + for (i=0; iinfo_priv.chip_id_num; i++) { + if (pid == sensor->info_priv.chip_id[i]) { + sensor->model = sensor->info_priv.chip_ident; + break; + } + } + + if (sensor->model != sensor->info_priv.chip_ident) { + SENSOR_TR("error: mismatched pid = 0x%x\n", pid); + ret = -ENODEV; + goto check_end; + } else { + ret = 0; + } + +check_end: + return ret; +} + +int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + struct rk29camera_platform_data *pdata = icl->priv_usr; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + int ret = 0; + + SENSOR_DG("%s cmd(%d) on(%d)\n",__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_Power: + { + if (icl->power) { + ret = icl->power(icd->pdev, on); + } else { + SENSOR_TR("haven't power callback"); + ret = -EINVAL; + } + break; + } + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + } else { + SENSOR_TR("haven't power down callback"); + ret = -EINVAL; + } + break; + } + case Sensor_Flash: + { + if (pdata && pdata->sensor_ioctrl) { + pdata->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on==Flash_On){ + //flash off after 1.5 secs + hrtimer_cancel(&(sensor->flash_off_timer.timer)); + hrtimer_start(&(sensor->flash_off_timer.timer),ktime_set(0, 1500*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s cmd(%d) is unknown!",__FUNCTION__,cmd); + break; + } + } + + return ret; +} + +int generic_sensor_init(struct v4l2_subdev *sd, u32 val) +{ + int ret = 0; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct generic_sensor *sensor = to_generic_sensor(client); + int array_index = 0; + int num = sensor->info_priv.num_series; + struct soc_camera_link *icl = to_soc_camera_link(icd); + struct rk29camera_platform_data *pdata = icl->priv_usr; + struct rkcamera_platform_data *sensor_device=NULL,*new_camera; + + new_camera = pdata->register_dev_new; + while (strstr(new_camera->dev_name,"end")==NULL) { + if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { + sensor_device = new_camera; + break; + } + new_camera++; + } + + /* ddl@rock-chips.com : i2c speed is config in new_camera_device_ex macro */ + if (sensor_device) { + sensor->info_priv.gI2c_speed = sensor_device->i2c_rate; + sensor->info_priv.mirror = sensor_device->mirror; + } + + if (((sensor_device!=NULL) && Sensor_HasBeen_PwrOff(sensor_device->pwdn_info)) + || (sensor_device == NULL)) { + + //softreset callback + ret = generic_sensor_softreset(client,sensor->info_priv.sensor_SfRstSeqe); + if(ret != 0){ + SENSOR_TR("soft reset failed!"); + goto sensor_INIT_ERR; + } + + while(array_index < num){ + if(sensor->info_priv.sensor_series[array_index].property == SEQUENCE_INIT) + break; + array_index++; + } + if(generic_sensor_write_array(client, sensor->info_priv.sensor_series[array_index].data)!=0){ + SENSOR_TR("write init array failed!"); + ret = -1; + goto sensor_INIT_ERR; + } + if (sensor_device!=NULL) { + sensor_device->pwdn_info &= 0xfe; + if (sensor->sensor_cb.sensor_mirror_cb) + sensor->sensor_cb.sensor_mirror_cb(client, sensor->info_priv.mirror&0x01); + if (sensor->sensor_cb.sensor_flip_cb) + sensor->sensor_cb.sensor_flip_cb(client, sensor->info_priv.mirror&0x02); + } + sensor->info_priv.winseqe_cur_addr = sensor->info_priv.sensor_series + array_index; + + //set focus status ,init focus + sensor->sensor_focus.focus_state = FocusState_Inval; + sensor->sensor_focus.focus_mode = WqCmd_af_invalid; + sensor->sensor_focus.focus_delay = WqCmd_af_invalid; + + } + + if (sensor->sensor_cb.sensor_activate_cb) + sensor->sensor_cb.sensor_activate_cb(client); + + + if (sensor->flash_off_timer.timer.function==NULL) + sensor->flash_off_timer.timer.function = generic_flash_off_func; + + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + if(sensor->sensor_cb.sensor_deactivate_cb) + sensor->sensor_cb.sensor_deactivate_cb(client); + return ret; +} + int generic_sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +unsigned long generic_sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + + unsigned long flags = sensor->info_priv.bus_parameter; + + return soc_camera_apply_sensor_flags(icl, flags); +} +int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct generic_sensor *sensor = to_generic_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.curfmt.code; + mf->colorspace = sensor->info_priv.curfmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct rk_sensor_datafmt *fmt; + struct generic_sensor *sensor = to_generic_sensor(client); + struct rk_sensor_sequence *winseqe_set_addr=NULL; + bool is_capture=(mf->reserved[7]==0xfefe5a5a)?true:false; + int ret=0; + + fmt =generic_sensor_find_datafmt(mf->code, sensor->info_priv.datafmt, + sensor->info_priv.num_datafmt); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + // get the proper series and write the array + ret =generic_sensor_try_fmt(sd, mf); + winseqe_set_addr = sensor->info_priv.sensor_series+ret; + + ret = 0; + if(sensor->info_priv.winseqe_cur_addr->data != winseqe_set_addr->data){ + + if (sensor->sensor_cb.sensor_s_fmt_cb_th) + ret |= sensor->sensor_cb.sensor_s_fmt_cb_th(client, mf, is_capture); + + ret |= generic_sensor_write_array(client, winseqe_set_addr->data); + if (ret != 0) { + SENSOR_TR("set format capability failed"); + goto sensor_s_fmt_end; + } + + if (sensor->sensor_cb.sensor_s_fmt_cb_bh) + ret |= sensor->sensor_cb.sensor_s_fmt_cb_bh(client, mf, is_capture); + sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; + SENSOR_DG("Sensor output is changed to %dx%d",winseqe_set_addr->gSeq_info.w,winseqe_set_addr->gSeq_info.h); + } else { + SENSOR_DG("Sensor output is still %dx%d",winseqe_set_addr->gSeq_info.w,winseqe_set_addr->gSeq_info.h); + } + +//video or capture special process +sensor_s_fmt_end: + return ret; +} + int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = sensor->info_priv.chip_ident; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +int generic_sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s : %x",__FUNCTION__, value); + return 0; + } + + SENSOR_TR("%s valure = %d is invalidate",__FUNCTION__,value); + return -EINVAL; +} +int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + int value = ext_ctrl->value; + + if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { + printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, + ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); + return -EINVAL; + } + + if (value == 3) { /* ddl@rock-chips.com: torch */ + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s : %x",__FUNCTION__, value); + return 0; +} + +int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + struct sensor_v4l2ctrl_info_s *ctrl_info; + int ret = 0; + + ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id); + if (!ctrl_info) { + SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id); + ret = -EINVAL; + } else { + ctrl->value = ctrl_info->cur_value; + } + + return ret; +} + +int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor_v4l2ctrl_info_s *ctrl_info; + struct v4l2_ext_control ext_ctrl; + int ret = 0; + + ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id); + if (!ctrl_info) { + SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id); + ret = -EINVAL; + } else { + + ext_ctrl.id = ctrl->id; + ext_ctrl.value = ctrl->value; + + if (ctrl_info->cb) { + ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl); + } else { + SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ctrl->id); + ret = -EINVAL; + } + } + + return ret; +} + +int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + struct sensor_v4l2ctrl_info_s *ctrl_info; + int ret = 0; + + ctrl_info = sensor_find_ctrl(sensor->ctrls,ext_ctrl->id); + if (!ctrl_info) { + SENSOR_TR("v4l2_control id(0x%x) is invalidate",ext_ctrl->id); + ret = -EINVAL; + } else { + ext_ctrl->value = ctrl_info->cur_value; + } + + return ret; +} + +int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + struct sensor_v4l2ctrl_info_s *ctrl_info; + int ret = 0; + + ctrl_info = sensor_find_ctrl(sensor->ctrls,ext_ctrl->id); + if (!ctrl_info) { + SENSOR_TR("v4l2_ext_control id(0x%x) is invalidate",ext_ctrl->id); + ret = -EINVAL; + } else { + if (ctrl_info->cb) { + ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl); + } else { + SENSOR_TR("v4l2_ext_control id(0x%x) callback isn't exist",ext_ctrl->id); + ret = -EINVAL; + } + } + return 0; +} + int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) + { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + //struct generic_sensor *sensor = to_generic_sensor(client); + int i, error_cnt=0, error_idx=-1; + + for (i=0; icount; i++) { + if (generic_sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } + } +int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct generic_sensor*sensor = to_generic_sensor(client); + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + + if (generic_sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + + +long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct generic_sensor*sensor = to_generic_sensor(client); + int ret = 0; + int i; + bool flash_attach=false; + struct rkcamera_platform_data *new_camera; + + SENSOR_DG("%s cmd: 0x%x ",__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + if(sensor->sensor_cb.sensor_deactivate_cb) + sensor->sensor_cb.sensor_deactivate_cb(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + } else { + SENSOR_TR("RK29_CAM_SUBDEV_IOREQUEST fail"); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + flash_attach = false; + } else { + flash_attach = true; + } + } + + new_camera = sensor->sensor_io_request->register_dev_new; + while (strstr(new_camera->dev_name,"end")==NULL) { + if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { + if (new_camera->flash){ + flash_attach = true; + } else { + flash_attach = false; + } + break; + } + new_camera++; + } + + if (flash_attach==false) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + sensor->sensor_controls[i].id |= 0x80000000; + } + } + } else { + for (i = 0; i < icd->ops->num_controls; i++) { + if(V4L2_CID_FLASH == (icd->ops->controls[i].id&0x7fffffff)){ + sensor->sensor_controls[i].id &= 0x7fffffff; + } + } + } + break; + } + default: + { + SENSOR_TR("%s cmd(0x%x) is unknown !\n",__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; +} + +int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor*sensor = to_generic_sensor(client); + if (index >= sensor->info_priv.num_datafmt) + return -EINVAL; + + *code = sensor->info_priv.datafmt[index].code; + return 0; +} + static void sensor_af_workqueue(struct work_struct *work) +{ + struct rk_sensor_focus_work *sensor_work = container_of(work, struct rk_sensor_focus_work, dwork.work); + struct i2c_client *client = sensor_work->client; + struct generic_sensor*sensor = to_generic_sensor(client); + //struct rk_sensor_focus_cmd_info cmdinfo; + int zone_tm_pos[4]; + int ret = 0; + + SENSOR_DG("%s Enter, cmd:0x%x",__FUNCTION__,sensor_work->cmd); + + switch (sensor_work->cmd) + { + case WqCmd_af_init: + { + if (sensor->sensor_focus.focus_state == FocusState_Inval) { + if(sensor->sensor_focus.focus_cb.sensor_focus_init_cb !=NULL) { + ret = (sensor->sensor_focus.focus_cb.sensor_focus_init_cb)(client); + } + if (ret < 0) { + SENSOR_TR("WqCmd_af_init is failed in sensor_af_workqueue!"); + } else { + if(sensor->sensor_focus.focus_delay != WqCmd_af_invalid) { + generic_sensor_af_workqueue_set(client->dev.platform_data,sensor->sensor_focus.focus_delay,0,false); + sensor->sensor_focus.focus_delay = WqCmd_af_invalid; + } + sensor->sensor_focus.focus_state = FocusState_Inited; + sensor_work->result = WqRet_success; + } + } else { + sensor_work->result = WqRet_success; + SENSOR_DG("sensor af have been inited, WqCmd_af_init is ignore!"); + } + break; + } + case WqCmd_af_single: + { + if(sensor->sensor_focus.focus_cb.sensor_af_single_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_single_cb)(client); + } + if (ret < 0) { + SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!",SENSOR_NAME_STRING()); + sensor_work->result = WqRet_fail; + } else { + sensor_work->result = WqRet_success; + } + break; + } + case WqCmd_af_near_pos: + { + if(sensor->sensor_focus.focus_cb.sensor_af_near_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_near_cb)(client); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else{ + sensor_work->result = WqRet_success; + } + break; + } + case WqCmd_af_far_pos: + { + if(sensor->sensor_focus.focus_cb.sensor_af_far_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_far_cb)(client); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_special_pos: + { + if(sensor->sensor_focus.focus_cb.sensor_af_specialpos_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_specialpos_cb)(client,sensor_work->var); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_continues: + { + if(sensor->sensor_focus.focus_cb.sensor_af_const_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_const_cb)(client); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_update_zone: + { + mutex_lock(&sensor->sensor_focus.focus_lock); + zone_tm_pos[0] = sensor->sensor_focus.focus_zone.lx; + zone_tm_pos[1] = sensor->sensor_focus.focus_zone.ty; + zone_tm_pos[2] = sensor->sensor_focus.focus_zone.rx; + zone_tm_pos[3] = sensor->sensor_focus.focus_zone.dy; + mutex_unlock(&sensor->sensor_focus.focus_lock); + + if(sensor->sensor_focus.focus_cb.sensor_af_zoneupdate_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_zoneupdate_cb)(client,zone_tm_pos); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_close: + { + if(sensor->sensor_focus.focus_cb.sensor_af_close_cb!=NULL){ + ret = (sensor->sensor_focus.focus_cb.sensor_af_close_cb)(client); + } + if (ret < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + default: + SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING()); + break; + } + +set_end: + if (sensor_work->wait == false) { + kfree((void*)sensor_work); + } else { + wake_up(&sensor_work->done); + } + return; +} + + int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor*sensor = to_generic_sensor(client); + struct rk_sensor_focus_work *wk; + int ret=0; + + if (sensor->sensor_focus.sensor_wq == NULL) { + ret = -EINVAL; + goto sensor_af_workqueue_set_end; + } + + wk = kzalloc(sizeof(struct rk_sensor_focus_work), GFP_KERNEL); + if (wk) { + wk->client = client; + INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue); + wk->cmd = cmd; + wk->result = WqRet_inval; + wk->wait = wait; + wk->var = var; + init_waitqueue_head(&wk->done); + + SENSOR_DG("generic_sensor_af_workqueue_set: cmd: %d",cmd); + + /* ddl@rock-chips.com: + * video_lock is been locked in v4l2_ioctl function, but auto focus may slow, + * As a result any other ioctl calls will proceed very, very slowly since each call + * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF + * and VIDIOC_DQBUF is sched. so unlock video_lock here. + */ + if (wait == true) { + queue_delayed_work(sensor->sensor_focus.sensor_wq,&(wk->dwork),0); + mutex_unlock(&icd->video_lock); + if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) { + SENSOR_TR("af cmd(%d) is timeout!",cmd); + } + flush_workqueue(sensor->sensor_focus.sensor_wq); + ret = wk->result; + kfree((void*)wk); + mutex_lock(&icd->video_lock); + } else { + queue_delayed_work(sensor->sensor_focus.sensor_wq,&(wk->dwork),msecs_to_jiffies(10)); + } + } else { + SENSOR_TR("af cmd(%d) ingore,because struct sensor_work malloc failed!",cmd); + ret = -1; + } +sensor_af_workqueue_set_end: + return ret; +} + + +int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct generic_sensor *sensor = to_generic_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + SENSOR_DG("s_stream: %d %d",enable,sensor->sensor_focus.focus_state); + if (enable == 1) { + sensor->info_priv.stream = true; + if (sensor->sensor_focus.sensor_wq) { + if (sensor->sensor_focus.focus_state == FocusState_Inval) { + generic_sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false); + } + } + } else if (enable == 0) { + sensor->info_priv.stream = false; + if (sensor->sensor_focus.sensor_wq) + flush_workqueue(sensor->sensor_focus.sensor_wq); + + } + return 0; +} + diff --git a/drivers/media/video/generic_sensor.h b/drivers/media/video/generic_sensor.h new file mode 100755 index 000000000000..8c674caafa1c --- /dev/null +++ b/drivers/media/video/generic_sensor.h @@ -0,0 +1,1291 @@ +#ifndef __ASM_ARCH_GENERIC_SENSOR_RK_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Camera Sensor driver */ + +#define MIN(x,y) ((xy) ? x: y) + +#define SENSOR_TR(format, ...) printk(KERN_ERR "%s(%d): " format"\n", SENSOR_NAME_STRING(),__LINE__, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, "%s(%d): "format"\n", SENSOR_NAME_STRING(),__LINE__,## __VA_ARGS__) + +//to generic sensor +//a represents a i2c_client type point +#define to_generic_sensor(a) (container_of(i2c_get_clientdata(a), struct generic_sensor, subdev)) + +//to specific sensor +//a represents a generic_sensor type point +#define to_specific_sensor(a) (container_of(a, struct specific_sensor, common_sensor)) + +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +#define SEQCMD_STREAMCHK 0xFA000000 +#define SEQCMD_INVALIDATE 0xFB000000 +#define SEQCMD_INTERPOLATION 0xFC000000 +#define SEQCMD_WAIT_MS 0xFD000000 +#define SEQCMD_WAIT_US 0xFE000000 +#define SEQCMD_END 0xFF000000 + +#define SensorReg0Val0(a,b) {SEQCMD_INVALIDATE,0,0,0} +#define SensorReg1Val1(a,b) {a,b,0xff,0xff} +#define SensorReg2Val1(a,b) {a,b,0xffff,0xff} +#define SensorReg2Val2(a,b) {a,b,0xffff,0xffff} + +#define SensorStreamChk {SEQCMD_STREAMCHK,0,0,0} +#define SensorWaitMs(a) {SEQCMD_WAIT_MS,a,0x00,0x00} +#define SensorWaitUs(a) {SEQCMD_WAIT_US,a,0x00,0x00} +#define SensorEnd {SEQCMD_END,0x00,0x00,0x00} + +#define CFG_WhiteBalance (1<<0) +#define CFG_Brightness (1<<1) +#define CFG_Contrast (1<<2) +#define CFG_Saturation (1<<3) +#define CFG_Effect (1<<4) +#define CFG_Scene (1<<5) +#define CFG_DigitalZoom (1<<6) +#define CFG_Focus (1<<7) +#define CFG_FocusContinues (1<<8) +#define CFG_FocusZone (1<<9) +#define CFG_FocusRelative (1<<10) +#define CFG_FocusAbsolute (1<<11) +#define CFG_FACE_DETECT (1<<12) +#define CFG_Exposure (1<<13) +#define CFG_Flash (1<<14) +#define CFG_Mirror (1<<15) +#define CFG_Flip (1<<16) + +#define CFG_FunChk(a,b) ((a&b)==b) +#define CFG_FunDis(a,b) (a &= (~b)) + +enum rk_sensor_sequence_property { + SEQUENCE_INIT =1, + SEQUENCE_PREVIEW, + SEQUENCE_CAPTURE +}; + +struct rk_sensor_reg { + unsigned int reg; + unsigned int val; + unsigned int reg_mask; + unsigned int val_mask; +}; + +struct rk_sensor_seq_info { + unsigned short w; + unsigned short h; + unsigned short fps; +}; +struct rk_sensor_sequence { + struct rk_sensor_seq_info gSeq_info; + enum rk_sensor_sequence_property property; + struct rk_sensor_reg *data; +}; + +/* only one fixed colorspace per pixelcode */ +struct rk_sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + + +//focus work +enum rk_sensor_focus_wq_cmd +{ + WqCmd_af_invalid = -1, + WqCmd_af_init =1, + WqCmd_af_single, + WqCmd_af_continues, + WqCmd_af_update_zone, + WqCmd_af_close, + WqCmd_af_special_pos, + WqCmd_af_near_pos, + WqCmd_af_far_pos + +}; +enum rk_sensor_focus_sensor_wq_result +{ + WqRet_success = 0, + WqRet_fail = -1, + WqRet_inval = -2 +}; + +enum rk_sensor_focus_state +{ + FocusState_Inval, + FocusState_Inited +}; + +struct rk_sensor_focus_work +{ + struct i2c_client *client; + struct delayed_work dwork; + enum rk_sensor_focus_wq_cmd cmd; + wait_queue_head_t done; + enum rk_sensor_focus_sensor_wq_result result; + bool wait; + int var; +}; + +//focus structs +struct rk_sensor_focus_cb{ + int (*sensor_focus_init_cb)(struct i2c_client *client); + int (*sensor_af_single_cb)(struct i2c_client *client); + int (*sensor_af_const_cb)(struct i2c_client *client); + int (*sensor_af_zoneupdate_cb)(struct i2c_client *client, int *zone_tm_pos); + int (*sensor_af_close_cb)(struct i2c_client *client); + int (*sensor_af_near_cb)(struct i2c_client *client); + int (*sensor_af_far_cb)(struct i2c_client *client); + int (*sensor_af_specialpos_cb)(struct i2c_client *client,int pos); + // +}; +//zone from hal is [-1000,-1000,1000,1000],must map to sensor's zone. +struct rk_sensor_focus_zone{ + int lx; + int ty; + int rx; + int dy; +}; +struct rk_sensor_focus_op_s{ + struct rk_sensor_focus_cb focus_cb; + struct workqueue_struct *sensor_wq; + struct mutex focus_lock; + unsigned int focus_state; + unsigned int focus_mode; //show the focus mode + struct rk_sensor_focus_zone focus_zone; + enum rk_sensor_focus_wq_cmd focus_delay; +}; + + +typedef struct rk_sensor_priv_s +{ + int mirror; + bool snap2preview; + bool video2preview; + struct rk_sensor_sequence* winseqe_cur_addr; + struct rk_sensor_datafmt* datafmt; + int num_datafmt; + struct rk_sensor_datafmt curfmt; + unsigned int funmodule_state; + // + struct rk_sensor_sequence* sensor_series; + int num_series; + + struct rk_sensor_reg* sensor_SfRstSeqe; + struct rk_sensor_reg* sensor_CkIdSeqe; + + struct rk_sensor_seq_info max_res;//maybe interploted + struct rk_sensor_seq_info max_real_res; + struct rk_sensor_seq_info min_res; + unsigned long bus_parameter; + unsigned int *chip_id; + unsigned int chip_id_num; + int chip_ident; + unsigned int gReg_mask; + unsigned int gVal_mask; + unsigned int gI2c_speed; + + bool stream; + +} rk_sensor_info_priv_t; + +struct sensor_v4l2ctrl_info_s { + struct v4l2_queryctrl *qctrl; + int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl); + struct rk_sensor_reg **sensor_Seqe; + int cur_value; + int num_ctrls; +}; + +struct sensor_v4l2ctrl_usr_s { + struct v4l2_queryctrl qctrl; + int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl); + struct rk_sensor_reg **sensor_Seqe; +}; + +struct sensor_ops_cb_s{ + int (*sensor_softreset_cb)(struct i2c_client *client,struct rk_sensor_reg *series); + int (*sensor_check_id_cb)(struct i2c_client *client,struct rk_sensor_reg *series); + int (*sensor_activate_cb)(struct i2c_client *client); + int (*sensor_deactivate_cb)(struct i2c_client *client); + int (*sensor_mirror_cb)(struct i2c_client *client, int mirror); + int (*sensor_flip_cb)(struct i2c_client *client, int flip); + int (*sensor_face_detect_cb)(struct i2c_client *client, int on); + + int (*sensor_s_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture); + int (*sensor_s_fmt_cb_bh)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture); + int (*sensor_try_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf); +}; +//flash off in fixed time to prevent from too hot , zyc +struct rk_flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; + +struct generic_sensor +{ + char dev_name[32]; + struct v4l2_subdev subdev; + struct i2c_client *client; + rk_sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ + + bool is_need_tasklock; + atomic_t tasklock_cnt; + struct soc_camera_ops *sensor_ops; + struct v4l2_queryctrl* sensor_controls; + struct sensor_v4l2ctrl_info_s *ctrls; + struct rk_flash_timer flash_off_timer; + struct sensor_ops_cb_s sensor_cb; + struct rk_sensor_focus_op_s sensor_focus; + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; + +}; + +extern int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series); +extern int generic_sensor_check_id(struct i2c_client *client, struct rk_sensor_reg *series); +extern int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val); +extern int sensor_write_reg2val2(struct i2c_client *client, u16 reg,u16 val); +extern int sensor_write_reg1val1(struct i2c_client *client, u8 reg,u8 val); +extern int sensor_write_reg1val2(struct i2c_client *client, u8 reg,u16 val); +extern int sensor_read_reg1val1(struct i2c_client *client, u8 reg,u8* val); +extern int sensor_read_reg2val1(struct i2c_client *client, u16 reg,u8* val); +extern int sensor_read_reg1val2(struct i2c_client *client, u8 reg,u16* val); +extern int sensor_read_reg2val2(struct i2c_client *client, u16 reg,u16* val); +extern int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_reg); +extern int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_reg); +extern int generic_sensor_write_array(struct i2c_client *client, struct rk_sensor_reg *regarray); +extern int generic_sensor_get_max_min_res(struct rk_sensor_sequence* res_array,int num,struct rk_sensor_seq_info * max_real_res + ,struct rk_sensor_seq_info * max_res,struct rk_sensor_seq_info *min_res); +extern int generic_sensor_init(struct v4l2_subdev *sd, u32 val); +extern int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); +extern int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); +extern int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on); +extern unsigned long generic_sensor_query_bus_param(struct soc_camera_device *icd); +extern int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); +extern int generic_sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +extern int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +extern int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +extern int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl); +extern int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl); +extern int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +extern int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); +extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); +extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,enum v4l2_mbus_pixelcode *code); +extern int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); +extern int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id); +extern int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl); +extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait); +extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable); +extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size); + +static inline int sensor_get_full_width_height(int full_resolution, unsigned short *w, unsigned short *h) +{ + switch (full_resolution) + { + case 0x30000: + { + *w = 640; + *h = 480; + break; + } + + case 0x100000: + { + *w = 1024; + *h = 768; + break; + } + + case 0x130000: + { + *w = 1280; + *h = 1024; + break; + } + + case 0x200000: + { + *w = 1600; + *h = 1200; + break; + } + + case 0x300000: + { + *w = 2048; + *h = 1536; + break; + } + + case 0x500000: + { + *w = 2592; + *h = 1944; + break; + } + + case 0x800000: + { + *w = 3264; + *h = 2448; + break; + } + + default: + return -1; + } + + return 0; +} +static inline int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + int ret; + struct generic_sensor *sensor = to_generic_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) { + ret = -ENODEV; + goto sensor_video_probe_end; + } + + generic_sensor_softreset(client,sensor->info_priv.sensor_SfRstSeqe); + ret = generic_sensor_check_id(client,sensor->info_priv.sensor_CkIdSeqe); + +sensor_video_probe_end: + return ret; +} + +static inline int sensor_regarray_check(struct rk_sensor_reg *data, int reg_num) +{ + struct rk_sensor_reg *data_ptr; + + data_ptr = data+reg_num-1; + if (data_ptr->reg == SEQCMD_END) { + return 0; + } else { + printk(KERN_ERR "%s(%d): data[%d].reg = 0x%x\n",__FUNCTION__,__LINE__,reg_num-1,data_ptr->reg); + return -1; + } + +} + +static inline void sensor_v4l2ctrl_info_init (struct sensor_v4l2ctrl_info_s *ptr, + unsigned int id, + enum v4l2_ctrl_type type, + char *name, + int min, + int max, + int step, + int default_val, + int(*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl), + struct rk_sensor_reg ** sensor_seqe + ) +{ + ptr->qctrl->id = id; + ptr->qctrl->type = type; + strcat(ptr->qctrl->name,name); + ptr->qctrl->minimum = min; + ptr->qctrl->maximum = max; + ptr->qctrl->step = step; + ptr->qctrl->default_value = default_val; + ptr->cur_value = default_val; + ptr->cb = cb; + ptr->sensor_Seqe = sensor_seqe; + return; +} + +static inline struct sensor_v4l2ctrl_info_s* sensor_find_ctrl( + struct sensor_v4l2ctrl_info_s *ops, int id) +{ + int i; + + for (i = 0; i < ops[i].num_ctrls; i++) + if (ops[i].qctrl->id == id) + return &ops[i]; + + return NULL; +} + +static inline void v4l2_querymenu_init (struct v4l2_querymenu *ptr, + unsigned int id, + unsigned int index, + char *name, + unsigned int reserved) +{ + ptr->id = id; + ptr->index = index; + strcat(ptr->name,name); + ptr->reserved = reserved; + + return; +} + +static inline int sensor_v4l2ctrl_replace_cb(struct generic_sensor *sensor, int id, void *cb) +{ + int i,num; + struct sensor_v4l2ctrl_info_s* ctrls; + + ctrls = sensor->ctrls; + num = ctrls->num_ctrls; + for (i=0; iqctrl->id == id) { + ctrls->cb = cb; + break; + } + } + + if (i>=num) { + printk(KERN_ERR "%s(%d): v4l2_control id(0x%x) isn't exist\n",__FUNCTION__,__LINE__,id); + } else { + return 0; + } +} + +static inline int sensor_v4l2ctrl_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + int value = ext_ctrl->value; + int index; + + if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { + printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, + ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); + return -EINVAL; + } + + index = value - ctrl_info->qctrl->minimum; + if (ctrl_info->sensor_Seqe && (ctrl_info->sensor_Seqe[index] != NULL)) { + if (generic_sensor_write_array(client, ctrl_info->sensor_Seqe[index]) != 0) { + printk(KERN_ERR "%s(%d): sensor write array sensor_Seqe failed\n",__FUNCTION__,__LINE__); + return -EINVAL; + } + + ctrl_info->cur_value = value; + return 0; + } else { + printk(KERN_ERR "%s(%d): ctrl_info(id=0x%x)'s sensor_Seqe is invalidate\n",__FUNCTION__,__LINE__,ctrl_info->qctrl->id); + return -EINVAL; + } +} +static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + int value = ext_ctrl->value; + int ret = 0; + struct generic_sensor* sensor = to_generic_sensor(client); + + if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { + printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, + ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); + return -EINVAL; + } + + if(sensor->sensor_focus.focus_state == FocusState_Inval){ + printk(KERN_ERR "%s(%d): focus have not been init success yet\n",__FUNCTION__,__LINE__); + //set focus delay + + switch (ext_ctrl->id) + { + case V4L2_CID_FOCUS_ABSOLUTE: + sensor->sensor_focus.focus_delay = WqCmd_af_special_pos; + break; + case V4L2_CID_FOCUS_RELATIVE: + if (ext_ctrl->value == ctrl_info->qctrl->minimum) + sensor->sensor_focus.focus_delay = WqCmd_af_near_pos; + else + sensor->sensor_focus.focus_delay = WqCmd_af_far_pos; + break; + + case V4L2_CID_FOCUS_AUTO: + sensor->sensor_focus.focus_delay = WqCmd_af_single; + break; + case V4L2_CID_FOCUS_CONTINUOUS: + sensor->sensor_focus.focus_delay = WqCmd_af_continues; + break; + default: + printk(KERN_ERR "%s(%d):not support this focus mode",__FUNCTION__,__LINE__ ); + } + return -EINVAL; + } + switch (ext_ctrl->id) + { + case V4L2_CID_FOCUS_ABSOLUTE: + { + if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){ + //need do something? + + } + if (ctrl_info->cur_value != value) { + if (ext_ctrl->value == ctrl_info->qctrl->minimum) + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_near_pos, value, true); + else if(ext_ctrl->value == ctrl_info->qctrl->maximum) + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_far_pos, value, true); + else + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true); + if(ret == 0){ + ctrl_info->cur_value = value; + } else { + ret = -EINVAL; + printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value); + } + } + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){ + //need do something? + + } + if (ctrl_info->cur_value != value) { + if (ext_ctrl->value == ctrl_info->qctrl->minimum) + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_near_pos, value, true); + else if(ext_ctrl->value == ctrl_info->qctrl->maximum) + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_far_pos, value, true); + if(ret == 0){ + ctrl_info->cur_value = value; + } else { + ret = -EINVAL; + printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value); + } + } + break; + } + case V4L2_CID_FOCUS_AUTO: + { + mutex_lock(&sensor->sensor_focus.focus_lock); + //get focuszone + sensor->sensor_focus.focus_zone.lx = ext_ctrl->rect[0]; + sensor->sensor_focus.focus_zone.ty = ext_ctrl->rect[1]; + sensor->sensor_focus.focus_zone.rx = ext_ctrl->rect[2]; + sensor->sensor_focus.focus_zone.dy = ext_ctrl->rect[3]; + mutex_unlock(&sensor->sensor_focus.focus_lock); + + if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){ + //need do something? + //generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true); + } + if((value==1) || (sensor->sensor_focus.focus_mode==V4L2_CID_FOCUS_AUTO)){ + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_update_zone, value, true); + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_single, value, true); + sensor->sensor_focus.focus_mode = V4L2_CID_FOCUS_AUTO; + }else if(value == 0){ + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true); + } + if(ret != 0){ + ret = -EINVAL; + printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value); + } + break; + + } + case V4L2_CID_FOCUS_CONTINUOUS: + { + if((value==1) && (sensor->sensor_focus.focus_mode!=V4L2_CID_FOCUS_CONTINUOUS)){ + //have to close focus firstly? + //generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true); + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_continues, value, true); + + sensor->sensor_focus.focus_mode = V4L2_CID_FOCUS_CONTINUOUS; + }else if(value ==0){ + ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true); + } + if(ret != 0){ + ret = -EINVAL; + printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value); + } + break; + } + + } + return ret; + +} +static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + int value = ext_ctrl->value; + int ret = 0; + struct generic_sensor* sensor = to_generic_sensor(client); + if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { + printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, + ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); + return -EINVAL; + } + if(ctrl_info->cur_value != value){ + if(sensor->sensor_cb.sensor_face_detect_cb) + ret = (sensor->sensor_cb.sensor_face_detect_cb)(client,value); + if(ret ==0) + ctrl_info->cur_value = value; + } + return ret; +} +#define new_user_v4l2ctrl(ctl_id,ctl_type,ctl_name,ctl_min,ctl_max,ctl_step,default_val,callback,seqe)\ +{\ + .qctrl = {\ + .id = ctl_id,\ + .type = ctl_type,\ + .name = ctl_name,\ + .minimum = ctl_min,\ + .maximum = ctl_max,\ + .step = ctl_step,\ + .default_value = default_val,\ + },\ + .cb = callback,\ + .sensor_Seqe = seqe,\ +} + + +#define new_usr_v4l2menu(menu_id,menu_idx,menu_name,menu_rev)\ + {\ + .id = menu_id,\ + .index = menu_idx,\ + .name = menu_name,\ + .reserved = menu_rev,\ + } + +#define sensor_init_parameters_default_code() static void sensor_init_parameters(struct specific_sensor* spsensor,struct soc_camera_device *icd)\ +{ \ + int num,i; \ + struct rk_sensor_sequence *sensor_series; \ + struct v4l2_queryctrl *controls, *control; \ + struct sensor_v4l2ctrl_info_s *ctrls; \ + struct v4l2_querymenu *menus,*menu; \ + struct soc_camera_link *icl = to_soc_camera_link(icd); \ + struct rk29camera_platform_data *pdata = icl->priv_usr; \ + struct rkcamera_platform_data *sensor_device=NULL,*new_camera; \ + struct rk_sensor_reg *reg_data; \ + int config_flash = 0;\ + int sensor_config;\ + \ + sensor_config = SensorConfiguration;\ + new_camera = pdata->register_dev_new; \ + while (strstr(new_camera->dev_name,"end")==NULL) { \ + if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { \ + sensor_device = new_camera; \ + break; \ + } \ + new_camera++; \ + } \ + \ + if(sensor_device && sensor_device->flash)\ + config_flash = 1;\ + spsensor->common_sensor.info_priv.gReg_mask = 0x00; \ + spsensor->common_sensor.info_priv.gVal_mask = 0x00; \ + for (i=0; icommon_sensor.info_priv.gReg_mask |= (0xff<<(i*8)); \ + for (i=0; icommon_sensor.info_priv.gVal_mask |= (0xff<<(i*8)); \ + spsensor->common_sensor.info_priv.gI2c_speed = 100000; \ + if (sensor_regarray_check(sensor_softreset_data, sizeof(sensor_softreset_data)/sizeof(struct rk_sensor_reg))==0) { \ + spsensor->common_sensor.info_priv.sensor_SfRstSeqe = sensor_softreset_data; \ + } else { \ + SENSOR_TR("sensor_softreset_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_softreset_data"); \ + BUG(); \ + } \ + if (sensor_regarray_check(sensor_check_id_data, sizeof(sensor_check_id_data)/sizeof(struct rk_sensor_reg))==0) { \ + spsensor->common_sensor.info_priv.sensor_CkIdSeqe= sensor_check_id_data; \ + } else { \ + SENSOR_TR("sensor_check_id_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_check_id_data"); \ + BUG(); \ + } \ + spsensor->common_sensor.sensor_cb.sensor_activate_cb = sensor_activate_cb; \ + spsensor->common_sensor.sensor_cb.sensor_deactivate_cb = sensor_deactivate_cb; \ + spsensor->common_sensor.sensor_cb.sensor_mirror_cb = sensor_mirror_cb; \ + spsensor->common_sensor.sensor_cb.sensor_flip_cb = sensor_flip_cb; \ + spsensor->common_sensor.sensor_cb.sensor_s_fmt_cb_th = sensor_s_fmt_cb_th; \ + spsensor->common_sensor.sensor_cb.sensor_s_fmt_cb_bh = sensor_s_fmt_cb_bh; \ + spsensor->common_sensor.sensor_cb.sensor_try_fmt_cb_th = sensor_try_fmt_cb_th;\ + spsensor->common_sensor.sensor_cb.sensor_softreset_cb = sensor_softrest_usr_cb;\ + spsensor->common_sensor.sensor_cb.sensor_check_id_cb = sensor_check_id_usr_cb;\ + if (CFG_FunChk(sensor_config,CFG_FACE_DETECT)) \ + spsensor->common_sensor.sensor_cb.sensor_face_detect_cb = sensor_face_detect_usr_cb; \ + else \ + spsensor->common_sensor.sensor_cb.sensor_face_detect_cb = NULL; \ + \ + num = 4; \ + if (sensor_720p[0].reg != SEQCMD_END) { \ + num++; \ + } \ + if (sensor_1080p[0].reg != SEQCMD_END) { \ + num++; \ + } \ + \ + if (sensor_device && (sensor_device->resolution > CONS(SENSOR_NAME,_FULL_RESOLUTION))) \ + num++; \ + \ + sensor_series = (struct rk_sensor_sequence*)kzalloc(sizeof(struct rk_sensor_sequence)*num,GFP_KERNEL); \ + if (sensor_series == NULL) { \ + SENSOR_TR("malloc sensor_series failed! n"); \ + BUG(); \ + } else { \ + spsensor->common_sensor.info_priv.sensor_series = sensor_series; \ + spsensor->common_sensor.info_priv.num_series = num; \ + \ + sensor_series->gSeq_info.w = SENSOR_PREVIEW_W; \ + sensor_series->gSeq_info.h = SENSOR_PREVIEW_H; \ + sensor_series->gSeq_info.fps = SENSOR_PREVIEW_FPS; \ + sensor_series->property = SEQUENCE_INIT; \ + if (sensor_regarray_check(sensor_init_data, sizeof(sensor_init_data)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_init_data; \ + } else { \ + SENSOR_TR("sensor_init_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_int_data"); \ + BUG(); \ + } \ + \ + sensor_series++; \ + sensor_series->gSeq_info.w = SENSOR_PREVIEW_W; \ + sensor_series->gSeq_info.h = SENSOR_PREVIEW_H; \ + sensor_series->gSeq_info.fps = SENSOR_PREVIEW_FPS; \ + sensor_series->property = SEQUENCE_PREVIEW; \ + if (sensor_regarray_check(sensor_preview_data, sizeof(sensor_preview_data)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_preview_data; \ + } else { \ + SENSOR_TR("sensor_preview_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_preview_data"); \ + BUG(); \ + } \ + \ + sensor_series++; \ + if (sensor_get_full_width_height(CONS(SENSOR_NAME,_FULL_RESOLUTION),&sensor_series->gSeq_info.w,&sensor_series->gSeq_info.h) == 0) { \ + sensor_series->gSeq_info.fps = SENSOR_FULLRES_L_FPS; \ + sensor_series->property = SEQUENCE_CAPTURE; \ + if (sensor_regarray_check(sensor_fullres_lowfps_data, sizeof(sensor_fullres_lowfps_data)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_fullres_lowfps_data; \ + } else { \ + SENSOR_TR("sensor_fullres_lowfps_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_fullres_lowfps_data"); \ + BUG(); \ + } \ + } else { \ + SENSOR_TR("generic_sensor_get_width_height failed!"); \ + BUG(); \ + } \ + \ + sensor_series++; \ + sensor_series->gSeq_info.w = (sensor_series-1)->gSeq_info.w; \ + sensor_series->gSeq_info.h = (sensor_series-1)->gSeq_info.h; \ + sensor_series->gSeq_info.fps = SENSOR_FULLRES_H_FPS; \ + sensor_series->property = SEQUENCE_PREVIEW; \ + if (sensor_regarray_check(sensor_fullres_highfps_data, sizeof(sensor_fullres_highfps_data)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_fullres_highfps_data; \ + } else { \ + SENSOR_TR("sensor_fullres_highfps_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_fullres_highfps_data"); \ + BUG(); \ + } \ + \ + if (sensor_device && (sensor_device->resolution > CONS(SENSOR_NAME,_FULL_RESOLUTION))) { \ + sensor_series++; \ + if (sensor_get_full_width_height(sensor_device->resolution,&sensor_series->gSeq_info.w,&sensor_series->gSeq_info.h) == 0) { \ + sensor_series->gSeq_info.fps = SENSOR_FULLRES_L_FPS; \ + sensor_series->property = SEQUENCE_CAPTURE; \ + reg_data = kzalloc(sizeof(struct rk_sensor_reg)*2,GFP_KERNEL); \ + if (reg_data == NULL) { \ + SENSOR_TR("kzalloc interpolate reg_data failed"); \ + } else { \ + sensor_series->data = reg_data; \ + reg_data->reg = SEQCMD_INTERPOLATION; \ + reg_data++; \ + reg_data->reg = SEQCMD_END; \ + } \ + } else { \ + SENSOR_TR("generic_sensor_get_width_height failed!"); \ + BUG(); \ + } \ + } \ + \ + if (sensor_720p[0].reg != SEQCMD_END) { \ + sensor_series++; \ + sensor_series->gSeq_info.w = 1280; \ + sensor_series->gSeq_info.h = 720; \ + sensor_series->gSeq_info.fps = SENSOR_720P_FPS; \ + sensor_series->property = SEQUENCE_PREVIEW; \ + if (sensor_regarray_check(sensor_720p, sizeof(sensor_720p)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_720p; \ + } else { \ + SENSOR_TR("sensor_720p haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_720p"); \ + BUG(); \ + } \ + } \ + \ + if (sensor_1080p[0].reg != SEQCMD_END) { \ + sensor_series++; \ + sensor_series->gSeq_info.w = 1920; \ + sensor_series->gSeq_info.h = 1080; \ + sensor_series->gSeq_info.fps = SENSOR_1080P_FPS; \ + sensor_series->property = SEQUENCE_PREVIEW; \ + if (sensor_regarray_check(sensor_1080p, sizeof(sensor_1080p)/sizeof(struct rk_sensor_reg))==0) { \ + sensor_series->data = sensor_1080p; \ + } else { \ + SENSOR_TR("sensor_1080p haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_1080p"); \ + BUG(); \ + } \ + } \ + } \ + \ + if (CFG_FunChk(sensor_config,CFG_Focus)) { \ + spsensor->common_sensor.sensor_focus.sensor_wq = create_workqueue(SENSOR_NAME_STRING(_af_workqueue)); \ + if (spsensor->common_sensor.sensor_focus.sensor_wq == NULL) {\ + SENSOR_TR("%s create fail, so auto focus is disable!", SENSOR_NAME_STRING(_af_workqueue));\ + CFG_FunDis(sensor_config,CFG_Focus);\ + CFG_FunDis(sensor_config,CFG_FocusContinues);\ + CFG_FunDis(sensor_config,CFG_FocusZone);\ + CFG_FunDis(sensor_config,CFG_FocusRelative);\ + CFG_FunDis(sensor_config,CFG_FocusAbsolute);\ + }\ + } else {\ + spsensor->common_sensor.sensor_focus.sensor_wq = NULL;\ + CFG_FunDis(sensor_config,CFG_FocusContinues);\ + CFG_FunDis(sensor_config,CFG_FocusZone);\ + CFG_FunDis(sensor_config,CFG_FocusRelative);\ + CFG_FunDis(sensor_config,CFG_FocusAbsolute);\ + }\ +\ + spsensor->common_sensor.info_priv.bus_parameter = SENSOR_BUS_PARAM; \ + spsensor->common_sensor.info_priv.chip_ident = SENSOR_V4L2_IDENT; \ + spsensor->common_sensor.info_priv.chip_id = SensorChipID;\ + spsensor->common_sensor.info_priv.chip_id_num = sizeof(SensorChipID)/sizeof(SensorChipID[0]);\ +\ + generic_sensor_get_max_min_res(spsensor->common_sensor.info_priv.sensor_series , \ + spsensor->common_sensor.info_priv.num_series, \ + &(spsensor->common_sensor.info_priv.max_real_res), \ + &(spsensor->common_sensor.info_priv.max_res), \ + &(spsensor->common_sensor.info_priv.min_res)); \ + \ + num = 0;\ + for (i=0; i<32; i++)\ + if (SensorConfiguration & (1<common_sensor.sensor_controls = controls; \ + sensor_ops.controls = controls; \ + sensor_ops.num_controls = num; \ + \ + ctrls = (struct sensor_v4l2ctrl_info_s*)kzalloc(sizeof(struct sensor_v4l2ctrl_info_s)*num,GFP_KERNEL); \ + if (ctrls == NULL) { \ + SENSOR_TR("kzalloc struct sensor_v4l2ctrl_info_s(%d) failed",num); \ + BUG(); \ + } \ + spsensor->common_sensor.ctrls = ctrls; \ + for (i=0; iqctrl = controls; \ + ctrls->num_ctrls = num; \ + ctrls++; \ + controls++; \ + } \ + controls = spsensor->common_sensor.sensor_controls; \ + ctrls = spsensor->common_sensor.ctrls; \ + \ + num = 0; \ + num += (CFG_FunChk(sensor_config,CFG_WhiteBalance)*5 + CFG_FunChk(sensor_config,CFG_Effect)*6 + CFG_FunChk(sensor_config,CFG_Scene)*2 + config_flash*4); \ + num += sizeof(sensor_menus)/sizeof(struct v4l2_querymenu); \ + menus = (struct v4l2_querymenu*)kzalloc(sizeof(struct v4l2_querymenu)*num,GFP_KERNEL); \ + if (menus == NULL) { \ + SENSOR_TR("kzalloc struct v4l2_querymenu(%d) failed",num); \ + BUG(); \ + } \ + sensor_ops.menus = menus; \ + sensor_ops.num_menus = num; \ + \ + sensor_ops.suspend = sensor_suspend; \ + sensor_ops.resume = sensor_resume; \ + sensor_ops.set_bus_param = generic_sensor_set_bus_param; \ + sensor_ops.query_bus_param = generic_sensor_query_bus_param; \ + \ + if (CFG_FunChk(sensor_config,CFG_WhiteBalance)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU, \ + "White Balance Control",0,4,1,0,sensor_v4l2ctrl_default_cb,sensor_WhiteBalanceSeqe); \ + controls++; \ + ctrls++; \ + \ + v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,0,"auto",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0); \ + menus++; \ + } \ + \ + if (CFG_FunChk(sensor_config,CFG_Brightness)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER, \ + "Brightness Control",-3,2,1,0,sensor_v4l2ctrl_default_cb,sensor_BrightnessSeqe); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Effect)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU, \ + "Effect Control",0,5,1,0,sensor_v4l2ctrl_default_cb,sensor_EffectSeqe); \ + controls++; \ + ctrls++; \ + \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,0,"none",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,1,"mono",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,2,"negative",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,3,"sepia",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,4,"posterize",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_EFFECT,5,"aqua",0); \ + menus++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Exposure)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER, \ + "Exposure Control",0,6,1,0,sensor_v4l2ctrl_default_cb,sensor_ExposureSeqe); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Saturation)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_SATURATION,V4L2_CTRL_TYPE_INTEGER, \ + "Saturation Control",0,2,1,0,sensor_v4l2ctrl_default_cb,sensor_SaturationSeqe); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Contrast)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER, \ + "Contrast Control",-3,3,1,0,sensor_v4l2ctrl_default_cb,sensor_ContrastSeqe); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Mirror)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_HFLIP,V4L2_CTRL_TYPE_BOOLEAN, \ + "Mirror Control",0,1,1,0,sensor_v4l2ctrl_mirror_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Flip)) { \ + ctrls->qctrl = controls; \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_VFLIP,V4L2_CTRL_TYPE_BOOLEAN, \ + "Flip Control",0,1,1,0,sensor_v4l2ctrl_flip_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Scene)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU, \ + "Scene Control",0,1,1,0,sensor_v4l2ctrl_default_cb,sensor_SceneSeqe); \ + controls++; \ + ctrls++; \ + \ + v4l2_querymenu_init(menus,V4L2_CID_SCENE,0,"auto",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_SCENE,1,"night",0); \ + menus++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_Focus)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_AUTO,V4L2_CTRL_TYPE_BOOLEAN, \ + "Focus Control",0,2,1,0,sensor_focus_default_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + \ + if (CFG_FunChk(sensor_config,CFG_FocusRelative)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_RELATIVE,V4L2_CTRL_TYPE_INTEGER, \ + "Focus Control",-1,1,1,0,sensor_focus_default_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + \ + if (CFG_FunChk(sensor_config,CFG_FocusAbsolute)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_ABSOLUTE,V4L2_CTRL_TYPE_INTEGER, \ + "Focus Control",0,255,1,125,sensor_focus_default_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_FocusZone)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUSZONE,V4L2_CTRL_TYPE_BOOLEAN, \ + "Focus Control",0,1,1,0,NULL,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_FocusContinues)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_CONTINUOUS,V4L2_CTRL_TYPE_BOOLEAN, \ + "Focus Control",0,1,1,0,sensor_focus_default_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (CFG_FunChk(sensor_config,CFG_FACE_DETECT)) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FACEDETECT,V4L2_CTRL_TYPE_BOOLEAN, \ + "FaceDEt Control",0,1,1,0,sensor_face_detect_default_cb,NULL); \ + controls++; \ + ctrls++; \ + } \ + if (config_flash) { \ + sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FLASH,V4L2_CTRL_TYPE_MENU, \ + "Flash Control",0,3,1,0,sensor_v4l2ctrl_flash_cb,NULL); \ + controls++; \ + ctrls++; \ + \ + v4l2_querymenu_init(menus,V4L2_CID_FLASH,0,"off",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_FLASH,1,"auto",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_FLASH,2,"on",0); \ + menus++; \ + v4l2_querymenu_init(menus,V4L2_CID_FLASH,3,"torch",0); \ + menus++; \ + } \ + \ + for (i=0; i<(sizeof(sensor_controls)/sizeof(struct sensor_v4l2ctrl_usr_s)); i++) { \ + \ + control = spsensor->common_sensor.sensor_controls; \ + while (control < controls) \ + { \ + if (control->id == sensor_controls[i].qctrl.id) { \ + control->id = 0xffffffff; \ + } \ + control++; \ + } \ + \ + memcpy(controls, &sensor_controls[i].qctrl,sizeof(struct v4l2_queryctrl)); \ + controls++; \ + \ + ctrls->sensor_Seqe = sensor_controls[i].sensor_Seqe; \ + ctrls->cur_value = sensor_controls[i].qctrl.default_value; \ + ctrls->cb = sensor_controls[i].cb; \ + ctrls++; \ + } \ + \ + for (i=0; i<(sizeof(sensor_menus)/sizeof(struct v4l2_querymenu)); i++) { \ + num = sensor_ops.num_menus - sizeof(sensor_menus)/sizeof(struct v4l2_querymenu); \ + menu = sensor_ops.menus; \ + while (num--) { \ + if (menu->id == sensor_menus[i].id) { \ + menu->id = 0xffffffff; \ + } \ + menu++; \ + } \ + \ + memcpy(menus, &sensor_menus[i],sizeof(struct v4l2_querymenu)); \ + menus++; \ + } \ + \ + spsensor->common_sensor.info_priv.datafmt = sensor_colour_fmts; \ + spsensor->common_sensor.info_priv.num_datafmt = ARRAY_SIZE(sensor_colour_fmts); \ + spsensor->common_sensor.sensor_ops = &sensor_ops; \ + icd->ops = &sensor_ops; \ + spsensor->common_sensor.info_priv.curfmt= sensor_colour_fmts[0]; \ + \ + if (config_flash) { \ + hrtimer_init(&(spsensor->common_sensor.flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); \ + spsensor->common_sensor.flash_off_timer.icd = icd; \ + } \ + if(CFG_FunChk(sensor_config,CFG_Focus)) { \ + mutex_init(&spsensor->common_sensor.sensor_focus.focus_lock); \ + spsensor->common_sensor.sensor_focus.focus_mode = WqCmd_af_invalid; \ + spsensor->common_sensor.sensor_focus.focus_state = FocusState_Inval;\ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_focus_init_cb = sensor_focus_init_usr_cb; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_single_cb = sensor_focus_af_single_usr_cb; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_near_cb = sensor_focus_af_near_usr_cb; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_far_cb = sensor_focus_af_far_usr_cb; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_specialpos_cb = sensor_focus_af_specialpos_usr_cb; \ + if(CFG_FunChk(sensor_config,CFG_FocusContinues))\ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_const_cb = sensor_focus_af_const_usr_cb; \ + if(CFG_FunChk(sensor_config,CFG_FocusZone)) \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_zoneupdate_cb = sensor_focus_af_zoneupdate_usr_cb; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_close_cb = sensor_focus_af_close_usr_cb; \ + }else{ \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_focus_init_cb = NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_single_cb = NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_near_cb = NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_far_cb =NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_specialpos_cb =NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_const_cb =NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_zoneupdate_cb =NULL; \ + spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_close_cb =NULL; \ + } \ + \ + memcpy(spsensor->common_sensor.dev_name,dev_name(icd->pdev), sizeof(spsensor->common_sensor.dev_name)-1); \ + sensor_init_parameters_user(spsensor,icd); \ +} + + +#define sensor_v4l2_struct_initialization() static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\ + .init = generic_sensor_init,\ + .g_ctrl = generic_sensor_g_control,\ + .s_ctrl = generic_sensor_s_control,\ + .g_ext_ctrls = generic_sensor_g_ext_controls,\ + .s_ext_ctrls = generic_sensor_s_ext_controls,\ + .g_chip_ident = generic_sensor_g_chip_ident,\ + .ioctl = generic_sensor_ioctl,\ +};\ +\ +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\ + .s_mbus_fmt = generic_sensor_s_fmt,\ + .g_mbus_fmt = generic_sensor_g_fmt,\ + .try_mbus_fmt = generic_sensor_try_fmt,\ + .enum_mbus_fmt = generic_sensor_enum_fmt,\ + .enum_frameintervals = generic_sensor_enum_frameintervals,\ + .s_stream = generic_sensor_s_stream,\ +};\ +static struct v4l2_subdev_ops sensor_subdev_ops = {\ + .core = &sensor_subdev_core_ops,\ + .video = &sensor_subdev_video_ops,\ +};\ +\ +static const struct i2c_device_id sensor_id[] = {\ + {SENSOR_NAME_STRING(), 0 },\ + {"\0",0}\ +};\ +\ +MODULE_DEVICE_TABLE(i2c, sensor_id); + + +#define sensor_probe_default_code() static int sensor_probe(struct i2c_client *client,\ + const struct i2c_device_id *did)\ +{\ + struct specific_sensor *spsensor=NULL;\ + struct soc_camera_device *icd = client->dev.platform_data;\ + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);\ + struct soc_camera_link *icl;\ + int ret=0;\ +\ + if (!icd) {\ + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());\ + ret = -EINVAL;\ + goto sensor_probe_end;\ + }\ +\ + icl = to_soc_camera_link(icd);\ + if (!icl) {\ + SENSOR_TR("driver needs platform data! But it is failed\n");\ + ret = -EINVAL;\ + goto sensor_probe_end;\ + }\ +\ + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {\ + SENSOR_TR("I2C-Adapter doesn't support I2C_FUNC_I2C\n");\ + ret = -EIO;\ + goto sensor_probe_end;\ + }\ +\ + spsensor = kzalloc(sizeof(struct specific_sensor), GFP_KERNEL);\ + if (!spsensor) {\ + ret = -ENOMEM;\ + SENSOR_TR("kzalloc failed\n");\ + goto sensor_probe_end;\ + }\ +\ + v4l2_i2c_subdev_init(&spsensor->common_sensor.subdev, client, &sensor_subdev_ops);\ + sensor_init_parameters(spsensor,icd);\ +\ + ret = sensor_video_probe(icd, client);\ +\ +sensor_probe_end:\ + if (ret != 0) {\ + if (icd->ops) {\ + if (icd->ops->controls) {\ + kfree(icd->ops->controls);\ + icd->ops->controls = NULL;\ + }\ + if (icd->ops->menus) {\ + kfree(icd->ops->menus);\ + icd->ops->menus = NULL;\ + }\ + icd->ops = NULL;\ + }\ + i2c_set_clientdata(client, NULL);\ + client->driver = NULL;\ + if (spsensor) {\ + kfree(spsensor);\ + }\ + spsensor = NULL;\ + }\ + return ret;\ +} + +#define sensor_remove_default_code() static int sensor_remove(struct i2c_client *client)\ +{\ + struct generic_sensor*sensor = to_generic_sensor(client);\ + struct soc_camera_device *icd = client->dev.platform_data;\ + struct specific_sensor *spsensor = to_specific_sensor(sensor);\ + int sensor_config;\ +\ + sensor_config = SensorConfiguration;\ + if(CFG_FunChk(sensor_config,CFG_Focus)){ \ + if (sensor->sensor_focus.sensor_wq) {\ + destroy_workqueue(sensor->sensor_focus.sensor_wq);\ + sensor->sensor_focus.sensor_wq = NULL;\ + }\ + }\ + if (icd->ops) {\ + if (icd->ops->controls) {\ + kfree(icd->ops->controls);\ + icd->ops->controls = NULL;\ + }\ + if (icd->ops->menus) {\ + kfree(icd->ops->menus);\ + icd->ops->menus = NULL;\ + }\ + icd->ops = NULL;\ + }\ + i2c_set_clientdata(client, NULL);\ + client->driver = NULL;\ + if (spsensor) {\ + kfree(spsensor);\ + }\ + spsensor = NULL;\ + return 0;\ +} + + +#define sensor_driver_default_module_code() static struct i2c_driver sensor_i2c_driver = {\ + .driver = {\ + .name = SENSOR_NAME_STRING(),\ + },\ + .probe = sensor_probe,\ + .remove = sensor_remove,\ + .id_table = sensor_id,\ +};\ +\ +static int __init sensor_mod_init(void)\ +{\ + return i2c_add_driver(&sensor_i2c_driver);\ +}\ +\ +static void __exit sensor_mod_exit(void)\ +{\ + i2c_del_driver(&sensor_i2c_driver);\ +}\ +\ +device_initcall_sync(sensor_mod_init);\ +module_exit(sensor_mod_exit);\ +\ +MODULE_DESCRIPTION(SENSOR_NAME_STRING(sensor driver));\ +MODULE_AUTHOR("");\ +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/media/video/gt2005.c b/drivers/media/video/gt2005.c index d9915c3aebd1..66f55ac41b66 100755 --- a/drivers/media/video/gt2005.c +++ b/drivers/media/video/gt2005.c @@ -1,3727 +1,1242 @@ +#include "generic_sensor.h" /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_GT2005 -#define SENSOR_V4L2_IDENT V4L2_IDENT_GT2005 -#define SENSOR_ID 0x5138 -#define SENSOR_MIN_WIDTH 640 -#define SENSOR_MIN_HEIGHT 480 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -struct reginfo -{ - u16 reg; - u8 val; -}; - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_GT2005_USER_DEFINED_SERIES -#include "gt2005_user_series.c" -#else -/* init 352X288 SVGA */ -static struct reginfo sensor_init_data[] = -{ - {0x0101 , 0x00}, - {0x0103 , 0x00}, - {0x0105 , 0x00}, - {0x0106 , 0xF0}, - {0x0107 , 0x00}, - {0x0108 , 0x1C}, - {0x0109 , 0x01}, - {0x010A , 0x00}, - {0x010B , 0x00}, - {0x010C , 0x00}, - {0x010D , 0x08}, - {0x010E , 0x00}, - {0x010F , 0x08}, - {0x0110 , 0x06}, - {0x0111 , 0x40}, - {0x0112 , 0x04}, - {0x0113 , 0xB0}, -{0x0114 , 0x00}, - {0x0115 , 0x00}, - {0x0116 , 0x02}, - {0x0117 , 0x00}, -{0x0118 , 0x67}, - {0x0119 , 0x02}, - {0x011A , 0x04}, - {0x011B , 0x01}, -{0x011C , 0x01}, -{0x011D , 0x02}, -{0x011E , 0x00}, -{0x011F , 0x00}, -{0x0120 , 0x1C}, -{0x0121 , 0x00}, -{0x0122 , 0x04}, -{0x0123 , 0x00}, -{0x0124 , 0x00}, -{0x0125 , 0x00}, -{0x0126 , 0x00}, -{0x0127 , 0x00}, -{0x0128 , 0x00}, -{0x0200 , 0x00}, -{0x0201 , 0x00}, -{0x0202 , 0x40}, -{0x0203 , 0x00}, -{0x0204 , 0x03}, -{0x0205 , 0x1F}, -{0x0206 , 0x0B}, -{0x0207 , 0x20}, -{0x0208 , 0x00}, -{0x0209 , 0x2A}, -{0x020A , 0x01}, -{0x020B , 0x48}, -{0x020C , 0x64}, -{0x020D , 0xC8}, -{0x020E , 0xBC}, -{0x020F , 0x08}, -{0x0210 , 0xD6}, -{0x0211 , 0x00}, -{0x0212 , 0x20}, -{0x0213 , 0x81}, -{0x0214 , 0x15}, -{0x0215 , 0x00}, -{0x0216 , 0x00}, -{0x0217 , 0x00}, -{0x0218 , 0x46}, -{0x0219 , 0x30}, -{0x021A , 0x03}, -{0x021B , 0x28}, -{0x021C , 0x02}, -{0x021D , 0x60}, -{0x021E , 0x00}, -{0x021F , 0x00}, -{0x0220 , 0x08}, -{0x0221 , 0x08}, -{0x0222 , 0x04}, -{0x0223 , 0x00}, -{0x0224 , 0x1F}, -{0x0225 , 0x1E}, -{0x0226 , 0x18}, -{0x0227 , 0x1D}, -{0x0228 , 0x1F}, -{0x0229 , 0x1F}, -{0x022A , 0x01}, -{0x022B , 0x04}, -{0x022C , 0x05}, -{0x022D , 0x05}, -{0x022E , 0x04}, -{0x022F , 0x03}, -{0x0230 , 0x02}, -{0x0231 , 0x1F}, -{0x0232 , 0x1A}, -{0x0233 , 0x19}, -{0x0234 , 0x19}, -{0x0235 , 0x1B}, -{0x0236 , 0x1F}, -{0x0237 , 0x04}, -{0x0238 , 0xEE}, -{0x0239 , 0xFF}, -{0x023A , 0x00}, -{0x023B , 0x00}, -{0x023C , 0x00}, -{0x023D , 0x00}, -{0x023E , 0x00}, -{0x023F , 0x00}, -{0x0240 , 0x00}, -{0x0241 , 0x00}, -{0x0242 , 0x00}, -{0x0243 , 0x21}, -{0x0244 , 0x42}, -{0x0245 , 0x53}, -{0x0246 , 0x54}, -{0x0247 , 0x54}, -{0x0248 , 0x54}, -{0x0249 , 0x33}, -{0x024A , 0x11}, -{0x024B , 0x00}, -{0x024C , 0x00}, -{0x024D , 0xFF}, -{0x024E , 0xEE}, -{0x024F , 0xDD}, -{0x0250 , 0x00}, -{0x0251 , 0x00}, -{0x0252 , 0x00}, -{0x0253 , 0x00}, -{0x0254 , 0x00}, -{0x0255 , 0x00}, -{0x0256 , 0x00}, -{0x0257 , 0x00}, -{0x0258 , 0x00}, -{0x0259 , 0x00}, -{0x025A , 0x00}, -{0x025B , 0x00}, -{0x025C , 0x00}, -{0x025D , 0x00}, -{0x025E , 0x00}, -{0x025F , 0x00}, -{0x0260 , 0x00}, -{0x0261 , 0x00}, -{0x0262 , 0x00}, -{0x0263 , 0x00}, -{0x0264 , 0x00}, -{0x0265 , 0x00}, -{0x0266 , 0x00}, -{0x0267 , 0x00}, -{0x0268 , 0x8F}, -{0x0269 , 0xA3}, -{0x026A , 0xB4}, -{0x026B , 0x90}, -{0x026C , 0x00}, -{0x026D , 0xD0}, -{0x026E , 0x60}, -{0x026F , 0xA0}, -{0x0270 , 0x40}, -{0x0300 , 0x81}, -{0x0301 , 0x80}, -{0x0302 , 0x22}, -{0x0303 , 0x06}, -{0x0304 , 0x03}, -{0x0305 , 0x83}, -{0x0306 , 0x00}, -{0x0307 , 0x22}, -{0x0308 , 0x00}, -{0x0309 , 0x55}, -{0x030A , 0x55}, -{0x030B , 0x55}, -{0x030C , 0x54}, -{0x030D , 0x1F}, -{0x030E , 0x13}, -{0x030F , 0x10}, -{0x0310 , 0x04}, -{0x0311 , 0xFF}, -{0x0312 , 0x08}, -{0x0313 , 0x28}, -{0x0314 , 0x66}, -{0x0315 , 0x16}, -{0x0316 , 0x26}, -{0x0317 , 0x02}, -{0x0318 , 0x08}, -{0x0319 , 0x0C}, -{0x031A , 0x81}, -{0x031B , 0x00}, -{0x031C , 0x3D}, -{0x031D , 0x00}, -{0x031E , 0xF9}, -{0x031F , 0x00}, -{0x0320 , 0x24}, -{0x0321 , 0x14}, -{0x0322 , 0x1A}, -{0x0323 , 0x24}, -{0x0324 , 0x08}, -{0x0325 , 0xF0}, -{0x0326 , 0x30}, -{0x0327 , 0x17}, -{0x0328 , 0x11}, -{0x0329 , 0x22}, -{0x032A , 0x2F}, -{0x032B , 0x21}, -{0x032C , 0xDA}, -{0x032D , 0x10}, -{0x032E , 0xEA}, -{0x032F , 0x18}, -{0x0330 , 0x29}, -{0x0331 , 0x25}, -{0x0332 , 0x12}, -{0x0333 , 0x0F}, -{0x0334 , 0xE0}, -{0x0335 , 0x13}, -{0x0336 , 0xFF}, -{0x0337 , 0x20}, -{0x0338 , 0x46}, -{0x0339 , 0x04}, -{0x033A , 0x04}, -{0x033B , 0xFF}, -{0x033C , 0x01}, -{0x033D , 0x00}, -{0x033E , 0x03}, -{0x033F , 0x28}, -{0x0340 , 0x02}, -{0x0341 , 0x60}, -{0x0342 , 0xAC}, -{0x0343 , 0x97}, -{0x0344 , 0x7F}, -{0x0400 , 0xE8}, -{0x0401 , 0x40}, -{0x0402 , 0x00}, -{0x0403 , 0x00}, -{0x0404 , 0xF8}, -{0x0405 , 0x03}, -{0x0406 , 0x03}, -{0x0407 , 0x85}, -{0x0408 , 0x44}, -{0x0409 , 0x1F}, -{0x040A , 0x40}, -{0x040B , 0x33}, -{0x040C , 0xA0}, -{0x040D , 0x00}, -{0x040E , 0x00}, -{0x040F , 0x00}, -{0x0410 , 0x0D}, -{0x0411 , 0x0D}, -{0x0412 , 0x0C}, -{0x0413 , 0x04}, -{0x0414 , 0x00}, -{0x0415 , 0x00}, -{0x0416 , 0x07}, -{0x0417 , 0x09}, -{0x0418 , 0x16}, -{0x0419 , 0x14}, -{0x041A , 0x11}, -{0x041B , 0x14}, -{0x041C , 0x07}, -{0x041D , 0x07}, -{0x041E , 0x06}, -{0x041F , 0x02}, -{0x0420 , 0x42}, -{0x0421 , 0x42}, -{0x0422 , 0x47}, -{0x0423 , 0x39}, -{0x0424 , 0x3E}, -{0x0425 , 0x4D}, -{0x0426 , 0x46}, -{0x0427 , 0x3A}, -{0x0428 , 0x21}, -{0x0429 , 0x21}, -{0x042A , 0x26}, -{0x042B , 0x1C}, -{0x042C , 0x25}, -{0x042D , 0x25}, -{0x042E , 0x28}, -{0x042F , 0x20}, -{0x0430 , 0x3E}, -{0x0431 , 0x3E}, -{0x0432 , 0x33}, -{0x0433 , 0x2E}, -{0x0434 , 0x54}, -{0x0435 , 0x53}, -{0x0436 , 0x3C}, -{0x0437 , 0x51}, -{0x0438 , 0x2B}, -{0x0439 , 0x2B}, -{0x043A , 0x38}, -{0x043B , 0x22}, -{0x043C , 0x3B}, -{0x043D , 0x3B}, -{0x043E , 0x31}, -{0x043F , 0x37}, -{0x0440 , 0x00}, -{0x0441 , 0x4B}, -{0x0442 , 0x00}, -{0x0443 , 0x00}, -{0x0444 , 0x31}, -{0x0445 , 0x00}, -{0x0446 , 0x00}, -{0x0447 , 0x00}, -{0x0448 , 0x00}, -{0x0449 , 0x00}, -{0x044A , 0x00}, -{0x044D , 0xE0}, -{0x044E , 0x05}, -{0x044F , 0x07}, -{0x0450 , 0x00}, -{0x0451 , 0x00}, -{0x0452 , 0x00}, -{0x0453 , 0x00}, -{0x0454 , 0x00}, -{0x0455 , 0x00}, -{0x0456 , 0x00}, -{0x0457 , 0x00}, -{0x0458 , 0x00}, -{0x0459 , 0x00}, -{0x045A , 0x00}, -{0x045B , 0x00}, -{0x045C , 0x00}, -{0x045D , 0x00}, -{0x045E , 0x00}, -{0x045F , 0x00}, -{0x0460 , 0x80}, -{0x0461 , 0x10}, -{0x0462 , 0x10}, -{0x0463 , 0x10}, -{0x0464 , 0x08}, -{0x0465 , 0x08}, -{0x0466 , 0x11}, -{0x0467 , 0x09}, -{0x0468 , 0x23}, -{0x0469 , 0x2A}, -{0x046A , 0x2A}, -{0x046B , 0x47}, -{0x046C , 0x52}, -{0x046D , 0x42}, -{0x046E , 0x36}, -{0x046F , 0x46}, -{0x0470 , 0x3A}, -{0x0471 , 0x32}, -{0x0472 , 0x32}, -{0x0473 , 0x38}, -{0x0474 , 0x3D}, -{0x0475 , 0x2F}, -{0x0476 , 0x29}, -{0x0477 , 0x48}, -{0x0600 , 0x00}, -{0x0601 , 0x24}, -{0x0602 , 0x45}, -{0x0603 , 0x0E}, -{0x0604 , 0x14}, -{0x0605 , 0x2F}, -{0x0606 , 0x01}, -{0x0607 , 0x0E}, -{0x0608 , 0x0E}, -{0x0609 , 0x37}, -{0x060A , 0x18}, -{0x060B , 0xA0}, -{0x060C , 0x20}, -{0x060D , 0x07}, -{0x060E , 0x47}, -{0x060F , 0x90}, -{0x0610 , 0x06}, -{0x0611 , 0x0C}, -{0x0612 , 0x28}, -{0x0613 , 0x13}, -{0x0614 , 0x0B}, -{0x0615 , 0x10}, -{0x0616 , 0x14}, -{0x0617 , 0x19}, -{0x0618 , 0x52}, -{0x0619 , 0xA0}, -{0x061A , 0x11}, -{0x061B , 0x33}, -{0x061C , 0x56}, -{0x061D , 0x20}, -{0x061E , 0x28}, -{0x061F , 0x2B}, -{0x0620 , 0x22}, -{0x0621 , 0x11}, -{0x0622 , 0x75}, -{0x0623 , 0x49}, -{0x0624 , 0x6E}, -{0x0625 , 0x80}, -{0x0626 , 0x02}, -{0x0627 , 0x0C}, -{0x0628 , 0x51}, -{0x0629 , 0x25}, -{0x062A , 0x01}, -{0x062B , 0x3D}, -{0x062C , 0x04}, -{0x062D , 0x01}, -{0x062E , 0x0C}, -{0x062F , 0x2C}, -{0x0630 , 0x0D}, -{0x0631 , 0x14}, -{0x0632 , 0x12}, -{0x0633 , 0x34}, -{0x0634 , 0x00}, -{0x0635 , 0x00}, -{0x0636 , 0x00}, -{0x0637 , 0xB1}, -{0x0638 , 0x22}, -{0x0639 , 0x32}, -{0x063A , 0x0E}, -{0x063B , 0x18}, -{0x063C , 0x88}, -{0x0640 , 0xB2}, -{0x0641 , 0xC0}, -{0x0642 , 0x01}, -{0x0643 , 0x26}, -{0x0644 , 0x13}, -{0x0645 , 0x88}, -{0x0646 , 0x64}, -{0x0647 , 0x00}, -{0x0681 , 0x1B}, -{0x0682 , 0xA0}, -{0x0683 , 0x28}, -{0x0684 , 0x00}, -{0x0685 , 0xB0}, -{0x0686 , 0x6F}, -{0x0687 , 0x33}, -{0x0688 , 0x1F}, -{0x0689 , 0x44}, -{0x068A , 0xA8}, -{0x068B , 0x44}, -{0x068C , 0x08}, -{0x068D , 0x08}, -{0x068E , 0x00}, -{0x068F , 0x00}, -{0x0690 , 0x01}, -{0x0691 , 0x00}, -{0x0692 , 0x01}, -{0x0693 , 0x00}, -{0x0694 , 0x00}, -{0x0695 , 0x00}, -{0x0696 , 0x00}, -{0x0697 , 0x00}, -{0x0698 , 0x2A}, -{0x0699 , 0x80}, -{0x069A , 0x1F}, -{0x069B , 0x00}, -{0x069C , 0x02}, -{0x069D , 0xF5}, -{0x069E , 0x03}, -{0x069F , 0x6D}, -{0x06A0 , 0x0C}, -{0x06A1 , 0xB8}, -{0x06A2 , 0x0D}, -{0x06A3 , 0x74}, -{0x06A4 , 0x00}, -{0x06A5 , 0x2F}, -{0x06A6 , 0x00}, -{0x06A7 , 0x2F}, -{0x0F00 , 0x00}, -{0x0F01 , 0x00}, -{0x0100 , 0x01}, -{0x0102 , 0x02}, -{0x0104 , 0x03}, -{0x0101 , 0x02}, - -/////////////////////////// -{0x020B , 0x48}, -{0x020C , 0x64}, -{0x040A , 0x40}, -{0x040B , 0x33}, -{0x0109 , 0x00}, -{0x010A , 0x04}, -{0x010B , 0x03}, -#if 0 -{0x0110 , 0x02}, -{0x0111 , 0x80}, -{0x0112 , 0x01}, -{0x0113 , 0xe0}, -#else -{0x0110, 0x03}, -{0x0111, 0x20}, -{0x0112, 0x02}, -{0x0113, 0x58}, - -#endif -{0x0116 , 0x02}, -{0x0118 , 0x40}, -{0x0119 , 0x01}, -{0x011a , 0x04}, -{0x011B , 0x00}, -{0x0313 , 0x35}, -{0x0314 , 0x36}, -{0x0315 , 0x16}, - -}; - - - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ - {0x010c , 0x00}, - {0x010d , 0x08}, - {0x010e , 0x00}, - {0x010f , 0x08}, - {0x010a , 0x00}, - {0x0110 , 0x06}, - {0x0111 , 0x40}, - {0x0112 , 0x04}, - {0x0113 , 0xb0}, - {0x0, 0x0}, -}; - - - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0x010c , 0x00}, - {0x010d , 0xa8}, - {0x010e , 0x00}, - {0x010f , 0x60}, - {0x010a , 0x00}, - {0x0110 , 0x05}, - {0x0111 , 0x00}, - {0x0112 , 0x04}, - {0x0113 , 0x00}, - {0x00, 0x00}, -}; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ -#if 0 - {0x0101, 0x00}, - {0x0103, 0x00}, - {0x0105, 0x00}, - {0x0106, 0xF0}, - {0x0107, 0x00}, - {0x0108, 0x1C}, - {0x0109, 0x01}, - {0x010A, 0x00}, - {0x010B, 0x00}, - {0x010C, 0x00}, - {0x010D, 0x08}, - {0x010E, 0x00}, - {0x010F, 0x08}, - {0x0110, 0x06}, - {0x0111, 0x40}, - {0x0112, 0x04}, - {0x0113, 0xB0}, - {0x0114, 0x04}, - {0x0115, 0x00}, - {0x0116, 0x02}, - {0x0117, 0x00}, - {0x0118, 0x40}, - {0x0119, 0x02}, - {0x011A, 0x04}, - {0x011B, 0x01}, - {0x011C, 0x00}, - {0x011D, 0x01}, - {0x011E, 0x36}, - {0x011F, 0x00}, - {0x0120, 0x1C}, - {0x0121, 0x00}, - {0x0122, 0x04}, - {0x0123, 0x00}, - {0x0124, 0x00}, - {0x0125, 0x00}, - {0x0126, 0x00}, - {0x0127, 0x00}, - {0x0128, 0x00}, - {0x0200, 0x1f}, - {0x0201, 0x0c}, - {0x0202, 0x38}, - {0x0203, 0x00}, - {0x0204, 0x03}, - {0x0205, 0x1F}, - {0x0206, 0x0B}, - {0x0207, 0x20}, - {0x0208, 0x00}, - {0x0209, 0x2A}, - {0x020A, 0x01}, - {0x020B, 0x28}, - {0x020C, 0x44}, - {0x020D, 0xC8}, - {0x020E, 0xBC}, - {0x020F, 0x08}, - {0x0210, 0xD6}, - {0x0211, 0x00}, - {0x0212, 0x20}, - {0x0213, 0x81}, - {0x0214, 0x15}, - {0x0215, 0x00}, - {0x0216, 0x00}, - {0x0217, 0x00}, - {0x0218, 0x46}, - {0x0219, 0x30}, - {0x021A, 0x03}, - {0x021B, 0x28}, - {0x021C, 0x02}, - {0x021D, 0x60}, - {0x021E, 0x00}, - {0x021F, 0x00}, - {0x0220, 0x08}, - {0x0221, 0x08}, - {0x0222, 0x04}, - {0x0223, 0x00}, - {0x0224, 0x1F}, - {0x0225, 0x1E}, - {0x0226, 0x18}, - {0x0227, 0x1D}, - {0x0228, 0x1F}, - {0x0229, 0x1F}, - {0x022A, 0x01}, - {0x022B, 0x04}, - {0x022C, 0x05}, - {0x022D, 0x05}, - {0x022E, 0x04}, - {0x022F, 0x03}, - {0x0230, 0x02}, - {0x0231, 0x1F}, - {0x0232, 0x1A}, - {0x0233, 0x19}, - {0x0234, 0x19}, - {0x0235, 0x1B}, - {0x0236, 0x1F}, - {0x0237, 0x04}, - {0x0238, 0xEE}, - {0x0239, 0xFF}, - {0x023A, 0x00}, - {0x023B, 0x00}, - {0x023C, 0x00}, - {0x023D, 0x00}, - {0x023E, 0x00}, - {0x023F, 0x00}, - {0x0240, 0x00}, - {0x0241, 0x00}, - {0x0242, 0x00}, - {0x0243, 0x21}, - {0x0244, 0x42}, - {0x0245, 0x53}, - {0x0246, 0x54}, - {0x0247, 0x54}, - {0x0248, 0x54}, - {0x0249, 0x33}, - {0x024A, 0x11}, - {0x024B, 0x00}, - {0x024C, 0x00}, - {0x024D, 0xFF}, - {0x024E, 0xEE}, - {0x024F, 0xDD}, - {0x0250, 0x00}, - {0x0251, 0x00}, - {0x0252, 0x00}, - {0x0253, 0x00}, - {0x0254, 0x00}, - {0x0255, 0x00}, - {0x0256, 0x00}, - {0x0257, 0x00}, - {0x0258, 0x00}, - {0x0259, 0x00}, - {0x025A, 0x00}, - {0x025B, 0x00}, - {0x025C, 0x00}, - {0x025D, 0x00}, - {0x025E, 0x00}, - {0x025F, 0x00}, - {0x0260, 0x00}, - {0x0261, 0x00}, - {0x0262, 0x00}, - {0x0263, 0x00}, - {0x0264, 0x00}, - {0x0265, 0x00}, - {0x0266, 0x00}, - {0x0267, 0x00}, - {0x0268, 0x8F}, - {0x0269, 0xA3}, - {0x026A, 0xB4}, - {0x026B, 0x90}, - {0x026C, 0x00}, - {0x026D, 0xD0}, - {0x026E, 0x60}, - {0x026F, 0xA0}, - {0x0270, 0x40}, - {0x0300, 0x81}, - {0x0301, 0x80}, - {0x0302, 0x22}, - {0x0303, 0x06}, - {0x0304, 0x03}, - {0x0305, 0x83}, - {0x0306, 0x00}, - {0x0307, 0x22}, - {0x0308, 0x00}, - {0x0309, 0x55}, - {0x030A, 0x55}, - {0x030B, 0x55}, - {0x030C, 0x54}, - {0x030D, 0x1F}, - {0x030E, 0x0A}, - {0x030F, 0x10}, - {0x0310, 0x04}, - {0x0311, 0xFF}, - {0x0312, 0x08}, - {0x0313, 0x35}, - {0x0314, 0x36}, - {0x0315, 0x15}, - {0x0316, 0x26}, - {0x0317, 0x02}, - {0x0318, 0x08}, - {0x0319, 0x0C}, - {0x031A, 0x81}, - {0x031B, 0x00}, - {0x031C, 0x3D}, - {0x031D, 0x00}, - {0x031E, 0xF9}, - {0x031F, 0x00}, - {0x0320, 0x24}, - {0x0321, 0x14}, - {0x0322, 0x1A}, - {0x0323, 0x24}, - {0x0324, 0x08}, - {0x0325, 0xF0}, - {0x0326, 0x30}, - {0x0327, 0x17}, - {0x0328, 0x11}, - {0x0329, 0x22}, - {0x032A, 0x2F}, - {0x032B, 0x21}, - {0x032C, 0xDA}, - {0x032D, 0x10}, - {0x032E, 0xEA}, - {0x032F, 0x18}, - {0x0330, 0x29}, - {0x0331, 0x25}, - {0x0332, 0x12}, - {0x0333, 0x0F}, - {0x0334, 0xE0}, - {0x0335, 0x13}, - {0x0336, 0xFF}, - {0x0337, 0x20}, - {0x0338, 0x46}, - {0x0339, 0x04}, - {0x033A, 0x04}, - {0x033B, 0xFF}, - {0x033C, 0x01}, - {0x033D, 0x00}, - {0x033E, 0x03}, - {0x033F, 0x28}, - {0x0340, 0x02}, - {0x0341, 0x60}, - {0x0342, 0xAC}, - {0x0343, 0x97}, - {0x0344, 0x7F}, - {0x0400, 0xE8}, - {0x0401, 0x40}, - {0x0402, 0x00}, - {0x0403, 0x00}, - {0x0404, 0xF8}, - {0x0405, 0x03}, - {0x0406, 0x03}, - {0x0407, 0x85}, - {0x0408, 0x44}, - {0x0409, 0x1F}, - {0x040A, 0x40}, - {0x040B, 0x33}, - {0x040C, 0xA0}, - {0x040D, 0x00}, - {0x040E, 0x00}, - {0x040F, 0x00}, - {0x0410, 0x0D}, - {0x0411, 0x0D}, - {0x0412, 0x0C}, - {0x0413, 0x04}, - {0x0414, 0x00}, - {0x0415, 0x00}, - {0x0416, 0x07}, - {0x0417, 0x09}, - {0x0418, 0x16}, - {0x0419, 0x14}, - {0x041A, 0x11}, - {0x041B, 0x14}, - {0x041C, 0x07}, - {0x041D, 0x07}, - {0x041E, 0x06}, - {0x041F, 0x02}, - {0x0420, 0x42}, - {0x0421, 0x42}, - {0x0422, 0x47}, - {0x0423, 0x39}, - {0x0424, 0x3E}, - {0x0425, 0x4D}, - {0x0426, 0x46}, - {0x0427, 0x3A}, - {0x0428, 0x21}, - {0x0429, 0x21}, - {0x042A, 0x26}, - {0x042B, 0x1C}, - {0x042C, 0x25}, - {0x042D, 0x25}, - {0x042E, 0x28}, - {0x042F, 0x20}, - {0x0430, 0x3E}, - {0x0431, 0x3E}, - {0x0432, 0x33}, - {0x0433, 0x2E}, - {0x0434, 0x54}, - {0x0435, 0x53}, - {0x0436, 0x3C}, - {0x0437, 0x51}, - {0x0438, 0x2B}, - {0x0439, 0x2B}, - {0x043A, 0x38}, - {0x043B, 0x22}, - {0x043C, 0x3B}, - {0x043D, 0x3B}, - {0x043E, 0x31}, - {0x043F, 0x37}, - {0x0440, 0x00}, - {0x0441, 0x4B}, - {0x0442, 0x00}, - {0x0443, 0x00}, - {0x0444, 0x31}, - {0x0445, 0x00}, - {0x0446, 0x00}, - {0x0447, 0x00}, - {0x0448, 0x00}, - {0x0449, 0x00}, - {0x044A, 0x00}, - {0x044D, 0xE0}, - {0x044E, 0x05}, - {0x044F, 0x07}, - {0x0450, 0x00}, - {0x0451, 0x00}, - {0x0452, 0x00}, - {0x0453, 0x00}, - {0x0454, 0x00}, - {0x0455, 0x00}, - {0x0456, 0x00}, - {0x0457, 0x00}, - {0x0458, 0x00}, - {0x0459, 0x00}, - {0x045A, 0x00}, - {0x045B, 0x00}, - {0x045C, 0x00}, - {0x045D, 0x00}, - {0x045E, 0x00}, - {0x045F, 0x00}, - {0x0460, 0x80}, - {0x0461, 0x10}, - {0x0462, 0x10}, - {0x0463, 0x10}, - {0x0464, 0x08}, - {0x0465, 0x08}, - {0x0466, 0x11}, - {0x0467, 0x09}, - {0x0468, 0x23}, - {0x0469, 0x2A}, - {0x046A, 0x2A}, - {0x046B, 0x47}, - {0x046C, 0x52}, - {0x046D, 0x42}, - {0x046E, 0x36}, - {0x046F, 0x46}, - {0x0470, 0x3A}, - {0x0471, 0x32}, - {0x0472, 0x32}, - {0x0473, 0x38}, - {0x0474, 0x3D}, - {0x0475, 0x2F}, - {0x0476, 0x29}, - {0x0477, 0x48}, - {0x0600, 0x00}, - {0x0601, 0x24}, - {0x0602, 0x45}, - {0x0603, 0x0E}, - {0x0604, 0x14}, - {0x0605, 0x2F}, - {0x0606, 0x01}, - {0x0607, 0x0E}, - {0x0608, 0x0E}, - {0x0609, 0x37}, - {0x060A, 0x18}, - {0x060B, 0xA0}, - {0x060C, 0x20}, - {0x060D, 0x07}, - {0x060E, 0x47}, - {0x060F, 0x90}, - {0x0610, 0x06}, - {0x0611, 0x0C}, - {0x0612, 0x28}, - {0x0613, 0x13}, - {0x0614, 0x0B}, - {0x0615, 0x10}, - {0x0616, 0x14}, - {0x0617, 0x19}, - {0x0618, 0x52}, - {0x0619, 0xA0}, - {0x061A, 0x11}, - {0x061B, 0x33}, - {0x061C, 0x56}, - {0x061D, 0x20}, - {0x061E, 0x28}, - {0x061F, 0x2B}, - {0x0620, 0x22}, - {0x0621, 0x11}, - {0x0622, 0x75}, - {0x0623, 0x49}, - {0x0624, 0x6E}, - {0x0625, 0x80}, - {0x0626, 0x02}, - {0x0627, 0x0C}, - {0x0628, 0x51}, - {0x0629, 0x25}, - {0x062A, 0x01}, - {0x062B, 0x3D}, - {0x062C, 0x04}, - {0x062D, 0x01}, - {0x062E, 0x0C}, - {0x062F, 0x2C}, - {0x0630, 0x0D}, - {0x0631, 0x14}, - {0x0632, 0x12}, - {0x0633, 0x34}, - {0x0634, 0x00}, - {0x0635, 0x00}, - {0x0636, 0x00}, - {0x0637, 0xB1}, - {0x0638, 0x22}, - {0x0639, 0x32}, - {0x063A, 0x0E}, - {0x063B, 0x18}, - {0x063C, 0x88}, - {0x0640, 0xB2}, - {0x0641, 0xC0}, - {0x0642, 0x01}, - {0x0643, 0x26}, - {0x0644, 0x13}, - {0x0645, 0x88}, - {0x0646, 0x64}, - {0x0647, 0x00}, - {0x0681, 0x1B}, - {0x0682, 0xA0}, - {0x0683, 0x28}, - {0x0684, 0x00}, - {0x0685, 0xB0}, - {0x0686, 0x6F}, - {0x0687, 0x33}, - {0x0688, 0x1F}, - {0x0689, 0x44}, - {0x068A, 0xA8}, - {0x068B, 0x44}, - {0x068C, 0x08}, - {0x068D, 0x08}, - {0x068E, 0x00}, - {0x068F, 0x00}, - {0x0690, 0x01}, - {0x0691, 0x00}, - {0x0692, 0x01}, - {0x0693, 0x00}, - {0x0694, 0x00}, - {0x0695, 0x00}, - {0x0696, 0x00}, - {0x0697, 0x00}, - {0x0698, 0x2A}, - {0x0699, 0x80}, - {0x069A, 0x1F}, - {0x069B, 0x00}, - {0x069C, 0x02}, - {0x069D, 0xF5}, - {0x069E, 0x03}, - {0x069F, 0x6D}, - {0x06A0, 0x0C}, - {0x06A1, 0xB8}, - {0x06A2, 0x0D}, - {0x06A3, 0x74}, - {0x06A4, 0x00}, - {0x06A5, 0x2F}, - {0x06A6, 0x00}, - {0x06A7, 0x2F}, - {0x0F00, 0x00}, - {0x0F01, 0x00}, - {0x0100, 0x01}, - {0x0102, 0x02}, - {0x0104, 0x03}, -#endif - {0x020B, 0x48}, - {0x020C, 0x64}, - {0x040A, 0x40}, - {0x040B, 0x33}, - {0x010c , 0x00}, - {0x010d , 0x08}, - {0x010e , 0x00}, - {0x010f , 0x08}, - {0x010a , 0x00}, - {0x0109, 0x00}, - {0x010A, 0x04}, - {0x010B, 0x03}, - {0x0110, 0x03}, - {0x0111, 0x20}, - {0x0112, 0x02}, - {0x0113, 0x58}, - {0x0116, 0x02}, - {0x0118, 0x40}, - {0x0119, 0x02}, - {0x011a, 0x04}, - {0x011B, 0x01}, - {0x0, 0x0}, -}; - - - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - {0x020B , 0x48}, - {0x020C , 0x64}, - {0x040A , 0x40}, - {0x040B , 0x33}, - {0x0109 , 0x00}, - {0x010A , 0x04}, - {0x010B , 0x03}, - {0x010c , 0x00}, - {0x010d , 0xa8}, - {0x010e , 0x00}, - {0x010f , 0x60}, - {0x010a , 0x04}, - #if 1 - {0x0110 , 0x02}, - {0x0111 , 0x80}, - {0x0112 , 0x01}, - {0x0113 , 0xe0}, - #else - {0x0110, 0x03}, - {0x0111, 0x20}, - {0x0112, 0x02}, - {0x0113, 0x58}, - #endif - {0x0116 , 0x02}, - {0x0118 , 0x40}, - {0x0119 , 0x01}, - {0x011a , 0x04}, - {0x011B , 0x00}, - {0x0313 , 0x35}, - {0x0314 , 0x36}, - {0x0315 , 0x16}, - {0x0, 0x0}, -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x0, 0x0}, -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - - - {0x0, 0x0}, -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - - {0x0, 0x0}, -}; -#endif -#if 0 -/* 160X120 QQVGA*/ -static struct reginfo gt2005_qqvga[] = -{ - - {0x300E, 0x34}, - {0x3011, 0x01}, - {0x3012, 0x10}, - {0x302a, 0x02}, - {0x302b, 0xE6}, - {0x306f, 0x14}, - {0x3362, 0x90}, - - {0x3070, 0x5d}, - {0x3072, 0x5d}, - {0x301c, 0x07}, - {0x301d, 0x07}, - - {0x3020, 0x01}, - {0x3021, 0x18}, - {0x3022, 0x00}, - {0x3023, 0x06}, - {0x3024, 0x06}, - {0x3025, 0x58}, - {0x3026, 0x02}, - {0x3027, 0x61}, - {0x3088, 0x00}, - {0x3089, 0xa0}, - {0x308a, 0x00}, - {0x308b, 0x78}, - {0x3316, 0x64}, - {0x3317, 0x25}, - {0x3318, 0x80}, - {0x3319, 0x08}, - {0x331a, 0x0a}, - {0x331b, 0x07}, - {0x331c, 0x80}, - {0x331d, 0x38}, - {0x3100, 0x00}, - {0x3302, 0x11}, - - {0x0, 0x0}, -}; - - - -static struct reginfo gt2005_Sharpness_auto[] = -{ - {0x3306, 0x00}, -}; - -static struct reginfo gt2005_Sharpness1[] = -{ - {0x3306, 0x08}, - {0x3371, 0x00}, -}; - -static struct reginfo gt2005_Sharpness2[][3] = -{ - //Sharpness 2 - {0x3306, 0x08}, - {0x3371, 0x01}, -}; - -static struct reginfo gt2005_Sharpness3[] = -{ - //default - {0x3306, 0x08}, - {0x332d, 0x02}, -}; -static struct reginfo gt2005_Sharpness4[]= -{ - //Sharpness 4 - {0x3306, 0x08}, - {0x332d, 0x03}, -}; - -static struct reginfo gt2005_Sharpness5[] = -{ - //Sharpness 5 - {0x3306, 0x08}, - {0x332d, 0x04}, -}; -#endif - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - //{0x3400, 0x00}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - //{0x3400, 0x02}, - {0x0000, 0x00} -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x3306, 0x00}, //AWB auto, bit[1]:0,auto - {0x0000, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x3306, 0x82}, - {0x3337, 0x68}, - {0x3338, 0x40}, - {0x3339, 0x4e}, - {0x0000, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x3306, 0x02}, //AWB off - {0x3337, 0x5e}, - {0x3338, 0x40}, - {0x3339, 0x46}, - {0x0000, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x3306, 0x02}, - {0x3337, 0x52}, - {0x3338, 0x40}, - {0x3339, 0x58}, - {0x0000, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x3306, 0x02}, - {0x3337, 0x44}, - {0x3338, 0x40}, - {0x3339, 0x70}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x49}, - {0x339a, 0x20}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x49}, - {0x339a, 0x10}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x00}, - {0x3390, 0x41}, - {0x339a, 0x00}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x41}, - {0x339a, 0x10}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x41}, - {0x339a, 0x20}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, //bit[2] enable - {0x3390, 0x41}, //bit[3] sign of brightness - {0x339a, 0x30}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x3391, 0x00}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x3391, 0x20}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x3391, 0x18}, - {0x3396, 0x40}, - {0x3397, 0xa6}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x3391, 0x40}, //bit[6] negative - {0x0000, 0x00} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x3391, 0x18}, - {0x3396, 0xa0}, - {0x3397, 0x40}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x3391, 0x18}, - {0x3396, 0x60}, - {0x3397, 0x60}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - //-3 - {0x3047, 0x05}, - {0x3018, 0x40}, - {0x3019, 0x30}, - {0x301a, 0x71}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - //-2 - {0x3047, 0x05}, - {0x3018, 0x5a}, - {0x3019, 0x4a}, - {0x301a, 0xc2}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - //-0.3EV - {0x3047, 0x05}, - {0x3018, 0x6a}, - {0x3019, 0x5a}, - {0x301a, 0xd4}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - //default - {0x3047, 0x05}, - {0x3018, 0x78}, - {0x3019, 0x68}, - {0x301a, 0xd4}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - // 1 - {0x3047, 0x05}, - {0x3018, 0x88}, - {0x3019, 0x78}, - {0x301a, 0xd5}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - // 2 - {0x3047, 0x05}, - {0x3018, 0xa8}, - {0x3019, 0x98}, - {0x301a, 0xe6}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - // 3 - {0x3047, 0x05}, - {0x3018, 0xc8}, - {0x3019, 0xb8}, - {0x301a, 0xf7}, - {0x0000, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x02}, - {0x3394, 0x40}, - {0x3395, 0x40}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x02}, - {0x3394, 0x50}, - {0x3395, 0x50}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x02}, //enable color saturation - {0x3394, 0x70}, - {0x3395, 0x70}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - //Contrast -3 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x45}, - {0x3398, 0x18}, - {0x3399, 0x18}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - //Contrast -2 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x45}, - {0x3398, 0x18}, - {0x3399, 0x18}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - // Contrast -1 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x45}, - {0x3398, 0x1c}, - {0x3399, 0x1c}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - //Contrast 0 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x00}, - {0x3390, 0x41}, - {0x3398, 0x20}, - {0x3399, 0x20}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - //Contrast +1 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x45}, - {0x3398, 0x24}, - {0x3399, 0x24}, - {0x0000, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - //Contrast +2 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, - {0x3390, 0x45}, - {0x3398, 0x28}, - {0x3399, 0x28}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - //Contrast +3 - {0x3301, 0xff},//bit[7]:1, enable SDE - {0x3391, 0x04}, //bit[2] enable contrast/brightness - {0x3390, 0x45}, //bit[2] Yoffset sign - {0x3398, 0x2c}, - {0x3399, 0x2c}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0x3069, 0x84}, - {0x307c, 0x13}, - {0x3087, 0x02}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0x3069, 0x84}, - {0x307c, 0x10}, - {0x3087, 0x02}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x300e, 0x34}, - {0x300f, 0xa6}, - {0x3010, 0x81}, - {0x3082, 0x01}, - {0x30f4, 0x01}, - {0x3090, 0x3b}, - {0x3091, 0xc0}, - {0x30ac, 0x42}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x300e, 0x34}, - {0x300f, 0xa6}, - {0x3010, 0x81}, - {0x3082, 0x01}, - {0x30f4, 0x01}, - {0x3090, 0x33}, - {0x3091, 0xc0}, - {0x30ac, 0x42}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ -#if 0 /* ddl@rock-chips.com : */ - {0x3014, 0x04}, - {0x3015, 0x00}, - {0x302e, 0x00}, - {0x302d, 0x00}, - {0x0000, 0x00} -#else - {0x3014, 0x84}, - {0x3015, 0x02}, - {0x302e, 0x00}, - {0x302d, 0x00}, - {0x0000, 0x00} -#endif -}; - -static struct reginfo sensor_SceneNight[] = -{ -#if 1 - //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk - {0x300e, 0x34}, - {0x3011, 0x00}, - {0x302c, 0x00}, - {0x3071, 0x00}, - {0x3070, 0xb9}, - {0x301c, 0x02}, - {0x3073, 0x00}, - {0x3072, 0x9a}, - {0x301d, 0x03}, - {0x3014, 0x0c}, - {0x3015, 0x50},//add 5 dummy frame - {0x302e, 0x00}, - {0x302d, 0x00}, - {0x0000, 0x00} -#else - //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk - {0x300e, 0x34}, - {0x3011, 0x01}, - {0x302c, 0x00}, - {0x3071, 0x00}, - {0x3070, 0x5d}, - {0x301c, 0x05}, - {0x3073, 0x00}, - {0x3072, 0x4d}, - {0x301d, 0x07}, - {0x3014, 0x0c}, - {0x3015, 0x50}, - {0x302e, 0x00}, - {0x302d, 0x00}, -#endif -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u16 reg, u8 val) -{ - int err,cnt; - u8 buf[3]; - struct i2c_msg msg[1]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - buf[2] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[2]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} - -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int ret; - int i = 0,j=0; - u8 value; - - SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); - while(regarray[i].reg != 0) - { - ret = sensor_read(client,regarray[i].reg,&value); - if(ret !=0) - { - SENSOR_TR("read value failed\n"); - - } - if(regarray[i].val != value) - { - SENSOR_DG("%s reg[0x%x] check err,writte :0x%x read:0x%x\n",__FUNCTION__,regarray[i].reg,regarray[i].val,value); - } - else - j++; - - i++; - } - if(i==j) - SENSOR_DG("%s check success\n",__FUNCTION__); - - return 0; -} -#endif -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* ret = sensor_write(client, 0x3012, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); */ //delay 5 microseconds - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x0000, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x0001, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { - sensor_write(client, 0x30b0, 0x00); - sensor_write(client, 0x30b1, 0x00); - } - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x30ab, 0x00}, - {0x30ad, 0x0a}, - {0x30ae,0x27}, - {0x363b,0x01}, - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - msleep(600); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - set_w = 1600; - set_h = 1200; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gt2005 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - /* ret = sensor_write(client, 0x3012, 0x80); - if (ret != 0) - { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } - mdelay(5); */ //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x0000, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x0001, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); -#if CONFIG_SENSOR_Flash - int i; -#endif - int ret = 0; - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_GT2005 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GT2005 +#define SENSOR_ID 0x5138 +#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 640 +#define SENSOR_PREVIEW_H 480 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + u16 shutter; + +}; + +/* +* 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[] ={ + {0x0101 , 0x00}, + {0x0103 , 0x00}, + {0x0105 , 0x00}, + {0x0106 , 0xF0}, + {0x0107 , 0x00}, + {0x0108 , 0x1C}, + {0x0109 , 0x01}, + {0x010A , 0x00}, + {0x010B , 0x00}, + {0x010C , 0x00}, + {0x010D , 0x08}, + {0x010E , 0x00}, + {0x010F , 0x08}, + {0x0110 , 0x06}, + {0x0111 , 0x40}, + {0x0112 , 0x04}, + {0x0113 , 0xB0}, + {0x0114 , 0x00}, + {0x0115 , 0x00}, + //{0x0116 , 0x02}, + //{0x0117 , 0x00}, + // {0x0118 , 0x67}, + //{0x0119 , 0x02}, + //{0x011A , 0x04}, + //{0x011B , 0x01}, + {0x011C , 0x00},//0x01 2011 11 04 + {0x011D , 0x02}, + {0x011E , 0x00}, + {0x011F , 0x00}, + {0x0120 , 0x1C}, + {0x0121 , 0x00}, + {0x0122 , 0x04}, + {0x0123 , 0x00}, + {0x0124 , 0x00}, + {0x0125 , 0x00}, + {0x0126 , 0x00}, + {0x0127 , 0x00}, + {0x0128 , 0x00}, + {0x0200 , 0x00}, + {0x0201 , 0x08}, //0x00 + {0x0202 , 0x40}, + {0x0203 , 0x00}, + {0x0204 , 0x78}, + {0x0205 , 0x1F}, + {0x0206 , 0x0B}, + {0x0207 , 0x20}, + {0x0208 , 0x00}, + {0x0209 , 0x2A}, + {0x020A , 0x01}, + {0x020B , 0x48}, + {0x020C , 0x64}, + {0x020D , 0xC8}, + {0x020E , 0xBC}, + {0x020F , 0x08}, + {0x0210 , 0xD6}, + {0x0211 , 0x00}, + {0x0212 , 0x20}, + {0x0213 , 0x81}, + {0x0214 , 0x15}, + {0x0215 , 0x00}, + {0x0216 , 0x00}, + {0x0217 , 0x00}, + {0x0218 , 0x46}, + {0x0219 , 0x30}, + {0x021A , 0x03}, + {0x021B , 0x28}, + {0x021C , 0x02}, + {0x021D , 0x60}, + {0x021E , 0x00}, + {0x021F , 0x00}, + {0x0220 , 0x10}, + {0x0221 , 0x10}, + {0x0222 , 0x10}, + {0x0223 , 0x10}, + {0x0224 , 0x1F}, + {0x0225 , 0x1E}, + {0x0226 , 0x18}, + {0x0227 , 0x1D}, + {0x0228 , 0x1F}, + {0x0229 , 0x1F}, + {0x022A , 0x01}, + {0x022B , 0x04}, + {0x022C , 0x05}, + {0x022D , 0x05}, + {0x022E , 0x04}, + {0x022F , 0x03}, + {0x0230 , 0x02}, + {0x0231 , 0x1F}, + {0x0232 , 0x1A}, + {0x0233 , 0x19}, + {0x0234 , 0x19}, + {0x0235 , 0x1B}, + {0x0236 , 0x1F}, + {0x0237 , 0x04}, + {0x0238 , 0xEE}, + {0x0239 , 0xFF}, + {0x023A , 0x00}, + {0x023B , 0x00}, + {0x023C , 0x00}, + {0x023D , 0x00}, + {0x023E , 0x00}, + {0x023F , 0x00}, + {0x0240 , 0x00}, + {0x0241 , 0x00}, + {0x0242 , 0x00}, + {0x0243 , 0x21}, + {0x0244 , 0x42}, + {0x0245 , 0x53}, + {0x0246 , 0x54}, + {0x0247 , 0x54}, + {0x0248 , 0x54}, + {0x0249 , 0x33}, + {0x024A , 0x11}, + {0x024B , 0x00}, + {0x024C , 0x00}, + {0x024D , 0xFF}, + {0x024E , 0xEE}, + {0x024F , 0xDD}, + {0x0250 , 0x00}, + {0x0251 , 0x00}, + {0x0252 , 0x00}, + {0x0253 , 0x00}, + {0x0254 , 0x00}, + {0x0255 , 0x00}, + {0x0256 , 0x00}, + {0x0257 , 0x00}, + {0x0258 , 0x00}, + {0x0259 , 0x00}, + {0x025A , 0x00}, + {0x025B , 0x00}, + {0x025C , 0x00}, + {0x025D , 0x00}, + {0x025E , 0x00}, + {0x025F , 0x00}, + {0x0260 , 0x00}, + {0x0261 , 0x00}, + {0x0262 , 0x00}, + {0x0263 , 0x00}, + {0x0264 , 0x00}, + {0x0265 , 0x00}, + {0x0266 , 0x00}, + {0x0267 , 0x00}, + {0x0268 , 0x8F}, + {0x0269 , 0xA3}, + {0x026A , 0xB4}, + {0x026B , 0x90}, + {0x026C , 0x00}, + {0x026D , 0xD0}, + {0x026E , 0x60}, + {0x026F , 0xA0}, + {0x0270 , 0x40}, + {0x0300 , 0x81}, + {0x0301 , 0x80}, + {0x0302 , 0x22}, + {0x0303 , 0x06}, + {0x0304 , 0x03}, + {0x0305 , 0x83}, + {0x0306 , 0x00}, + {0x0307 , 0x22}, + {0x0308 , 0x00}, + {0x0309 , 0x55}, + {0x030A , 0x55}, + {0x030B , 0x55}, + {0x030C , 0x54}, + {0x030D , 0x1F}, + {0x030E , 0x13}, + {0x030F , 0x10}, + {0x0310 , 0x04}, + {0x0311 , 0xFF}, + {0x0312 , 0x98}, + {0x0313 , 0x28}, + {0x0314 , 0x66}, + {0x0315 , 0x16}, + {0x0316 , 0x26}, + {0x0317 , 0x02}, + {0x0318 , 0x08}, + {0x0319 , 0x0C}, + {0x031A , 0x81}, + {0x031B , 0x00}, + {0x031C , 0x3D}, + {0x031D , 0x00}, + {0x031E , 0xF9}, + {0x031F , 0x00}, + {0x0320 , 0x24}, + {0x0321 , 0x14}, + {0x0322 , 0x1A}, + {0x0323 , 0x24}, + {0x0324 , 0x08}, + {0x0325 , 0xF0}, + {0x0326 , 0x30}, + {0x0327 , 0x17}, + {0x0328 , 0x11}, + {0x0329 , 0x22}, + {0x032A , 0x2F}, + {0x032B , 0x21}, + {0x032C , 0xDA}, + {0x032D , 0x10}, + {0x032E , 0xEA}, + {0x032F , 0x18}, + {0x0330 , 0x29}, + {0x0331 , 0x25}, + {0x0332 , 0x12}, + {0x0333 , 0x0F}, + {0x0334 , 0xE0}, + {0x0335 , 0x13}, + {0x0336 , 0xFF}, + {0x0337 , 0x20}, + {0x0338 , 0x46}, + {0x0339 , 0x04}, + {0x033A , 0x04}, + {0x033B , 0xFF}, + {0x033C , 0x01}, + {0x033D , 0x00}, + {0x033E , 0x03}, + {0x033F , 0x28}, + {0x0340 , 0x02}, + {0x0341 , 0x60}, + {0x0342 , 0xAC}, + {0x0343 , 0x97}, + {0x0344 , 0x7F}, + {0x0400 , 0xE8}, + {0x0401 , 0x40}, + {0x0402 , 0x00}, + {0x0403 , 0x00}, + {0x0404 , 0xF8}, + {0x0405 , 0x03}, + {0x0406 , 0x03}, + {0x0407 , 0x85}, + {0x0408 , 0x44}, + {0x0409 , 0x1F}, + {0x040A , 0x40}, + {0x040B , 0x33}, + {0x040C , 0xA0}, + {0x040D , 0x00}, + {0x040E , 0x00}, + {0x040F , 0x00}, + {0x0410 , 0x0D}, + {0x0411 , 0x0D}, + {0x0412 , 0x0C}, + {0x0413 , 0x04}, + {0x0414 , 0x00}, + {0x0415 , 0x00}, + {0x0416 , 0x07}, + {0x0417 , 0x09}, + {0x0418 , 0x16}, + {0x0419 , 0x14}, + {0x041A , 0x11}, + {0x041B , 0x14}, + {0x041C , 0x07}, + {0x041D , 0x07}, + {0x041E , 0x06}, + {0x041F , 0x02}, + {0x0420 , 0x42}, + {0x0421 , 0x42}, + {0x0422 , 0x47}, + {0x0423 , 0x39}, + {0x0424 , 0x3E}, + {0x0425 , 0x4D}, + {0x0426 , 0x46}, + {0x0427 , 0x3A}, + {0x0428 , 0x21}, + {0x0429 , 0x21}, + {0x042A , 0x26}, + {0x042B , 0x1C}, + {0x042C , 0x25}, + {0x042D , 0x25}, + {0x042E , 0x28}, + {0x042F , 0x20}, + {0x0430 , 0x3E}, + {0x0431 , 0x3E}, + {0x0432 , 0x33}, + {0x0433 , 0x2E}, + {0x0434 , 0x54}, + {0x0435 , 0x53}, + {0x0436 , 0x3C}, + {0x0437 , 0x51}, + {0x0438 , 0x2B}, + {0x0439 , 0x2B}, + {0x043A , 0x38}, + {0x043B , 0x22}, + {0x043C , 0x3B}, + {0x043D , 0x3B}, + {0x043E , 0x31}, + {0x043F , 0x37}, + {0x0440 , 0x00}, + {0x0441 , 0x4B}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x31}, + {0x0445 , 0x00}, + {0x0446 , 0x00}, + {0x0447 , 0x00}, + {0x0448 , 0x00}, + {0x0449 , 0x00}, + {0x044A , 0x00}, + {0x044D , 0xE0}, + {0x044E , 0x05}, + {0x044F , 0x07}, + {0x0450 , 0x00}, + {0x0451 , 0x00}, + {0x0452 , 0x00}, + {0x0453 , 0x00}, + {0x0454 , 0x00}, + {0x0455 , 0x00}, + {0x0456 , 0x00}, + {0x0457 , 0x00}, + {0x0458 , 0x00}, + {0x0459 , 0x00}, + {0x045A , 0x00}, + {0x045B , 0x00}, + {0x045C , 0x00}, + {0x045D , 0x00}, + {0x045E , 0x00}, + {0x045F , 0x00}, + {0x0460 , 0x80}, + {0x0461 , 0x10}, + {0x0462 , 0x10}, + {0x0463 , 0x10}, + {0x0464 , 0x08}, + {0x0465 , 0x08}, + {0x0466 , 0x11}, + {0x0467 , 0x09}, + {0x0468 , 0x23}, + {0x0469 , 0x2A}, + {0x046A , 0x2A}, + {0x046B , 0x47}, + {0x046C , 0x52}, + {0x046D , 0x42}, + {0x046E , 0x36}, + {0x046F , 0x46}, + {0x0470 , 0x3A}, + {0x0471 , 0x32}, + {0x0472 , 0x32}, + {0x0473 , 0x38}, + {0x0474 , 0x3D}, + {0x0475 , 0x2F}, + {0x0476 , 0x29}, + {0x0477 , 0x48}, + {0x0600 , 0x00}, + {0x0601 , 0x24}, + {0x0602 , 0x45}, + {0x0603 , 0x0E}, + {0x0604 , 0x14}, + {0x0605 , 0x2F}, + {0x0606 , 0x01}, + {0x0607 , 0x0E}, + {0x0608 , 0x0E}, + {0x0609 , 0x37}, + {0x060A , 0x18}, + {0x060B , 0xA0}, + {0x060C , 0x20}, + {0x060D , 0x07}, + {0x060E , 0x47}, + {0x060F , 0x90}, + {0x0610 , 0x06}, + {0x0611 , 0x0C}, + {0x0612 , 0x28}, + {0x0613 , 0x13}, + {0x0614 , 0x0B}, + {0x0615 , 0x10}, + {0x0616 , 0x14}, + {0x0617 , 0x19}, + {0x0618 , 0x52}, + {0x0619 , 0xA0}, + {0x061A , 0x11}, + {0x061B , 0x33}, + {0x061C , 0x56}, + {0x061D , 0x20}, + {0x061E , 0x28}, + {0x061F , 0x2B}, + {0x0620 , 0x22}, + {0x0621 , 0x11}, + {0x0622 , 0x75}, + {0x0623 , 0x49}, + {0x0624 , 0x6E}, + {0x0625 , 0x80}, + {0x0626 , 0x02}, + {0x0627 , 0x0C}, + {0x0628 , 0x51}, + {0x0629 , 0x25}, + {0x062A , 0x01}, + {0x062B , 0x3D}, + {0x062C , 0x04}, + {0x062D , 0x01}, + {0x062E , 0x0C}, + {0x062F , 0x2C}, + {0x0630 , 0x0D}, + {0x0631 , 0x14}, + {0x0632 , 0x12}, + {0x0633 , 0x34}, + {0x0634 , 0x00}, + {0x0635 , 0x00}, + {0x0636 , 0x00}, + {0x0637 , 0xB1}, + {0x0638 , 0x22}, + {0x0639 , 0x32}, + {0x063A , 0x0E}, + {0x063B , 0x18}, + {0x063C , 0x88}, + {0x0640 , 0xB2}, + {0x0641 , 0xC0}, + {0x0642 , 0x01}, + {0x0643 , 0x26}, + {0x0644 , 0x13}, + {0x0645 , 0x88}, + {0x0646 , 0x64}, + {0x0647 , 0x00}, + {0x0681 , 0x1B}, + {0x0682 , 0xA0}, + {0x0683 , 0x28}, + {0x0684 , 0x00}, + {0x0685 , 0xB0}, + {0x0686 , 0x6F}, + {0x0687 , 0x33}, + {0x0688 , 0x1F}, + {0x0689 , 0x44}, + {0x068A , 0xA8}, + {0x068B , 0x44}, + {0x068C , 0x08}, + {0x068D , 0x08}, + {0x068E , 0x00}, + {0x068F , 0x00}, + {0x0690 , 0x01}, + {0x0691 , 0x00}, + {0x0692 , 0x01}, + {0x0693 , 0x00}, + {0x0694 , 0x00}, + {0x0695 , 0x00}, + {0x0696 , 0x00}, + {0x0697 , 0x00}, + {0x0698 , 0x2A}, + {0x0699 , 0x80}, + {0x069A , 0x1F}, + {0x069B , 0x00}, + {0x069C , 0x02}, + {0x069D , 0xF5}, + {0x069E , 0x03}, + {0x069F , 0x6D}, + {0x06A0 , 0x0C}, + {0x06A1 , 0xB8}, + {0x06A2 , 0x0D}, + {0x06A3 , 0x74}, + {0x06A4 , 0x00}, + {0x06A5 , 0x2F}, + {0x06A6 , 0x00}, + {0x06A7 , 0x2F}, + {0x0F00 , 0x00}, + {0x0F01 , 0x00}, + {0x0100 , 0x01}, + {0x0102 , 0x02}, + {0x0104 , 0x03}, + + + /////////////////////////// + {0x020B , 0x48}, + {0x020C , 0x64}, + {0x040A , 0x40}, + {0x040B , 0x33}, + {0x0109 , 0x00}, + {0x010A , 0x04}, + {0x010B , 0x03}, + + {0x0110, 0x03}, + {0x0111, 0x20}, + {0x0112, 0x02}, + {0x0113, 0x58}, + + {0x0116 , 0x02}, + {0x0118 , 0x56},//56 0x40 + {0x0119 , 0x02}, + {0x011a , 0x04}, + {0x011B , 0x01}, + {0x0313 , 0x36},//36 + {0x0314 , 0xff},//ff + {0x0315 , 0x16}, + /* + {0x020B , 0x48}, + {0x020C , 0x64}, + {0x040A , 0x40}, + {0x040B , 0x33}, + {0x0109 , 0x00}, + {0x010A , 0x04}, + {0x010B , 0x03}, + {0x010c , 0x00}, + {0x010d , 0xa8}, + {0x010e , 0x00}, + {0x010f , 0x60}, + {0x010a , 0x04}, + + {0x0110 , 0x02}, + {0x0111 , 0x80}, + {0x0112 , 0x01}, + {0x0113 , 0xe0}, + + {0x0116 , 0x02}, + {0x0118 , 0x40}, + {0x0119 , 0x01}, + {0x011a , 0x04}, + {0x011B , 0x00}, + {0x0313 , 0x35}, + {0x0314 , 0x36}, + {0x0315 , 0x16}, */ + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + //Binning&Resoultion + {0x0109 , 0x01},//Fixed the number of lines by VCOUNT setting + {0x010A , 0x00}, + {0x010B , 0x00}, + + {0x0110 , 0x06}, + {0x0111 , 0x40}, + {0x0112 , 0x04}, + {0x0113 , 0xB0}, // 1600*1200 SETTING + 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[] = +{ + {0x0109 , 0x00}, + {0x010A , 0x04}, + {0x010B , 0x03}, + + {0x0110 , 0x02}, + {0x0111 , 0x80}, + {0x0112 , 0x01}, + {0x0113 , 0xe0}, + 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[]={ + SensorRegVal(0x0000,0), + SensorRegVal(0x0001,0), + 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[]= +{ + {0x031a , 0x81}, + {0x0320 , 0x24}, + {0x0321 , 0x14}, + {0x0322 , 0x1a}, + {0x0323 , 0x24}, + {0x0441 , 0x4B}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x31}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x0320 , 0x02}, + {0x0321 , 0x02}, + {0x0322 , 0x02}, + {0x0323 , 0x02}, + {0x0441 , 0x80}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x0D}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x0320 , 0x02}, + {0x0321 , 0x02}, + {0x0322 , 0x02}, + {0x0323 , 0x02}, + {0x0441 , 0x60}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x14}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x0320 , 0x02}, + {0x0321 , 0x02}, + {0x0322 , 0x02}, + {0x0323 , 0x02}, + {0x0441 , 0x50}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x30}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x0320 , 0x02}, + {0x0321 , 0x02}, + {0x0322 , 0x02}, + {0x0323 , 0x02}, + {0x0441 , 0x0B}, + {0x0442 , 0x00}, + {0x0443 , 0x00}, + {0x0444 , 0x5E}, + 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 + {0x0300 , 0x81}, + {0x0301 , 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + {0x0300 , 0x81}, + {0x0301 , 0x70}, + + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + {0x0300 , 0x81}, + {0x0301 , 0x80}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + {0x0300 , 0x81}, + {0x0301 , 0x90}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + {0x0300 , 0x81}, + {0x0301 , 0xa0}, + + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + {0x0300 , 0x81}, + {0x0301 , 0xb0}, + + 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[] = +{ + {0x0115,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x0115,0x06}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x0115,0x0a}, + {0x026e,0x60}, + {0x026f,0xa0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x0115,0x09}, //bit[6] negative + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x0115,0x0a}, + {0x026e,0xfb}, + {0x026f,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x0115,0x0a}, + {0x026e,0x20}, + {0x026f,0x00}, + 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[]= +{ + //-3 + {0x0300 , 0x81}, + {0x0301 , 0x50}, + {0x0201 , 0xa0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + //-2 + {0x0300 , 0x81}, + {0x0301 , 0x60}, + {0x0201 , 0xb0}, + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + //-0.3EV + {0x0300 , 0x81}, + {0x0301 , 0x70}, + {0x0201 , 0xd0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + //default + {0x0300 , 0x81}, + {0x0301 , 0x80}, + {0x0201 , 0x10},//0c + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + // 1 + {0x0300 , 0x81}, + {0x0301 , 0x90}, + {0x0201 , 0x30}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + // 2 + {0x0300 , 0x81}, + {0x0301 , 0xa0}, + {0x0201 , 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + // 3 + {0x0300 , 0x81}, + {0x0301 , 0xb0}, + {0x0201 , 0x60}, + 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[]= +{ + {0x0202 , 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[]= +{ + {0x0202 , 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[]= +{ + {0x0202 , 0x60}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +static struct rk_sensor_reg sensor_Contrast0[]= +{ + //Contrast -3 + {0x0200 , 0xe8}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + //Contrast -2 + {0x0200 , 0xf0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + // Contrast -1 + {0x0200 , 0xf8}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + //Contrast 0 + {0x0200 , 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + //Contrast +1 + {0x0200 , 0x10}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + //Contrast +2 + {0x0200 , 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + //Contrast +3 + {0x0200 , 0x30}, + 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[] = +{ + {0x0312, 0x08}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + + + {0x0312, 0x98}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//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} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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 0; +} +/* +* 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 0; +} +/* +* 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_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) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x0101, &val); + if (err == 0) { + if((val & 0x1) == 0){ + err = sensor_write(client, 0x0101, (val |0x1)); + } + else + err = sensor_write(client, 0x0101, (val & 0xfe)); + } + } else { + //do nothing + } + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x0101, &val); + if (err == 0) { + if((val & 0x2) == 0){ + err = sensor_write(client, 0x0101, (val |0x2)); + } + else { + err = sensor_write(client, 0x0101, (val & 0xfc)); + } + } + } else { + //do nothing + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/gt2005_old.c b/drivers/media/video/gt2005_old.c new file mode 100755 index 000000000000..d9915c3aebd1 --- /dev/null +++ b/drivers/media/video/gt2005_old.c @@ -0,0 +1,3727 @@ +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_GT2005 +#define SENSOR_V4L2_IDENT V4L2_IDENT_GT2005 +#define SENSOR_ID 0x5138 +#define SENSOR_MIN_WIDTH 640 +#define SENSOR_MIN_HEIGHT 480 +#define SENSOR_MAX_WIDTH 1600 +#define SENSOR_MAX_HEIGHT 1200 +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u16 reg; + u8 val; +}; + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_GT2005_USER_DEFINED_SERIES +#include "gt2005_user_series.c" +#else +/* init 352X288 SVGA */ +static struct reginfo sensor_init_data[] = +{ + {0x0101 , 0x00}, + {0x0103 , 0x00}, + {0x0105 , 0x00}, + {0x0106 , 0xF0}, + {0x0107 , 0x00}, + {0x0108 , 0x1C}, + {0x0109 , 0x01}, + {0x010A , 0x00}, + {0x010B , 0x00}, + {0x010C , 0x00}, + {0x010D , 0x08}, + {0x010E , 0x00}, + {0x010F , 0x08}, + {0x0110 , 0x06}, + {0x0111 , 0x40}, + {0x0112 , 0x04}, + {0x0113 , 0xB0}, +{0x0114 , 0x00}, + {0x0115 , 0x00}, + {0x0116 , 0x02}, + {0x0117 , 0x00}, +{0x0118 , 0x67}, + {0x0119 , 0x02}, + {0x011A , 0x04}, + {0x011B , 0x01}, +{0x011C , 0x01}, +{0x011D , 0x02}, +{0x011E , 0x00}, +{0x011F , 0x00}, +{0x0120 , 0x1C}, +{0x0121 , 0x00}, +{0x0122 , 0x04}, +{0x0123 , 0x00}, +{0x0124 , 0x00}, +{0x0125 , 0x00}, +{0x0126 , 0x00}, +{0x0127 , 0x00}, +{0x0128 , 0x00}, +{0x0200 , 0x00}, +{0x0201 , 0x00}, +{0x0202 , 0x40}, +{0x0203 , 0x00}, +{0x0204 , 0x03}, +{0x0205 , 0x1F}, +{0x0206 , 0x0B}, +{0x0207 , 0x20}, +{0x0208 , 0x00}, +{0x0209 , 0x2A}, +{0x020A , 0x01}, +{0x020B , 0x48}, +{0x020C , 0x64}, +{0x020D , 0xC8}, +{0x020E , 0xBC}, +{0x020F , 0x08}, +{0x0210 , 0xD6}, +{0x0211 , 0x00}, +{0x0212 , 0x20}, +{0x0213 , 0x81}, +{0x0214 , 0x15}, +{0x0215 , 0x00}, +{0x0216 , 0x00}, +{0x0217 , 0x00}, +{0x0218 , 0x46}, +{0x0219 , 0x30}, +{0x021A , 0x03}, +{0x021B , 0x28}, +{0x021C , 0x02}, +{0x021D , 0x60}, +{0x021E , 0x00}, +{0x021F , 0x00}, +{0x0220 , 0x08}, +{0x0221 , 0x08}, +{0x0222 , 0x04}, +{0x0223 , 0x00}, +{0x0224 , 0x1F}, +{0x0225 , 0x1E}, +{0x0226 , 0x18}, +{0x0227 , 0x1D}, +{0x0228 , 0x1F}, +{0x0229 , 0x1F}, +{0x022A , 0x01}, +{0x022B , 0x04}, +{0x022C , 0x05}, +{0x022D , 0x05}, +{0x022E , 0x04}, +{0x022F , 0x03}, +{0x0230 , 0x02}, +{0x0231 , 0x1F}, +{0x0232 , 0x1A}, +{0x0233 , 0x19}, +{0x0234 , 0x19}, +{0x0235 , 0x1B}, +{0x0236 , 0x1F}, +{0x0237 , 0x04}, +{0x0238 , 0xEE}, +{0x0239 , 0xFF}, +{0x023A , 0x00}, +{0x023B , 0x00}, +{0x023C , 0x00}, +{0x023D , 0x00}, +{0x023E , 0x00}, +{0x023F , 0x00}, +{0x0240 , 0x00}, +{0x0241 , 0x00}, +{0x0242 , 0x00}, +{0x0243 , 0x21}, +{0x0244 , 0x42}, +{0x0245 , 0x53}, +{0x0246 , 0x54}, +{0x0247 , 0x54}, +{0x0248 , 0x54}, +{0x0249 , 0x33}, +{0x024A , 0x11}, +{0x024B , 0x00}, +{0x024C , 0x00}, +{0x024D , 0xFF}, +{0x024E , 0xEE}, +{0x024F , 0xDD}, +{0x0250 , 0x00}, +{0x0251 , 0x00}, +{0x0252 , 0x00}, +{0x0253 , 0x00}, +{0x0254 , 0x00}, +{0x0255 , 0x00}, +{0x0256 , 0x00}, +{0x0257 , 0x00}, +{0x0258 , 0x00}, +{0x0259 , 0x00}, +{0x025A , 0x00}, +{0x025B , 0x00}, +{0x025C , 0x00}, +{0x025D , 0x00}, +{0x025E , 0x00}, +{0x025F , 0x00}, +{0x0260 , 0x00}, +{0x0261 , 0x00}, +{0x0262 , 0x00}, +{0x0263 , 0x00}, +{0x0264 , 0x00}, +{0x0265 , 0x00}, +{0x0266 , 0x00}, +{0x0267 , 0x00}, +{0x0268 , 0x8F}, +{0x0269 , 0xA3}, +{0x026A , 0xB4}, +{0x026B , 0x90}, +{0x026C , 0x00}, +{0x026D , 0xD0}, +{0x026E , 0x60}, +{0x026F , 0xA0}, +{0x0270 , 0x40}, +{0x0300 , 0x81}, +{0x0301 , 0x80}, +{0x0302 , 0x22}, +{0x0303 , 0x06}, +{0x0304 , 0x03}, +{0x0305 , 0x83}, +{0x0306 , 0x00}, +{0x0307 , 0x22}, +{0x0308 , 0x00}, +{0x0309 , 0x55}, +{0x030A , 0x55}, +{0x030B , 0x55}, +{0x030C , 0x54}, +{0x030D , 0x1F}, +{0x030E , 0x13}, +{0x030F , 0x10}, +{0x0310 , 0x04}, +{0x0311 , 0xFF}, +{0x0312 , 0x08}, +{0x0313 , 0x28}, +{0x0314 , 0x66}, +{0x0315 , 0x16}, +{0x0316 , 0x26}, +{0x0317 , 0x02}, +{0x0318 , 0x08}, +{0x0319 , 0x0C}, +{0x031A , 0x81}, +{0x031B , 0x00}, +{0x031C , 0x3D}, +{0x031D , 0x00}, +{0x031E , 0xF9}, +{0x031F , 0x00}, +{0x0320 , 0x24}, +{0x0321 , 0x14}, +{0x0322 , 0x1A}, +{0x0323 , 0x24}, +{0x0324 , 0x08}, +{0x0325 , 0xF0}, +{0x0326 , 0x30}, +{0x0327 , 0x17}, +{0x0328 , 0x11}, +{0x0329 , 0x22}, +{0x032A , 0x2F}, +{0x032B , 0x21}, +{0x032C , 0xDA}, +{0x032D , 0x10}, +{0x032E , 0xEA}, +{0x032F , 0x18}, +{0x0330 , 0x29}, +{0x0331 , 0x25}, +{0x0332 , 0x12}, +{0x0333 , 0x0F}, +{0x0334 , 0xE0}, +{0x0335 , 0x13}, +{0x0336 , 0xFF}, +{0x0337 , 0x20}, +{0x0338 , 0x46}, +{0x0339 , 0x04}, +{0x033A , 0x04}, +{0x033B , 0xFF}, +{0x033C , 0x01}, +{0x033D , 0x00}, +{0x033E , 0x03}, +{0x033F , 0x28}, +{0x0340 , 0x02}, +{0x0341 , 0x60}, +{0x0342 , 0xAC}, +{0x0343 , 0x97}, +{0x0344 , 0x7F}, +{0x0400 , 0xE8}, +{0x0401 , 0x40}, +{0x0402 , 0x00}, +{0x0403 , 0x00}, +{0x0404 , 0xF8}, +{0x0405 , 0x03}, +{0x0406 , 0x03}, +{0x0407 , 0x85}, +{0x0408 , 0x44}, +{0x0409 , 0x1F}, +{0x040A , 0x40}, +{0x040B , 0x33}, +{0x040C , 0xA0}, +{0x040D , 0x00}, +{0x040E , 0x00}, +{0x040F , 0x00}, +{0x0410 , 0x0D}, +{0x0411 , 0x0D}, +{0x0412 , 0x0C}, +{0x0413 , 0x04}, +{0x0414 , 0x00}, +{0x0415 , 0x00}, +{0x0416 , 0x07}, +{0x0417 , 0x09}, +{0x0418 , 0x16}, +{0x0419 , 0x14}, +{0x041A , 0x11}, +{0x041B , 0x14}, +{0x041C , 0x07}, +{0x041D , 0x07}, +{0x041E , 0x06}, +{0x041F , 0x02}, +{0x0420 , 0x42}, +{0x0421 , 0x42}, +{0x0422 , 0x47}, +{0x0423 , 0x39}, +{0x0424 , 0x3E}, +{0x0425 , 0x4D}, +{0x0426 , 0x46}, +{0x0427 , 0x3A}, +{0x0428 , 0x21}, +{0x0429 , 0x21}, +{0x042A , 0x26}, +{0x042B , 0x1C}, +{0x042C , 0x25}, +{0x042D , 0x25}, +{0x042E , 0x28}, +{0x042F , 0x20}, +{0x0430 , 0x3E}, +{0x0431 , 0x3E}, +{0x0432 , 0x33}, +{0x0433 , 0x2E}, +{0x0434 , 0x54}, +{0x0435 , 0x53}, +{0x0436 , 0x3C}, +{0x0437 , 0x51}, +{0x0438 , 0x2B}, +{0x0439 , 0x2B}, +{0x043A , 0x38}, +{0x043B , 0x22}, +{0x043C , 0x3B}, +{0x043D , 0x3B}, +{0x043E , 0x31}, +{0x043F , 0x37}, +{0x0440 , 0x00}, +{0x0441 , 0x4B}, +{0x0442 , 0x00}, +{0x0443 , 0x00}, +{0x0444 , 0x31}, +{0x0445 , 0x00}, +{0x0446 , 0x00}, +{0x0447 , 0x00}, +{0x0448 , 0x00}, +{0x0449 , 0x00}, +{0x044A , 0x00}, +{0x044D , 0xE0}, +{0x044E , 0x05}, +{0x044F , 0x07}, +{0x0450 , 0x00}, +{0x0451 , 0x00}, +{0x0452 , 0x00}, +{0x0453 , 0x00}, +{0x0454 , 0x00}, +{0x0455 , 0x00}, +{0x0456 , 0x00}, +{0x0457 , 0x00}, +{0x0458 , 0x00}, +{0x0459 , 0x00}, +{0x045A , 0x00}, +{0x045B , 0x00}, +{0x045C , 0x00}, +{0x045D , 0x00}, +{0x045E , 0x00}, +{0x045F , 0x00}, +{0x0460 , 0x80}, +{0x0461 , 0x10}, +{0x0462 , 0x10}, +{0x0463 , 0x10}, +{0x0464 , 0x08}, +{0x0465 , 0x08}, +{0x0466 , 0x11}, +{0x0467 , 0x09}, +{0x0468 , 0x23}, +{0x0469 , 0x2A}, +{0x046A , 0x2A}, +{0x046B , 0x47}, +{0x046C , 0x52}, +{0x046D , 0x42}, +{0x046E , 0x36}, +{0x046F , 0x46}, +{0x0470 , 0x3A}, +{0x0471 , 0x32}, +{0x0472 , 0x32}, +{0x0473 , 0x38}, +{0x0474 , 0x3D}, +{0x0475 , 0x2F}, +{0x0476 , 0x29}, +{0x0477 , 0x48}, +{0x0600 , 0x00}, +{0x0601 , 0x24}, +{0x0602 , 0x45}, +{0x0603 , 0x0E}, +{0x0604 , 0x14}, +{0x0605 , 0x2F}, +{0x0606 , 0x01}, +{0x0607 , 0x0E}, +{0x0608 , 0x0E}, +{0x0609 , 0x37}, +{0x060A , 0x18}, +{0x060B , 0xA0}, +{0x060C , 0x20}, +{0x060D , 0x07}, +{0x060E , 0x47}, +{0x060F , 0x90}, +{0x0610 , 0x06}, +{0x0611 , 0x0C}, +{0x0612 , 0x28}, +{0x0613 , 0x13}, +{0x0614 , 0x0B}, +{0x0615 , 0x10}, +{0x0616 , 0x14}, +{0x0617 , 0x19}, +{0x0618 , 0x52}, +{0x0619 , 0xA0}, +{0x061A , 0x11}, +{0x061B , 0x33}, +{0x061C , 0x56}, +{0x061D , 0x20}, +{0x061E , 0x28}, +{0x061F , 0x2B}, +{0x0620 , 0x22}, +{0x0621 , 0x11}, +{0x0622 , 0x75}, +{0x0623 , 0x49}, +{0x0624 , 0x6E}, +{0x0625 , 0x80}, +{0x0626 , 0x02}, +{0x0627 , 0x0C}, +{0x0628 , 0x51}, +{0x0629 , 0x25}, +{0x062A , 0x01}, +{0x062B , 0x3D}, +{0x062C , 0x04}, +{0x062D , 0x01}, +{0x062E , 0x0C}, +{0x062F , 0x2C}, +{0x0630 , 0x0D}, +{0x0631 , 0x14}, +{0x0632 , 0x12}, +{0x0633 , 0x34}, +{0x0634 , 0x00}, +{0x0635 , 0x00}, +{0x0636 , 0x00}, +{0x0637 , 0xB1}, +{0x0638 , 0x22}, +{0x0639 , 0x32}, +{0x063A , 0x0E}, +{0x063B , 0x18}, +{0x063C , 0x88}, +{0x0640 , 0xB2}, +{0x0641 , 0xC0}, +{0x0642 , 0x01}, +{0x0643 , 0x26}, +{0x0644 , 0x13}, +{0x0645 , 0x88}, +{0x0646 , 0x64}, +{0x0647 , 0x00}, +{0x0681 , 0x1B}, +{0x0682 , 0xA0}, +{0x0683 , 0x28}, +{0x0684 , 0x00}, +{0x0685 , 0xB0}, +{0x0686 , 0x6F}, +{0x0687 , 0x33}, +{0x0688 , 0x1F}, +{0x0689 , 0x44}, +{0x068A , 0xA8}, +{0x068B , 0x44}, +{0x068C , 0x08}, +{0x068D , 0x08}, +{0x068E , 0x00}, +{0x068F , 0x00}, +{0x0690 , 0x01}, +{0x0691 , 0x00}, +{0x0692 , 0x01}, +{0x0693 , 0x00}, +{0x0694 , 0x00}, +{0x0695 , 0x00}, +{0x0696 , 0x00}, +{0x0697 , 0x00}, +{0x0698 , 0x2A}, +{0x0699 , 0x80}, +{0x069A , 0x1F}, +{0x069B , 0x00}, +{0x069C , 0x02}, +{0x069D , 0xF5}, +{0x069E , 0x03}, +{0x069F , 0x6D}, +{0x06A0 , 0x0C}, +{0x06A1 , 0xB8}, +{0x06A2 , 0x0D}, +{0x06A3 , 0x74}, +{0x06A4 , 0x00}, +{0x06A5 , 0x2F}, +{0x06A6 , 0x00}, +{0x06A7 , 0x2F}, +{0x0F00 , 0x00}, +{0x0F01 , 0x00}, +{0x0100 , 0x01}, +{0x0102 , 0x02}, +{0x0104 , 0x03}, +{0x0101 , 0x02}, + +/////////////////////////// +{0x020B , 0x48}, +{0x020C , 0x64}, +{0x040A , 0x40}, +{0x040B , 0x33}, +{0x0109 , 0x00}, +{0x010A , 0x04}, +{0x010B , 0x03}, +#if 0 +{0x0110 , 0x02}, +{0x0111 , 0x80}, +{0x0112 , 0x01}, +{0x0113 , 0xe0}, +#else +{0x0110, 0x03}, +{0x0111, 0x20}, +{0x0112, 0x02}, +{0x0113, 0x58}, + +#endif +{0x0116 , 0x02}, +{0x0118 , 0x40}, +{0x0119 , 0x01}, +{0x011a , 0x04}, +{0x011B , 0x00}, +{0x0313 , 0x35}, +{0x0314 , 0x36}, +{0x0315 , 0x16}, + +}; + + + +/* 1600X1200 UXGA */ +static struct reginfo sensor_uxga[] = +{ + {0x010c , 0x00}, + {0x010d , 0x08}, + {0x010e , 0x00}, + {0x010f , 0x08}, + {0x010a , 0x00}, + {0x0110 , 0x06}, + {0x0111 , 0x40}, + {0x0112 , 0x04}, + {0x0113 , 0xb0}, + {0x0, 0x0}, +}; + + + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0x010c , 0x00}, + {0x010d , 0xa8}, + {0x010e , 0x00}, + {0x010f , 0x60}, + {0x010a , 0x00}, + {0x0110 , 0x05}, + {0x0111 , 0x00}, + {0x0112 , 0x04}, + {0x0113 , 0x00}, + {0x00, 0x00}, +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ +#if 0 + {0x0101, 0x00}, + {0x0103, 0x00}, + {0x0105, 0x00}, + {0x0106, 0xF0}, + {0x0107, 0x00}, + {0x0108, 0x1C}, + {0x0109, 0x01}, + {0x010A, 0x00}, + {0x010B, 0x00}, + {0x010C, 0x00}, + {0x010D, 0x08}, + {0x010E, 0x00}, + {0x010F, 0x08}, + {0x0110, 0x06}, + {0x0111, 0x40}, + {0x0112, 0x04}, + {0x0113, 0xB0}, + {0x0114, 0x04}, + {0x0115, 0x00}, + {0x0116, 0x02}, + {0x0117, 0x00}, + {0x0118, 0x40}, + {0x0119, 0x02}, + {0x011A, 0x04}, + {0x011B, 0x01}, + {0x011C, 0x00}, + {0x011D, 0x01}, + {0x011E, 0x36}, + {0x011F, 0x00}, + {0x0120, 0x1C}, + {0x0121, 0x00}, + {0x0122, 0x04}, + {0x0123, 0x00}, + {0x0124, 0x00}, + {0x0125, 0x00}, + {0x0126, 0x00}, + {0x0127, 0x00}, + {0x0128, 0x00}, + {0x0200, 0x1f}, + {0x0201, 0x0c}, + {0x0202, 0x38}, + {0x0203, 0x00}, + {0x0204, 0x03}, + {0x0205, 0x1F}, + {0x0206, 0x0B}, + {0x0207, 0x20}, + {0x0208, 0x00}, + {0x0209, 0x2A}, + {0x020A, 0x01}, + {0x020B, 0x28}, + {0x020C, 0x44}, + {0x020D, 0xC8}, + {0x020E, 0xBC}, + {0x020F, 0x08}, + {0x0210, 0xD6}, + {0x0211, 0x00}, + {0x0212, 0x20}, + {0x0213, 0x81}, + {0x0214, 0x15}, + {0x0215, 0x00}, + {0x0216, 0x00}, + {0x0217, 0x00}, + {0x0218, 0x46}, + {0x0219, 0x30}, + {0x021A, 0x03}, + {0x021B, 0x28}, + {0x021C, 0x02}, + {0x021D, 0x60}, + {0x021E, 0x00}, + {0x021F, 0x00}, + {0x0220, 0x08}, + {0x0221, 0x08}, + {0x0222, 0x04}, + {0x0223, 0x00}, + {0x0224, 0x1F}, + {0x0225, 0x1E}, + {0x0226, 0x18}, + {0x0227, 0x1D}, + {0x0228, 0x1F}, + {0x0229, 0x1F}, + {0x022A, 0x01}, + {0x022B, 0x04}, + {0x022C, 0x05}, + {0x022D, 0x05}, + {0x022E, 0x04}, + {0x022F, 0x03}, + {0x0230, 0x02}, + {0x0231, 0x1F}, + {0x0232, 0x1A}, + {0x0233, 0x19}, + {0x0234, 0x19}, + {0x0235, 0x1B}, + {0x0236, 0x1F}, + {0x0237, 0x04}, + {0x0238, 0xEE}, + {0x0239, 0xFF}, + {0x023A, 0x00}, + {0x023B, 0x00}, + {0x023C, 0x00}, + {0x023D, 0x00}, + {0x023E, 0x00}, + {0x023F, 0x00}, + {0x0240, 0x00}, + {0x0241, 0x00}, + {0x0242, 0x00}, + {0x0243, 0x21}, + {0x0244, 0x42}, + {0x0245, 0x53}, + {0x0246, 0x54}, + {0x0247, 0x54}, + {0x0248, 0x54}, + {0x0249, 0x33}, + {0x024A, 0x11}, + {0x024B, 0x00}, + {0x024C, 0x00}, + {0x024D, 0xFF}, + {0x024E, 0xEE}, + {0x024F, 0xDD}, + {0x0250, 0x00}, + {0x0251, 0x00}, + {0x0252, 0x00}, + {0x0253, 0x00}, + {0x0254, 0x00}, + {0x0255, 0x00}, + {0x0256, 0x00}, + {0x0257, 0x00}, + {0x0258, 0x00}, + {0x0259, 0x00}, + {0x025A, 0x00}, + {0x025B, 0x00}, + {0x025C, 0x00}, + {0x025D, 0x00}, + {0x025E, 0x00}, + {0x025F, 0x00}, + {0x0260, 0x00}, + {0x0261, 0x00}, + {0x0262, 0x00}, + {0x0263, 0x00}, + {0x0264, 0x00}, + {0x0265, 0x00}, + {0x0266, 0x00}, + {0x0267, 0x00}, + {0x0268, 0x8F}, + {0x0269, 0xA3}, + {0x026A, 0xB4}, + {0x026B, 0x90}, + {0x026C, 0x00}, + {0x026D, 0xD0}, + {0x026E, 0x60}, + {0x026F, 0xA0}, + {0x0270, 0x40}, + {0x0300, 0x81}, + {0x0301, 0x80}, + {0x0302, 0x22}, + {0x0303, 0x06}, + {0x0304, 0x03}, + {0x0305, 0x83}, + {0x0306, 0x00}, + {0x0307, 0x22}, + {0x0308, 0x00}, + {0x0309, 0x55}, + {0x030A, 0x55}, + {0x030B, 0x55}, + {0x030C, 0x54}, + {0x030D, 0x1F}, + {0x030E, 0x0A}, + {0x030F, 0x10}, + {0x0310, 0x04}, + {0x0311, 0xFF}, + {0x0312, 0x08}, + {0x0313, 0x35}, + {0x0314, 0x36}, + {0x0315, 0x15}, + {0x0316, 0x26}, + {0x0317, 0x02}, + {0x0318, 0x08}, + {0x0319, 0x0C}, + {0x031A, 0x81}, + {0x031B, 0x00}, + {0x031C, 0x3D}, + {0x031D, 0x00}, + {0x031E, 0xF9}, + {0x031F, 0x00}, + {0x0320, 0x24}, + {0x0321, 0x14}, + {0x0322, 0x1A}, + {0x0323, 0x24}, + {0x0324, 0x08}, + {0x0325, 0xF0}, + {0x0326, 0x30}, + {0x0327, 0x17}, + {0x0328, 0x11}, + {0x0329, 0x22}, + {0x032A, 0x2F}, + {0x032B, 0x21}, + {0x032C, 0xDA}, + {0x032D, 0x10}, + {0x032E, 0xEA}, + {0x032F, 0x18}, + {0x0330, 0x29}, + {0x0331, 0x25}, + {0x0332, 0x12}, + {0x0333, 0x0F}, + {0x0334, 0xE0}, + {0x0335, 0x13}, + {0x0336, 0xFF}, + {0x0337, 0x20}, + {0x0338, 0x46}, + {0x0339, 0x04}, + {0x033A, 0x04}, + {0x033B, 0xFF}, + {0x033C, 0x01}, + {0x033D, 0x00}, + {0x033E, 0x03}, + {0x033F, 0x28}, + {0x0340, 0x02}, + {0x0341, 0x60}, + {0x0342, 0xAC}, + {0x0343, 0x97}, + {0x0344, 0x7F}, + {0x0400, 0xE8}, + {0x0401, 0x40}, + {0x0402, 0x00}, + {0x0403, 0x00}, + {0x0404, 0xF8}, + {0x0405, 0x03}, + {0x0406, 0x03}, + {0x0407, 0x85}, + {0x0408, 0x44}, + {0x0409, 0x1F}, + {0x040A, 0x40}, + {0x040B, 0x33}, + {0x040C, 0xA0}, + {0x040D, 0x00}, + {0x040E, 0x00}, + {0x040F, 0x00}, + {0x0410, 0x0D}, + {0x0411, 0x0D}, + {0x0412, 0x0C}, + {0x0413, 0x04}, + {0x0414, 0x00}, + {0x0415, 0x00}, + {0x0416, 0x07}, + {0x0417, 0x09}, + {0x0418, 0x16}, + {0x0419, 0x14}, + {0x041A, 0x11}, + {0x041B, 0x14}, + {0x041C, 0x07}, + {0x041D, 0x07}, + {0x041E, 0x06}, + {0x041F, 0x02}, + {0x0420, 0x42}, + {0x0421, 0x42}, + {0x0422, 0x47}, + {0x0423, 0x39}, + {0x0424, 0x3E}, + {0x0425, 0x4D}, + {0x0426, 0x46}, + {0x0427, 0x3A}, + {0x0428, 0x21}, + {0x0429, 0x21}, + {0x042A, 0x26}, + {0x042B, 0x1C}, + {0x042C, 0x25}, + {0x042D, 0x25}, + {0x042E, 0x28}, + {0x042F, 0x20}, + {0x0430, 0x3E}, + {0x0431, 0x3E}, + {0x0432, 0x33}, + {0x0433, 0x2E}, + {0x0434, 0x54}, + {0x0435, 0x53}, + {0x0436, 0x3C}, + {0x0437, 0x51}, + {0x0438, 0x2B}, + {0x0439, 0x2B}, + {0x043A, 0x38}, + {0x043B, 0x22}, + {0x043C, 0x3B}, + {0x043D, 0x3B}, + {0x043E, 0x31}, + {0x043F, 0x37}, + {0x0440, 0x00}, + {0x0441, 0x4B}, + {0x0442, 0x00}, + {0x0443, 0x00}, + {0x0444, 0x31}, + {0x0445, 0x00}, + {0x0446, 0x00}, + {0x0447, 0x00}, + {0x0448, 0x00}, + {0x0449, 0x00}, + {0x044A, 0x00}, + {0x044D, 0xE0}, + {0x044E, 0x05}, + {0x044F, 0x07}, + {0x0450, 0x00}, + {0x0451, 0x00}, + {0x0452, 0x00}, + {0x0453, 0x00}, + {0x0454, 0x00}, + {0x0455, 0x00}, + {0x0456, 0x00}, + {0x0457, 0x00}, + {0x0458, 0x00}, + {0x0459, 0x00}, + {0x045A, 0x00}, + {0x045B, 0x00}, + {0x045C, 0x00}, + {0x045D, 0x00}, + {0x045E, 0x00}, + {0x045F, 0x00}, + {0x0460, 0x80}, + {0x0461, 0x10}, + {0x0462, 0x10}, + {0x0463, 0x10}, + {0x0464, 0x08}, + {0x0465, 0x08}, + {0x0466, 0x11}, + {0x0467, 0x09}, + {0x0468, 0x23}, + {0x0469, 0x2A}, + {0x046A, 0x2A}, + {0x046B, 0x47}, + {0x046C, 0x52}, + {0x046D, 0x42}, + {0x046E, 0x36}, + {0x046F, 0x46}, + {0x0470, 0x3A}, + {0x0471, 0x32}, + {0x0472, 0x32}, + {0x0473, 0x38}, + {0x0474, 0x3D}, + {0x0475, 0x2F}, + {0x0476, 0x29}, + {0x0477, 0x48}, + {0x0600, 0x00}, + {0x0601, 0x24}, + {0x0602, 0x45}, + {0x0603, 0x0E}, + {0x0604, 0x14}, + {0x0605, 0x2F}, + {0x0606, 0x01}, + {0x0607, 0x0E}, + {0x0608, 0x0E}, + {0x0609, 0x37}, + {0x060A, 0x18}, + {0x060B, 0xA0}, + {0x060C, 0x20}, + {0x060D, 0x07}, + {0x060E, 0x47}, + {0x060F, 0x90}, + {0x0610, 0x06}, + {0x0611, 0x0C}, + {0x0612, 0x28}, + {0x0613, 0x13}, + {0x0614, 0x0B}, + {0x0615, 0x10}, + {0x0616, 0x14}, + {0x0617, 0x19}, + {0x0618, 0x52}, + {0x0619, 0xA0}, + {0x061A, 0x11}, + {0x061B, 0x33}, + {0x061C, 0x56}, + {0x061D, 0x20}, + {0x061E, 0x28}, + {0x061F, 0x2B}, + {0x0620, 0x22}, + {0x0621, 0x11}, + {0x0622, 0x75}, + {0x0623, 0x49}, + {0x0624, 0x6E}, + {0x0625, 0x80}, + {0x0626, 0x02}, + {0x0627, 0x0C}, + {0x0628, 0x51}, + {0x0629, 0x25}, + {0x062A, 0x01}, + {0x062B, 0x3D}, + {0x062C, 0x04}, + {0x062D, 0x01}, + {0x062E, 0x0C}, + {0x062F, 0x2C}, + {0x0630, 0x0D}, + {0x0631, 0x14}, + {0x0632, 0x12}, + {0x0633, 0x34}, + {0x0634, 0x00}, + {0x0635, 0x00}, + {0x0636, 0x00}, + {0x0637, 0xB1}, + {0x0638, 0x22}, + {0x0639, 0x32}, + {0x063A, 0x0E}, + {0x063B, 0x18}, + {0x063C, 0x88}, + {0x0640, 0xB2}, + {0x0641, 0xC0}, + {0x0642, 0x01}, + {0x0643, 0x26}, + {0x0644, 0x13}, + {0x0645, 0x88}, + {0x0646, 0x64}, + {0x0647, 0x00}, + {0x0681, 0x1B}, + {0x0682, 0xA0}, + {0x0683, 0x28}, + {0x0684, 0x00}, + {0x0685, 0xB0}, + {0x0686, 0x6F}, + {0x0687, 0x33}, + {0x0688, 0x1F}, + {0x0689, 0x44}, + {0x068A, 0xA8}, + {0x068B, 0x44}, + {0x068C, 0x08}, + {0x068D, 0x08}, + {0x068E, 0x00}, + {0x068F, 0x00}, + {0x0690, 0x01}, + {0x0691, 0x00}, + {0x0692, 0x01}, + {0x0693, 0x00}, + {0x0694, 0x00}, + {0x0695, 0x00}, + {0x0696, 0x00}, + {0x0697, 0x00}, + {0x0698, 0x2A}, + {0x0699, 0x80}, + {0x069A, 0x1F}, + {0x069B, 0x00}, + {0x069C, 0x02}, + {0x069D, 0xF5}, + {0x069E, 0x03}, + {0x069F, 0x6D}, + {0x06A0, 0x0C}, + {0x06A1, 0xB8}, + {0x06A2, 0x0D}, + {0x06A3, 0x74}, + {0x06A4, 0x00}, + {0x06A5, 0x2F}, + {0x06A6, 0x00}, + {0x06A7, 0x2F}, + {0x0F00, 0x00}, + {0x0F01, 0x00}, + {0x0100, 0x01}, + {0x0102, 0x02}, + {0x0104, 0x03}, +#endif + {0x020B, 0x48}, + {0x020C, 0x64}, + {0x040A, 0x40}, + {0x040B, 0x33}, + {0x010c , 0x00}, + {0x010d , 0x08}, + {0x010e , 0x00}, + {0x010f , 0x08}, + {0x010a , 0x00}, + {0x0109, 0x00}, + {0x010A, 0x04}, + {0x010B, 0x03}, + {0x0110, 0x03}, + {0x0111, 0x20}, + {0x0112, 0x02}, + {0x0113, 0x58}, + {0x0116, 0x02}, + {0x0118, 0x40}, + {0x0119, 0x02}, + {0x011a, 0x04}, + {0x011B, 0x01}, + {0x0, 0x0}, +}; + + + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + {0x020B , 0x48}, + {0x020C , 0x64}, + {0x040A , 0x40}, + {0x040B , 0x33}, + {0x0109 , 0x00}, + {0x010A , 0x04}, + {0x010B , 0x03}, + {0x010c , 0x00}, + {0x010d , 0xa8}, + {0x010e , 0x00}, + {0x010f , 0x60}, + {0x010a , 0x04}, + #if 1 + {0x0110 , 0x02}, + {0x0111 , 0x80}, + {0x0112 , 0x01}, + {0x0113 , 0xe0}, + #else + {0x0110, 0x03}, + {0x0111, 0x20}, + {0x0112, 0x02}, + {0x0113, 0x58}, + #endif + {0x0116 , 0x02}, + {0x0118 , 0x40}, + {0x0119 , 0x01}, + {0x011a , 0x04}, + {0x011B , 0x00}, + {0x0313 , 0x35}, + {0x0314 , 0x36}, + {0x0315 , 0x16}, + {0x0, 0x0}, +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0x0, 0x0}, +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + + + {0x0, 0x0}, +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + + {0x0, 0x0}, +}; +#endif +#if 0 +/* 160X120 QQVGA*/ +static struct reginfo gt2005_qqvga[] = +{ + + {0x300E, 0x34}, + {0x3011, 0x01}, + {0x3012, 0x10}, + {0x302a, 0x02}, + {0x302b, 0xE6}, + {0x306f, 0x14}, + {0x3362, 0x90}, + + {0x3070, 0x5d}, + {0x3072, 0x5d}, + {0x301c, 0x07}, + {0x301d, 0x07}, + + {0x3020, 0x01}, + {0x3021, 0x18}, + {0x3022, 0x00}, + {0x3023, 0x06}, + {0x3024, 0x06}, + {0x3025, 0x58}, + {0x3026, 0x02}, + {0x3027, 0x61}, + {0x3088, 0x00}, + {0x3089, 0xa0}, + {0x308a, 0x00}, + {0x308b, 0x78}, + {0x3316, 0x64}, + {0x3317, 0x25}, + {0x3318, 0x80}, + {0x3319, 0x08}, + {0x331a, 0x0a}, + {0x331b, 0x07}, + {0x331c, 0x80}, + {0x331d, 0x38}, + {0x3100, 0x00}, + {0x3302, 0x11}, + + {0x0, 0x0}, +}; + + + +static struct reginfo gt2005_Sharpness_auto[] = +{ + {0x3306, 0x00}, +}; + +static struct reginfo gt2005_Sharpness1[] = +{ + {0x3306, 0x08}, + {0x3371, 0x00}, +}; + +static struct reginfo gt2005_Sharpness2[][3] = +{ + //Sharpness 2 + {0x3306, 0x08}, + {0x3371, 0x01}, +}; + +static struct reginfo gt2005_Sharpness3[] = +{ + //default + {0x3306, 0x08}, + {0x332d, 0x02}, +}; +static struct reginfo gt2005_Sharpness4[]= +{ + //Sharpness 4 + {0x3306, 0x08}, + {0x332d, 0x03}, +}; + +static struct reginfo gt2005_Sharpness5[] = +{ + //Sharpness 5 + {0x3306, 0x08}, + {0x332d, 0x04}, +}; +#endif + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + //{0x3400, 0x00}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + //{0x3400, 0x02}, + {0x0000, 0x00} +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x3306, 0x00}, //AWB auto, bit[1]:0,auto + {0x0000, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x3306, 0x82}, + {0x3337, 0x68}, + {0x3338, 0x40}, + {0x3339, 0x4e}, + {0x0000, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x3306, 0x02}, //AWB off + {0x3337, 0x5e}, + {0x3338, 0x40}, + {0x3339, 0x46}, + {0x0000, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x3306, 0x02}, + {0x3337, 0x52}, + {0x3338, 0x40}, + {0x3339, 0x58}, + {0x0000, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x3306, 0x02}, + {0x3337, 0x44}, + {0x3338, 0x40}, + {0x3339, 0x70}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x49}, + {0x339a, 0x20}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x49}, + {0x339a, 0x10}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x00}, + {0x3390, 0x41}, + {0x339a, 0x00}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x41}, + {0x339a, 0x10}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x41}, + {0x339a, 0x20}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, //bit[2] enable + {0x3390, 0x41}, //bit[3] sign of brightness + {0x339a, 0x30}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x3391, 0x00}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x3391, 0x20}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x3391, 0x18}, + {0x3396, 0x40}, + {0x3397, 0xa6}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x3391, 0x40}, //bit[6] negative + {0x0000, 0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x3391, 0x18}, + {0x3396, 0xa0}, + {0x3397, 0x40}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x3391, 0x18}, + {0x3396, 0x60}, + {0x3397, 0x60}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + //-3 + {0x3047, 0x05}, + {0x3018, 0x40}, + {0x3019, 0x30}, + {0x301a, 0x71}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + //-2 + {0x3047, 0x05}, + {0x3018, 0x5a}, + {0x3019, 0x4a}, + {0x301a, 0xc2}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + //-0.3EV + {0x3047, 0x05}, + {0x3018, 0x6a}, + {0x3019, 0x5a}, + {0x301a, 0xd4}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + //default + {0x3047, 0x05}, + {0x3018, 0x78}, + {0x3019, 0x68}, + {0x301a, 0xd4}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + // 1 + {0x3047, 0x05}, + {0x3018, 0x88}, + {0x3019, 0x78}, + {0x301a, 0xd5}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + // 2 + {0x3047, 0x05}, + {0x3018, 0xa8}, + {0x3019, 0x98}, + {0x301a, 0xe6}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + // 3 + {0x3047, 0x05}, + {0x3018, 0xc8}, + {0x3019, 0xb8}, + {0x301a, 0xf7}, + {0x0000, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x02}, + {0x3394, 0x40}, + {0x3395, 0x40}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x02}, + {0x3394, 0x50}, + {0x3395, 0x50}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x02}, //enable color saturation + {0x3394, 0x70}, + {0x3395, 0x70}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + //Contrast -3 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x45}, + {0x3398, 0x18}, + {0x3399, 0x18}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + //Contrast -2 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x45}, + {0x3398, 0x18}, + {0x3399, 0x18}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + // Contrast -1 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x45}, + {0x3398, 0x1c}, + {0x3399, 0x1c}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + //Contrast 0 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x00}, + {0x3390, 0x41}, + {0x3398, 0x20}, + {0x3399, 0x20}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + //Contrast +1 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x45}, + {0x3398, 0x24}, + {0x3399, 0x24}, + {0x0000, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + //Contrast +2 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, + {0x3390, 0x45}, + {0x3398, 0x28}, + {0x3399, 0x28}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + //Contrast +3 + {0x3301, 0xff},//bit[7]:1, enable SDE + {0x3391, 0x04}, //bit[2] enable contrast/brightness + {0x3390, 0x45}, //bit[2] Yoffset sign + {0x3398, 0x2c}, + {0x3399, 0x2c}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0x3069, 0x84}, + {0x307c, 0x13}, + {0x3087, 0x02}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0x3069, 0x84}, + {0x307c, 0x10}, + {0x3087, 0x02}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x300e, 0x34}, + {0x300f, 0xa6}, + {0x3010, 0x81}, + {0x3082, 0x01}, + {0x30f4, 0x01}, + {0x3090, 0x3b}, + {0x3091, 0xc0}, + {0x30ac, 0x42}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x300e, 0x34}, + {0x300f, 0xa6}, + {0x3010, 0x81}, + {0x3082, 0x01}, + {0x30f4, 0x01}, + {0x3090, 0x33}, + {0x3091, 0xc0}, + {0x30ac, 0x42}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ +#if 0 /* ddl@rock-chips.com : */ + {0x3014, 0x04}, + {0x3015, 0x00}, + {0x302e, 0x00}, + {0x302d, 0x00}, + {0x0000, 0x00} +#else + {0x3014, 0x84}, + {0x3015, 0x02}, + {0x302e, 0x00}, + {0x302d, 0x00}, + {0x0000, 0x00} +#endif +}; + +static struct reginfo sensor_SceneNight[] = +{ +#if 1 + //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk + {0x300e, 0x34}, + {0x3011, 0x00}, + {0x302c, 0x00}, + {0x3071, 0x00}, + {0x3070, 0xb9}, + {0x301c, 0x02}, + {0x3073, 0x00}, + {0x3072, 0x9a}, + {0x301d, 0x03}, + {0x3014, 0x0c}, + {0x3015, 0x50},//add 5 dummy frame + {0x302e, 0x00}, + {0x302d, 0x00}, + {0x0000, 0x00} +#else + //15fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,18Mhz pclk + {0x300e, 0x34}, + {0x3011, 0x01}, + {0x302c, 0x00}, + {0x3071, 0x00}, + {0x3070, 0x5d}, + {0x301c, 0x05}, + {0x3073, 0x00}, + {0x3072, 0x4d}, + {0x301d, 0x07}, + {0x3014, 0x0c}, + {0x3015, 0x50}, + {0x302e, 0x00}, + {0x302d, 0x00}, +#endif +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u16 reg, u8 val) +{ + int err,cnt; + u8 buf[3]; + struct i2c_msg msg[1]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + buf[2] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[2]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} + +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int ret; + int i = 0,j=0; + u8 value; + + SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); + while(regarray[i].reg != 0) + { + ret = sensor_read(client,regarray[i].reg,&value); + if(ret !=0) + { + SENSOR_TR("read value failed\n"); + + } + if(regarray[i].val != value) + { + SENSOR_DG("%s reg[0x%x] check err,writte :0x%x read:0x%x\n",__FUNCTION__,regarray[i].reg,regarray[i].val,value); + } + else + j++; + + i++; + } + if(i==j) + SENSOR_DG("%s check success\n",__FUNCTION__); + + return 0; +} +#endif +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret,pid = 0; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* ret = sensor_write(client, 0x3012, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); */ //delay 5 microseconds + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x0000, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x0001, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_write(client, 0x30b0, 0x00); + sensor_write(client, 0x30b1, 0x00); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + {0x30ab, 0x00}, + {0x30ad, 0x0a}, + {0x30ae,0x27}, + {0x363b,0x01}, + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + winseqe_set_addr = sensor_uxga; + set_w = 1600; + set_h = 1200; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + set_w = 1600; + set_h = 1200; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gt2005 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret,pid = 0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + /* ret = sensor_write(client, 0x3012, 0x80); + if (ret != 0) + { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + return -ENODEV; + } + mdelay(5); */ //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x0000, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x0001, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); +#if CONFIG_SENSOR_Flash + int i; +#endif + int ret = 0; + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + diff --git a/drivers/media/video/hm2057.c b/drivers/media/video/hm2057.c new file mode 100755 index 000000000000..113aa43c3467 --- /dev/null +++ b/drivers/media/video/hm2057.c @@ -0,0 +1,1241 @@ + +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +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_SENSOR_HM2057 +#define SENSOR_V4L2_IDENT V4L2_IDENT_HM2057 +#define SENSOR_ID 0x2056 +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect); +static unsigned int SensorChipID[] = {SENSOR_ID,0x2057}; + +/* 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 + +#define SENSOR_PLL_ENABLE 1 +//ͬÑùµÄÖ¡ÂÊ bypass PLLµÄÆعâʱ¼äÊÇEnalble PLLµÄ2±¶ +//Enable PLL: 0x0025=0x00 +//bypass PLL: 0x0025=0x80 + + +#define SENSOR_FAST_MODE 1 +//¿ìËÙģʽ£¬Ö¡ÂÊÔ½¿ì£¬Ôëµã»áÔ½´ó£¬ÇåÎú¶È»áÔ½²î +//ËٶȺÍÇåÎú¶ÈÁ½Õß²»ÄܼæµÃ + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + + +}; + +/* +* Local define +*/ + + +/* +* 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[] = { +{0x0022,0x00}, +{0x0004,0x10}, +{0x0006,0x00}, +{0x000D,0x11}, +{0x000E,0x11}, +{0x000F,0x10},//00 +{0x0011,0x02}, +{0x0012,0x1C}, +{0x0013,0x01}, +{0x0015,0x02}, +{0x0016,0x80}, +{0x0018,0x00}, +{0x001D,0x40}, +{0x0020,0x40}, + +#if SENSOR_PLL_ENABLE + {0x0025,0x00}, +#else + {0x0025,0x80}, +#endif + +{0x0026,0x87}, +{0x0027,0x10},//0x30}, +{0x0040,0x20}, +{0x0053,0x0A}, +{0x0044,0x06}, +{0x0046,0xD8}, +{0x004A,0x0A}, +{0x004B,0x72}, +{0x0075,0x01}, +{0x002A,0x1F}, +{0x0070,0x5F}, +{0x0071,0xFF}, +{0x0072,0x55}, +{0x0073,0x50}, +{0x0080,0xC8}, +{0x0082,0xA2}, +{0x0083,0xF0}, +{0x0085,0x11},//0x12 HMAX Ô­³§½¨Òé ADC POWER ÒÔÇ°ÊÇ75%µÄÏÖÔÚÒªÉ趨³É100% +{0x0086,0x02}, +{0x0087,0x80}, +{0x0088,0x6C}, +{0x0089,0x2E}, +{0x008A,0x7D}, +{0x008D,0x20}, +{0x0090,0x00}, +{0x0091,0x10}, +{0x0092,0x11}, +{0x0093,0x12}, +{0x0094,0x16}, +{0x0095,0x08}, +{0x0096,0x00}, +{0x0097,0x10}, +{0x0098,0x11}, +{0x0099,0x12}, +{0x009A,0x06}, +{0x009B,0x34}, +{0x00A0,0x00}, +{0x00A1,0x04}, +{0x011F,0xF7}, +{0x0120,0x36}, +{0x0121,0x83}, +{0x0122,0x7B}, +{0x0123,0xC2}, +{0x0124,0xDE}, +{0x0125,0xDF}, +{0x0126,0x70}, +{0x0128,0x1F}, +{0x0132,0x10}, +{0x0131,0xBD}, +{0x0140,0x14}, +{0x0141,0x0A}, +{0x0142,0x14}, +{0x0143,0x0A}, +{0x0144,0x04}, +{0x0145,0x00}, +{0x0146,0x20}, +{0x0147,0x0A}, +{0x0148,0x10}, +{0x0149,0x0C}, +{0x014A,0x80}, +{0x014B,0x80}, +{0x014C,0x2E}, +{0x014D,0x2E}, +{0x014E,0x05}, +{0x014F,0x05}, +{0x0150,0x0D}, +{0x0155,0x00}, +{0x0156,0x10}, +{0x0157,0x0A}, +{0x0158,0x0A}, +{0x0159,0x0A}, +{0x015A,0x05}, +{0x015B,0x05}, +{0x015C,0x05}, +{0x015D,0x05}, +{0x015E,0x08}, +{0x015F,0xFF}, +{0x0160,0x50}, +{0x0161,0x20}, +{0x0162,0x14}, +{0x0163,0x0A}, +{0x0164,0x10}, +{0x0165,0x0A}, +{0x0166,0x0A}, +{0x018C,0x24}, +{0x018D,0x04}, +{0x018E,0x00}, +{0x018F,0x11}, +{0x0190,0x80}, +{0x0191,0x47}, +{0x0192,0x48}, +{0x0193,0x64}, +{0x0194,0x32}, +{0x0195,0xc8}, +{0x0196,0x96}, +{0x0197,0x64}, +{0x0198,0x32}, +{0x0199,0x14}, +{0x019A,0x20}, +{0x019B,0x14}, +{0x01B0,0x55}, +{0x01B1,0x0C}, +{0x01B2,0x0A}, +{0x01B3,0x10}, +{0x01B4,0x0E}, +{0x01BA,0x10}, +{0x01BB,0x04}, +{0x01D8,0x40}, +{0x01DE,0x60}, +{0x01E4,0x10}, +{0x01E5,0x10}, +{0x01F2,0x0C}, +{0x01F3,0x14}, +{0x01F8,0x04}, +{0x01F9,0x0C}, +{0x01FE,0x02}, +{0x01FF,0x04}, +{0x0220,0x00}, +{0x0221,0xB0}, +{0x0222,0x00}, +{0x0223,0x80}, +{0x0224,0x8E}, +{0x0225,0x00}, +{0x0226,0x88}, +{0x022A,0x88}, +{0x022B,0x00}, +{0x022C,0x8C}, +{0x022D,0x13}, +{0x022E,0x0B}, +{0x022F,0x13}, +{0x0230,0x0B}, +{0x0233,0x13}, +{0x0234,0x0B}, +{0x0235,0x28}, +{0x0236,0x03}, +{0x0237,0x28}, +{0x0238,0x03}, +{0x023B,0x28}, +{0x023C,0x03}, +{0x023D,0x5C}, +{0x023E,0x02}, +{0x023F,0x5C}, +{0x0240,0x02}, +{0x0243,0x5C}, +{0x0244,0x02}, +{0x0251,0x0E}, +{0x0252,0x00}, +{0x0280,0x0A}, +{0x0282,0x14}, +{0x0284,0x2A}, +{0x0286,0x50}, +{0x0288,0x60}, +{0x028A,0x6D}, +{0x028C,0x79}, +{0x028E,0x82}, +{0x0290,0x8A}, +{0x0292,0x91}, +{0x0294,0x9C}, +{0x0296,0xA7}, +{0x0298,0xBA}, +{0x029A,0xCD}, +{0x029C,0xE0}, +{0x029E,0x2D}, +{0x02A0,0x06}, +{0x02E0,0x04}, +{0x02C0,0x8F}, +{0x02C1,0x01}, +{0x02C2,0x8F}, +{0x02C3,0x07}, +{0x02C4,0xE3}, +{0x02C5,0x07}, +{0x02C6,0xC1}, +{0x02C7,0x07}, +{0x02C8,0x70}, +{0x02C9,0x01}, +{0x02CA,0xD0}, +{0x02CB,0x07}, +{0x02CC,0xF7}, +{0x02CD,0x07}, +{0x02CE,0x5A}, +{0x02CF,0x07}, +{0x02D0,0xB0}, +{0x02D1,0x01}, +{0x0302,0x00}, +{0x0303,0x00}, +{0x0304,0x00}, +{0x02F0,0x80}, +{0x02F1,0x07}, +{0x02F2,0x8E}, +{0x02F3,0x00}, +{0x02F4,0xF2}, +{0x02F5,0x07}, +{0x02F6,0xCC}, +{0x02F7,0x07}, +{0x02F8,0x16}, +{0x02F9,0x00}, +{0x02FA,0x1E}, +{0x02FB,0x00}, +{0x02FC,0x9D}, +{0x02FD,0x07}, +{0x02FE,0xA6}, +{0x02FF,0x07}, +{0x0300,0xBD}, +{0x0301,0x00}, +{0x0305,0x00}, +{0x0306,0x00}, +{0x0307,0x00}, +{0x032D,0x00}, +{0x032E,0x01}, +{0x032F,0x00}, +{0x0330,0x01}, +{0x0331,0x00}, +{0x0332,0x01}, +{0x0333,0x82}, +{0x0334,0x00}, +{0x0335,0x84}, +{0x0336,0x00}, +{0x0337,0x01}, +{0x0338,0x00}, +{0x0339,0x01}, +{0x033A,0x00}, +{0x033B,0x01}, +{0x033E,0x04}, +{0x033F,0x86}, +{0x0340,0x30}, +{0x0341,0x44}, +{0x0342,0x4A}, +{0x0343,0x42}, +{0x0344,0x74}, +{0x0345,0x4F}, +{0x0346,0x67}, +{0x0347,0x5C}, +{0x0348,0x59}, +{0x0349,0x67}, +{0x034A,0x4D}, +{0x034B,0x6E}, +{0x034C,0x44}, +{0x0350,0x80}, +{0x0351,0x80}, +{0x0352,0x18}, +{0x0353,0x18}, +{0x0354,0x6E}, +{0x0355,0x4A}, +{0x0356,0x73}, +{0x0357,0xC0}, +{0x0358,0x06}, +{0x035A,0x06}, +{0x035B,0xA0}, +{0x035C,0x73}, +{0x035D,0x50}, +{0x035E,0xC0}, +{0x035F,0xA0}, +{0x0360,0x02}, +{0x0361,0x18}, +{0x0362,0x80}, +{0x0363,0x6C}, +{0x0364,0x00}, +{0x0365,0xF0}, +{0x0366,0x20}, +{0x0367,0x0C}, +{0x0369,0x00}, +{0x036A,0x10}, +{0x036B,0x10}, +{0x036E,0x20}, +{0x036F,0x00}, +{0x0370,0x10}, +{0x0371,0x18}, +{0x0372,0x0C}, +{0x0373,0x38}, +{0x0374,0x3A}, +{0x0375,0x13}, +{0x0376,0x22}, +{0x0380,0xFF}, +{0x0381,0x4c}, +{0x0382,0x3c}, +{0x038A,0x40}, +{0x038B,0x08}, +{0x038C,0xC1}, +{0x038E,0x44}, + +#if SENSOR_PLL_ENABLE + //10 fps + {0x038F,0x07}, + {0x0390,0x5c}, +#else + #if SENSOR_FAST_MODE + //10 fps + {0x038F,0x03}, + {0x0390,0xae}, + #else + //7.5 fps + {0x038F,0x04}, //09 + {0x0390,0xE8}, //18 + #endif +#endif + +{0x0391,0x05}, +{0x0393,0x80}, +{0x0395,0x21}, +{0x0398,0x02}, +{0x0399,0x84}, +{0x039A,0x03}, +{0x039B,0x25}, +{0x039C,0x03}, +{0x039D,0xC6}, +{0x039E,0x05}, +{0x039F,0x08}, +{0x03A0,0x06}, +{0x03A1,0x4A}, +{0x03A2,0x07}, +{0x03A3,0x8C}, +{0x03A4,0x0A}, +{0x03A5,0x10}, +{0x03A6,0x0C}, +{0x03A7,0x0E}, +{0x03A8,0x10}, +{0x03A9,0x18}, +{0x03AA,0x20}, +{0x03AB,0x28}, +{0x03AC,0x1E}, +{0x03AD,0x1A}, +{0x03AE,0x13}, +{0x03AF,0x0C}, +{0x03B0,0x0B}, +{0x03B1,0x09}, +{0x03B3,0x10}, +{0x03B4,0x00}, +{0x03B5,0x10}, +{0x03B6,0x00}, +{0x03B7,0xEA}, +{0x03B8,0x00}, +{0x03B9,0x3A}, +{0x03BA,0x01}, +{0x03BB,0x9F}, +{0x03BC,0xCF}, +{0x03BD,0xE7}, +{0x03BE,0xF3}, +{0x03BF,0x01}, +{0x03D0,0xF8}, +{0x03E0,0x04}, +{0x03E1,0x01}, +{0x03E2,0x04}, +{0x03E4,0x10}, +{0x03E5,0x12}, +{0x03E6,0x00}, +{0x03E8,0x21}, +{0x03E9,0x23}, +{0x03EA,0x01}, +{0x03EC,0x21}, +{0x03ED,0x23}, +{0x03EE,0x01}, +{0x03F0,0x20}, +{0x03F1,0x22}, +{0x03F2,0x00}, +{0x0420,0x84}, +{0x0421,0x00}, +{0x0422,0x00}, +{0x0423,0x83}, +{0x0430,0x08}, +{0x0431,0x28}, +{0x0432,0x10}, +{0x0433,0x08}, +{0x0435,0x0C}, +{0x0450,0xFF}, +{0x0451,0xE8}, +{0x0452,0xC4}, +{0x0453,0x88}, +{0x0454,0x00}, +{0x0458,0x70}, +{0x0459,0x03}, +{0x045A,0x00}, +{0x045B,0x30}, +{0x045C,0x00}, +{0x045D,0x70}, +{0x0466,0x14}, +{0x047A,0x00}, +{0x047B,0x00}, +{0x0480,0x58}, +{0x0481,0x06}, +{0x0482,0x0C}, +{0x04B0,0x50}, +{0x04B6,0x30}, +{0x04B9,0x10}, +{0x04B3,0x10}, +{0x04B1,0x8E}, +{0x04B4,0x20}, +{0x0540,0x00}, +{0x0541,0x60},//9D +{0x0542,0x00}, +{0x0543,0x73},//BC +{0x0580,0x01}, +{0x0581,0x0F}, +{0x0582,0x04}, +{0x0594,0x00}, +{0x0595,0x04}, +{0x05A9,0x03}, +{0x05AA,0x40}, +{0x05AB,0x80}, +{0x05AC,0x0A}, +{0x05AD,0x10}, +{0x05AE,0x0C}, +{0x05AF,0x0C}, +{0x05B0,0x03}, +{0x05B1,0x03}, +{0x05B2,0x1C}, +{0x05B3,0x02}, +{0x05B4,0x00}, +{0x05B5,0x0C}, +{0x05B8,0x80}, +{0x05B9,0x32}, +{0x05BA,0x00}, +{0x05BB,0x80}, +{0x05BC,0x03}, +{0x05BD,0x00}, +{0x05BF,0x05}, +{0x05C0,0x10}, +{0x05C3,0x00}, +{0x05C4,0x0C}, +{0x05C5,0x20}, +{0x05C7,0x01}, +{0x05C8,0x14}, +{0x05C9,0x54}, +{0x05CA,0x14}, +{0x05CB,0xE0}, +{0x05CC,0x20}, +{0x05CD,0x00}, +{0x05CE,0x08}, +{0x05CF,0x60}, +{0x05D0,0x10}, +{0x05D1,0x05}, +{0x05D2,0x03}, +{0x05D4,0x00}, +{0x05D5,0x05}, +{0x05D6,0x05}, +{0x05D7,0x05}, +{0x05D8,0x08}, +{0x05DC,0x0C}, +{0x05D9,0x00}, +{0x05DB,0x00}, +{0x05DD,0x0F}, +{0x05DE,0x00}, +{0x05DF,0x0A}, +{0x05E0,0xA0}, +{0x05E1,0x00}, +{0x05E2,0xA0}, +{0x05E3,0x00}, +{0x05E4,0x05}, +{0x05E5,0x00}, +{0x05E6,0x24}, +{0x05E7,0x03}, +{0x05E8,0x07}, +{0x05E9,0x00}, +{0x05EA,0x5E}, +{0x05EB,0x02}, +{0x0660,0x04}, +{0x0661,0x16}, +{0x0662,0x04}, +{0x0663,0x28}, +{0x0664,0x04}, +{0x0665,0x18}, +{0x0666,0x04}, +{0x0667,0x21}, +{0x0668,0x04}, +{0x0669,0x0C}, +{0x066A,0x04}, +{0x066B,0x25}, +{0x066C,0x00}, +{0x066D,0x12}, +{0x066E,0x00}, +{0x066F,0x80}, +{0x0670,0x00}, +{0x0671,0x0A}, +{0x0672,0x04}, +{0x0673,0x1D}, +{0x0674,0x04}, +{0x0675,0x1D}, +{0x0676,0x00}, +{0x0677,0x7E}, +{0x0678,0x01}, +{0x0679,0x47}, +{0x067A,0x00}, +{0x067B,0x73}, +{0x067C,0x04}, +{0x067D,0x14}, +{0x067E,0x04}, +{0x067F,0x28}, +{0x0680,0x00}, +{0x0681,0x22}, +{0x0682,0x00}, +{0x0683,0xA5}, +{0x0684,0x00}, +{0x0685,0x1E}, +{0x0686,0x04}, +{0x0687,0x1D}, +{0x0688,0x04}, +{0x0689,0x19}, +{0x068A,0x04}, +{0x068B,0x21}, +{0x068C,0x04}, +{0x068D,0x0A}, +{0x068E,0x04}, +{0x068F,0x25}, +{0x0690,0x04}, +{0x0691,0x15}, +{0x0698,0x20}, +{0x0699,0x20}, +{0x069A,0x01}, +{0x069C,0x22}, +{0x069D,0x10}, +{0x069E,0x10}, +{0x069F,0x08}, +{0x0000,0x01}, +{0x0100,0x01}, +{0x0101,0x01}, +{0x0005,0x01}, + +SensorEnd + +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ +{0x0380,0xFE}, +{0x000D,0x00}, +{0x000E,0x00}, +{0x011F,0x88}, +{0x0125,0xDF}, +{0x0126,0x70}, +{0x0131,0xAC}, +{0x0366,0x20}, +{0x0433,0x40}, +{0x0435,0x50}, +{0x05E4,0x0A}, +{0x05E5,0x00}, +{0x05E6,0x49}, +{0x05E7,0x06}, +{0x05E8,0x0A}, +{0x05E9,0x00}, +{0x05EA,0xB9}, +{0x05EB,0x04}, +{0x0000,0x01}, +{0x0100,0x01}, +{0x0101,0x01}, +{0x0005,0x01}, + + 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[] = +{ +/*¼ÏñÍêºóÔÚ·µ»Øµ½Ô¤ÀÀ£¬Ô¤ÀÀʱÓÐË®²¨ÎƵÄbugÐÞ¸Ä<2012.11.22>*/ + {0x0380,0xFF}, +{0x0006,0x00}, +{0x000D,0x11}, +{0x000E,0x11}, +//{0x0012,0x1C}, +//{0x0013,0x01}, +//{{0x0027,0x18}, +{0x002A,0x1F}, +//{0x0071,0xFF}, +{0x0082,0xA2}, +{0x011F,0x80}, +{0x0125,0xDF}, +{0x0126,0x70}, +{0x0131,0xAD}, +{0x0144,0x04}, +{0x0190,0x80}, +{0x0192,0x48}, +//{0x0541,0x9D},// 0541ºÍ0543ÊDZíʾflicker step +//{0x0543,0xBC}, +{0x05E0,0xA0}, +{0x05E1,0x00}, +{0x05E2,0xA0}, +{0x05E3,0x00}, +{0x05E4,0x05}, +{0x05E5,0x00}, +{0x05E6,0x24}, +{0x05E7,0x03}, +{0x05E8,0x08}, +{0x05E9,0x00}, +{0x05EA,0x5F}, +{0x05EB,0x02}, +{0x0000,0x01}, +{0x0100,0x01}, +{0x0101,0x01}, + + 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[]={ + SensorRegVal(0x0001,0), + SensorRegVal(0x0002,0), + 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[]= +{ + {0x0380, 0xFF}, //AWB auto + {0x0000, 0x01}, + {0x0100, 0x01}, + {0x0101, 0x01}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x0380, 0xFD}, + {0x032D, 0x70}, + {0x032E, 0x01}, + {0x032F, 0x00}, + {0x0330, 0x01}, + {0x0331, 0x08}, + {0x0332, 0x01}, + {0x0101, 0xFF}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + {0x0380, 0xFD}, + {0x032D, 0x60}, + {0x032E, 0x01}, + {0x032F, 0x00}, + {0x0330, 0x01}, + {0x0331, 0x20}, + {0x0332, 0x01}, + {0x0101, 0xFF}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + {0x0380, 0xFD}, + {0x032D, 0x50}, + {0x032E, 0x01}, + {0x032F, 0x00}, + {0x0330, 0x01}, + {0x0331, 0x30}, + {0x0332, 0x01}, + {0x0101, 0xFF}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + {0x0380, 0xFD}, + {0x032D, 0x10}, + {0x032E, 0x01}, + {0x032F, 0x00}, + {0x0330, 0x01}, + {0x0331, 0xA0}, + {0x0332, 0x01}, + {0x0101, 0xFF}, + 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[] = +{ + {0x0488, 0x10}, + {0x0486, 0x00}, + {0x0487, 0xFF}, + {0x0101, 0xFF}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x0488, 0x12}, + {0x0486, 0x00}, + {0x0487, 0xFF}, + {0x0101, 0xFF}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x0488, 0x11}, + {0x0486, 0x40}, + {0x0487, 0x90}, + {0x0101, 0xFF}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + {0x0488, 0x12}, + {0x0486, 0x00}, + {0x0487, 0xFF}, + {0x0101, 0xFF}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + {0x0488, 0x11}, + {0x0486, 0xB0}, + {0x0487, 0x80}, + {0x0101, 0xFF}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + {0x0488, 0x11}, + {0x0486, 0x60}, + {0x0487, 0x60}, + {0x0101, 0xFF}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//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} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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) +{ + + SENSOR_DG("%s",__FUNCTION__); + + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + //struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + 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 0; +} +/* +* 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_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) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + SENSOR_DG("flip: %d",flip); + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/mt9p111.c b/drivers/media/video/mt9p111.c index 5d8ef04b7897..a2c74b8ce5ef 100755 --- a/drivers/media/video/mt9p111.c +++ b/drivers/media/video/mt9p111.c @@ -1,29 +1,11 @@ + +#include "generic_sensor.h" /* - * Driver for OV5642 CMOS Image Sensor from OmniVision - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "mt9p111.h" +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -32,1414 +14,1371 @@ module_param(debug, int, S_IRUGO|S_IWUSR); if (debug >= level) \ printk(KERN_WARNING fmt , ## arg); } while (0) -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ +/* Sensor Driver Configuration Begin */ #define SENSOR_NAME RK29_CAM_SENSOR_MT9P111 #define SENSOR_V4L2_IDENT V4L2_IDENT_MT9P111 -#define SENSOR_ID SEQUENCE_END -#define SENSOR_ID_REG SEQUENCE_END -#define SENSOR_RESET_REG 0x0010 -#define SENSOR_RESET_VAL 0x0115 -#define SENSOR_RESET_REG_LEN WORD_LEN -#define SENSOR_MIN_WIDTH 176 -#define SENSOR_MIN_HEIGHT 144 -#define SENSOR_MAX_WIDTH 2592 -#define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 -#define YUV420_BUFFER_MAX_SIZE 7558272 /* 2592*1944*1.5*/ - -#define CONFIG_SENSOR_WhiteBalance 0 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 0 -#define CONFIG_SENSOR_Scene 0 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 0 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 -#define CONFIG_SENSOR_Focus 1 - - -#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ -//#define CONFIG_SENSOR_I2C_SPEED 350000 /* Hz */ - -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 +#define SENSOR_ID 0x00 +#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 576 +#define SENSOR_PREVIEW_H 432 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 30000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 0 // sensor register address bytes +#define SENSOR_VALUE_LEN 0 // sensor register value bytes + +static unsigned int SensorConfiguration = CFG_Focus|CFG_FocusZone; +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 SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - - - -#if CONFIG_SENSOR_Focus -/*#define SENSOR_AF_MODE_INFINITY 0 -#define SENSOR_AF_MODE_MACRO 1 -#define SENSOR_AF_MODE_FIXED 2 -#define SENSOR_AF_MODE_AUTO 3 -#define SENSOR_AF_MODE_CONTINUOUS 4 -#define SENSOR_AF_MODE_CLOSE 5*/ -#define SENSOR_AF_MODE_AUTO 0 -#define SENSOR_AF_MODE_CLOSE 1 -#define SENSOR_AF_MODE_CONTINUOUS 2 -#endif - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - int status; - struct soc_camera_device *icd; - struct hrtimer timer; +#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 + +struct sensor_parameter +{ + +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + }; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_MT9P111_USER_DEFINED_SERIES -#include "mt9p111_user_series.c" -#else - -/* init 640X480 VGA */ -static struct reginfo sensor_init_data[] = -{ -{ 0x0010, 0x0340, WORD_LEN, 0 }, - - -{ 0x0010, 0x0340, WORD_LEN, 0 }, // PLL_DIVIDERS -{ 0x0012, 0x0080, WORD_LEN, 0 }, // PLL_P_DIVIDERS -{ 0x0014, 0x2025, WORD_LEN, 0 }, // PLL_CONTROL -{ 0x001E, 0x0565, WORD_LEN, 0 }, // PAD_SLEW_PAD_CONFIG -{ 0x0022, 0x0030, WORD_LEN, 0 }, // VDD_DIS_COUNTER -{ 0x002A, 0x7FFF, WORD_LEN, 0 }, // PLL_P4_P5_P6_DIVIDERS -{ 0x002C, 0x0000, WORD_LEN, 0 }, // PLL_P7_DIVIDER -{ 0x002E, 0x0000, WORD_LEN, 0 }, // SENSOR_CLOCK_DIVIDER -{ 0x0018, 0x400c, WORD_LEN, 0 }, // STANDBY_CONTROL_AND_STATUS + +/* +* 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[] = { +{ 0x0010, 0x0340, 0xffff,0xffff }, + + +{ 0x0010, 0x0340, 0xffff,0xffff }, // PLL_DIVIDERS +{ 0x0012, 0x0080, 0xffff,0xffff }, // PLL_P_DIVIDERS +{ 0x0014, 0x2025, 0xffff,0xffff }, // PLL_CONTROL +{ 0x001E, 0x0565, 0xffff,0xffff }, // PAD_SLEW_PAD_CONFIG +{ 0x0022, 0x0030, 0xffff,0xffff }, // VDD_DIS_COUNTER +{ 0x002A, 0x7FFF, 0xffff,0xffff }, // PLL_P4_P5_P6_DIVIDERS +{ 0x002C, 0x0000, 0xffff,0xffff }, // PLL_P7_DIVIDER +{ 0x002E, 0x0000, 0xffff,0xffff }, // SENSOR_CLOCK_DIVIDER +{ 0x0018, 0x400c, 0xffff,0xffff }, // STANDBY_CONTROL_AND_STATUS //delay = 100 -{SEQUENCE_WAIT_MS,300,WORD_LEN,0}, -{ 0x098E, 0x483A, WORD_LEN, 0 }, // LOGICAL_ADDRESS_ACCESS -{ 0xC83A, 0x000C, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_START -{ 0xC83C, 0x0018, WORD_LEN, 0 }, // CAM_CORE_A_X_ADDR_START -{ 0xC83E, 0x07B1, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_END -{ 0xC840, 0x0A45, WORD_LEN, 0 }, // CAM_CORE_A_X_ADDR_END -{ 0xC842, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_ROW_SPEED -{ 0xC844, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_X_CORE -{ 0xC846, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_Y_CORE -{ 0xC848, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_X_PIPE -{ 0xC84A, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_Y_PIPE -{ 0xC84C, 0x00F6, WORD_LEN, 0 }, // CAM_CORE_A_POWER_MODE -{ 0xC84E, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_BIN_MODE -{ 0xC850, 0x00, BYTE_LEN, 0}, // CAM_CORE_A_ORIENTATION -{ 0xC851, 0x00, BYTE_LEN, 0}, // CAM_CORE_A_PIXEL_ORDER -{ 0xC852, 0x019C, WORD_LEN, 0 }, // CAM_CORE_A_FINE_CORRECTION -{ 0xC854, 0x0732, WORD_LEN, 0 }, // CAM_CORE_A_FINE_ITMIN -{ 0xC858, 0x0000, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMIN -{ 0xC85A, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMAX_MARGIN -{ 0xC85C, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_MIN_FRAME_LENGTH_LINES -{ 0xC85E, 0xFFFF, WORD_LEN, 0 }, // CAM_CORE_A_MAX_FRAME_LENGTH_LINES -{ 0xC860, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_BASE_FRAME_LENGTH_LINES -{ 0xC862, 0x1194, WORD_LEN, 0 }, // CAM_CORE_A_MIN_LINE_LENGTH_PCLK -{ 0xC864, 0xFFFE, WORD_LEN, 0 }, // CAM_CORE_A_MAX_LINE_LENGTH_PCLK -{ 0xC866, 0x7F7F, WORD_LEN, 0 }, // CAM_CORE_A_P4_5_6_DIVIDER -{ 0xC868, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_FRAME_LENGTH_LINES -{ 0xC86A, 0x1194, WORD_LEN, 0 }, // CAM_CORE_A_LINE_LENGTH_PCK -{ 0xC86C, 0x0518, WORD_LEN, 0 }, // CAM_CORE_A_OUTPUT_SIZE_WIDTH -{ 0xC86E, 0x03D4, WORD_LEN, 0 }, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT -{ 0xC870, 0x0014, WORD_LEN, 0 }, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK -{ 0xC858, 0x0003, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMIN -{ 0xC8B8, 0x0004, WORD_LEN, 0 }, // CAM_OUTPUT_0_JPEG_CONTROL -{ 0xC8AE, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_0_OUTPUT_FORMAT -{ 0xC8AA, 0x0280, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_WIDTH -{ 0xC8AC, 0x01E0, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_HEIGHT -{ 0xC872, 0x0010, WORD_LEN, 0 }, // CAM_CORE_B_Y_ADDR_START -{ 0xC874, 0x001C, WORD_LEN, 0 }, // CAM_CORE_B_X_ADDR_START -{ 0xC876, 0x07AF, WORD_LEN, 0 }, // CAM_CORE_B_Y_ADDR_END -{ 0xC878, 0x0A43, WORD_LEN, 0 }, // CAM_CORE_B_X_ADDR_END -{ 0xC87A, 0x0001, WORD_LEN, 0 }, // CAM_CORE_B_ROW_SPEED -{ 0xC87C, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_X_CORE -{ 0xC87E, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_Y_CORE -{ 0xC880, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_X_PIPE -{ 0xC882, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_Y_PIPE -{ 0xC884, 0x00F2, WORD_LEN, 0 }, // CAM_CORE_B_POWER_MODE -{ 0xC886, 0x0000, WORD_LEN, 0 }, // CAM_CORE_B_BIN_MODE -{ 0xC888, 0x00, BYTE_LEN, 0}, // CAM_CORE_B_ORIENTATION -{ 0xC889, 0x00, BYTE_LEN, 0}, // CAM_CORE_B_PIXEL_ORDER -{ 0xC88A, 0x009C, WORD_LEN, 0 }, // CAM_CORE_B_FINE_CORRECTION -{ 0xC88C, 0x034A, WORD_LEN, 0 }, // CAM_CORE_B_FINE_ITMIN -{ 0xC890, 0x0000, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMIN -{ 0xC892, 0x0001, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMAX_MARGIN -{ 0xC894, 0x07EF, WORD_LEN, 0 }, // CAM_CORE_B_MIN_FRAME_LENGTH_LINES -{ 0xC896, 0xFFFF, WORD_LEN, 0 }, // CAM_CORE_B_MAX_FRAME_LENGTH_LINES -{ 0xC898, 0x082F, WORD_LEN, 0 }, // CAM_CORE_B_BASE_FRAME_LENGTH_LINES -{ 0xC89A, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK -{ 0xC89C, 0xFFFE, WORD_LEN, 0 }, // CAM_CORE_B_MAX_LINE_LENGTH_PCLK -{ 0xC89E, 0x7F7F, WORD_LEN, 0 }, // CAM_CORE_B_P4_5_6_DIVIDER -{ 0xC8A0, 0x07EF, WORD_LEN, 0 }, // CAM_CORE_B_FRAME_LENGTH_LINES -{ 0xC8A2, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_LINE_LENGTH_PCK -{ 0xC8A4, 0x0A28, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_WIDTH -{ 0xC8A6, 0x07A0, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT -{ 0xC8A8, 0x0124, WORD_LEN, 0 }, // CAM_CORE_B_RX_FIFO_TRIGGER_MARK -{ 0xC890, 0x0003, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMIN -{ 0xC8C0, 0x0A20, WORD_LEN, 0 }, // CAM_OUTPUT_1_IMAGE_WIDTH -{ 0xC8C2, 0x0798, WORD_LEN, 0 }, // CAM_OUTPUT_1_IMAGE_HEIGHT -{ 0xC89A, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK -{ 0xC8A2, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_LINE_LENGTH_PCK -{ 0xC8C4, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_1_OUTPUT_FORMAT -{ 0xC8C6, 0x0000, WORD_LEN, 0 }, // CAM_OUTPUT_1_OUTPUT_FORMAT_ORDER -{ 0xC8CE, 0x0014, WORD_LEN, 0 }, // CAM_OUTPUT_1_JPEG_CONTROL -{ 0xD822, 0x4610, WORD_LEN, 0 }, // JPEG_JPSS_CTRL_VAR -{ 0x3330, 0x0000, WORD_LEN, 0 }, // OUTPUT_FORMAT_TEST -{ 0x098E, 0xA00E, WORD_LEN, 0 }, // LOGICAL_ADDRESS_ACCESS -{ 0xA00E, 0x32, BYTE_LEN, 0}, // FD_MAX_NUM_AUTOCOR_FUNC_VALUES_TO_CHECK -{ 0xA010, 0x00CC, WORD_LEN, 0 }, // FD_MIN_EXPECTED50HZ_FLICKER_PERIOD -{ 0xA012, 0x00E0, WORD_LEN, 0 }, // FD_MAX_EXPECTED50HZ_FLICKER_PERIOD -{ 0xA014, 0x00A8, WORD_LEN, 0 }, // FD_MIN_EXPECTED60HZ_FLICKER_PERIOD -{ 0xA016, 0x00BC, WORD_LEN, 0 }, // FD_MAX_EXPECTED60HZ_FLICKER_PERIOD -{ 0xA018, 0x00D6, WORD_LEN, 0 }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_A -{ 0xA01A, 0x0075, WORD_LEN, 0 }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_B -{ 0xA01C, 0x00B2, WORD_LEN, 0 }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_A -{ 0xA01E, 0x0062, WORD_LEN, 0 }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_B -{ 0xA000, 0x10, BYTE_LEN, 0}, // FD_STATUS -{ 0x8417, 0x02, BYTE_LEN, 0}, // SEQ_STATE_CFG_1_FD +SensorWaitMs(300), +{ 0x098E, 0x483A, 0xffff,0xffff }, // LOGICAL_ADDRESS_ACCESS +{ 0xC83A, 0x000C, 0xffff,0xffff }, // CAM_CORE_A_Y_ADDR_START +{ 0xC83C, 0x0018, 0xffff,0xffff }, // CAM_CORE_A_X_ADDR_START +{ 0xC83E, 0x07B1, 0xffff,0xffff }, // CAM_CORE_A_Y_ADDR_END +{ 0xC840, 0x0A45, 0xffff,0xffff }, // CAM_CORE_A_X_ADDR_END +{ 0xC842, 0x0001, 0xffff,0xffff }, // CAM_CORE_A_ROW_SPEED +{ 0xC844, 0x0103, 0xffff,0xffff }, // CAM_CORE_A_SKIP_X_CORE +{ 0xC846, 0x0103, 0xffff,0xffff }, // CAM_CORE_A_SKIP_Y_CORE +{ 0xC848, 0x0103, 0xffff,0xffff }, // CAM_CORE_A_SKIP_X_PIPE +{ 0xC84A, 0x0103, 0xffff,0xffff }, // CAM_CORE_A_SKIP_Y_PIPE +{ 0xC84C, 0x00F6, 0xffff,0xffff }, // CAM_CORE_A_POWER_MODE +{ 0xC84E, 0x0001, 0xffff,0xffff }, // CAM_CORE_A_BIN_MODE +{ 0xC850, 0x00, 0xffff,0xff}, // CAM_CORE_A_ORIENTATION +{ 0xC851, 0x00, 0xffff,0xff}, // CAM_CORE_A_PIXEL_ORDER +{ 0xC852, 0x019C, 0xffff,0xffff }, // CAM_CORE_A_FINE_CORRECTION +{ 0xC854, 0x0732, 0xffff,0xffff }, // CAM_CORE_A_FINE_ITMIN +{ 0xC858, 0x0000, 0xffff,0xffff }, // CAM_CORE_A_COARSE_ITMIN +{ 0xC85A, 0x0001, 0xffff,0xffff }, // CAM_CORE_A_COARSE_ITMAX_MARGIN +{ 0xC85C, 0x0423, 0xffff,0xffff }, // CAM_CORE_A_MIN_FRAME_LENGTH_LINES +{ 0xC85E, 0xFFFF, 0xffff,0xffff }, // CAM_CORE_A_MAX_FRAME_LENGTH_LINES +{ 0xC860, 0x0423, 0xffff,0xffff }, // CAM_CORE_A_BASE_FRAME_LENGTH_LINES +{ 0xC862, 0x1194, 0xffff,0xffff }, // CAM_CORE_A_MIN_LINE_LENGTH_PCLK +{ 0xC864, 0xFFFE, 0xffff,0xffff }, // CAM_CORE_A_MAX_LINE_LENGTH_PCLK +{ 0xC866, 0x7F7F, 0xffff,0xffff }, // CAM_CORE_A_P4_5_6_DIVIDER +{ 0xC868, 0x0423, 0xffff,0xffff }, // CAM_CORE_A_FRAME_LENGTH_LINES +{ 0xC86A, 0x1194, 0xffff,0xffff }, // CAM_CORE_A_LINE_LENGTH_PCK +{ 0xC86C, 0x0518, 0xffff,0xffff }, // CAM_CORE_A_OUTPUT_SIZE_WIDTH +{ 0xC86E, 0x03D4, 0xffff,0xffff }, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT +{ 0xC870, 0x0014, 0xffff,0xffff }, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK +{ 0xC858, 0x0003, 0xffff,0xffff }, // CAM_CORE_A_COARSE_ITMIN +{ 0xC8B8, 0x0004, 0xffff,0xffff }, // CAM_OUTPUT_0_JPEG_CONTROL +{ 0xC8AE, 0x0001, 0xffff,0xffff }, // CAM_OUTPUT_0_OUTPUT_FORMAT +{ 0xC8AA, 0x0280, 0xffff,0xffff }, // CAM_OUTPUT_0_IMAGE_WIDTH +{ 0xC8AC, 0x01E0, 0xffff,0xffff }, // CAM_OUTPUT_0_IMAGE_HEIGHT +{ 0xC872, 0x0010, 0xffff,0xffff }, // CAM_CORE_B_Y_ADDR_START +{ 0xC874, 0x001C, 0xffff,0xffff }, // CAM_CORE_B_X_ADDR_START +{ 0xC876, 0x07AF, 0xffff,0xffff }, // CAM_CORE_B_Y_ADDR_END +{ 0xC878, 0x0A43, 0xffff,0xffff }, // CAM_CORE_B_X_ADDR_END +{ 0xC87A, 0x0001, 0xffff,0xffff }, // CAM_CORE_B_ROW_SPEED +{ 0xC87C, 0x0101, 0xffff,0xffff }, // CAM_CORE_B_SKIP_X_CORE +{ 0xC87E, 0x0101, 0xffff,0xffff }, // CAM_CORE_B_SKIP_Y_CORE +{ 0xC880, 0x0101, 0xffff,0xffff }, // CAM_CORE_B_SKIP_X_PIPE +{ 0xC882, 0x0101, 0xffff,0xffff }, // CAM_CORE_B_SKIP_Y_PIPE +{ 0xC884, 0x00F2, 0xffff,0xffff }, // CAM_CORE_B_POWER_MODE +{ 0xC886, 0x0000, 0xffff,0xffff }, // CAM_CORE_B_BIN_MODE +{ 0xC888, 0x00, 0xffff,0xff}, // CAM_CORE_B_ORIENTATION +{ 0xC889, 0x00, 0xffff,0xff}, // CAM_CORE_B_PIXEL_ORDER +{ 0xC88A, 0x009C, 0xffff,0xffff }, // CAM_CORE_B_FINE_CORRECTION +{ 0xC88C, 0x034A, 0xffff,0xffff }, // CAM_CORE_B_FINE_ITMIN +{ 0xC890, 0x0000, 0xffff,0xffff }, // CAM_CORE_B_COARSE_ITMIN +{ 0xC892, 0x0001, 0xffff,0xffff }, // CAM_CORE_B_COARSE_ITMAX_MARGIN +{ 0xC894, 0x07EF, 0xffff,0xffff }, // CAM_CORE_B_MIN_FRAME_LENGTH_LINES +{ 0xC896, 0xFFFF, 0xffff,0xffff }, // CAM_CORE_B_MAX_FRAME_LENGTH_LINES +{ 0xC898, 0x082F, 0xffff,0xffff }, // CAM_CORE_B_BASE_FRAME_LENGTH_LINES +{ 0xC89A, 0x1964, 0xffff,0xffff }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK +{ 0xC89C, 0xFFFE, 0xffff,0xffff }, // CAM_CORE_B_MAX_LINE_LENGTH_PCLK +{ 0xC89E, 0x7F7F, 0xffff,0xffff }, // CAM_CORE_B_P4_5_6_DIVIDER +{ 0xC8A0, 0x07EF, 0xffff,0xffff }, // CAM_CORE_B_FRAME_LENGTH_LINES +{ 0xC8A2, 0x1964, 0xffff,0xffff }, // CAM_CORE_B_LINE_LENGTH_PCK +{ 0xC8A4, 0x0A28, 0xffff,0xffff }, // CAM_CORE_B_OUTPUT_SIZE_WIDTH +{ 0xC8A6, 0x07A0, 0xffff,0xffff }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT +{ 0xC8A8, 0x0124, 0xffff,0xffff }, // CAM_CORE_B_RX_FIFO_TRIGGER_MARK +{ 0xC890, 0x0003, 0xffff,0xffff }, // CAM_CORE_B_COARSE_ITMIN +{ 0xC8C0, 0x0A20, 0xffff,0xffff }, // CAM_OUTPUT_1_IMAGE_WIDTH +{ 0xC8C2, 0x0798, 0xffff,0xffff }, // CAM_OUTPUT_1_IMAGE_HEIGHT +{ 0xC89A, 0x1964, 0xffff,0xffff }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK +{ 0xC8A2, 0x1964, 0xffff,0xffff }, // CAM_CORE_B_LINE_LENGTH_PCK +{ 0xC8C4, 0x0001, 0xffff,0xffff }, // CAM_OUTPUT_1_OUTPUT_FORMAT +{ 0xC8C6, 0x0000, 0xffff,0xffff }, // CAM_OUTPUT_1_OUTPUT_FORMAT_ORDER +{ 0xC8CE, 0x0014, 0xffff,0xffff }, // CAM_OUTPUT_1_JPEG_CONTROL +{ 0xD822, 0x4610, 0xffff,0xffff }, // JPEG_JPSS_CTRL_VAR +{ 0x3330, 0x0000, 0xffff,0xffff }, // OUTPUT_FORMAT_TEST +{ 0x098E, 0xA00E, 0xffff,0xffff }, // LOGICAL_ADDRESS_ACCESS +{ 0xA00E, 0x32, 0xffff,0xff}, // FD_MAX_NUM_AUTOCOR_FUNC_VALUES_TO_CHECK +{ 0xA010, 0x00CC, 0xffff,0xffff }, // FD_MIN_EXPECTED50HZ_FLICKER_PERIOD +{ 0xA012, 0x00E0, 0xffff,0xffff }, // FD_MAX_EXPECTED50HZ_FLICKER_PERIOD +{ 0xA014, 0x00A8, 0xffff,0xffff }, // FD_MIN_EXPECTED60HZ_FLICKER_PERIOD +{ 0xA016, 0x00BC, 0xffff,0xffff }, // FD_MAX_EXPECTED60HZ_FLICKER_PERIOD +{ 0xA018, 0x00D6, 0xffff,0xffff }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_A +{ 0xA01A, 0x0075, 0xffff,0xffff }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_B +{ 0xA01C, 0x00B2, 0xffff,0xffff }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_A +{ 0xA01E, 0x0062, 0xffff,0xffff }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_B +{ 0xA000, 0x10, 0xffff,0xff}, // FD_STATUS +{ 0x8417, 0x02, 0xffff,0xff}, // SEQ_STATE_CFG_1_FD //delay = 100 -{ SEQUENCE_WAIT_MS,100, BYTE_LEN, 0}, - +SensorWaitMs(100), //[Step2-Fixups] // Default variable access mode is always logical. -{ 0x098E, 0x0000, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS -{ 0x301A, 0x0030, WORD_LEN, 0}, // RESET_REGISTER -{ 0x316C, 0xB430, WORD_LEN, 0}, // DAC_TXLO -{ 0x31E0, 0x0003, WORD_LEN, 0}, // PIX_DEF_ID -{ 0x3E2E, 0xF319, WORD_LEN, 0}, // SAMP_SPARE -{ 0x3EE6, 0xA7C1, WORD_LEN, 0}, // DAC_LD_26_27 -{ 0x301E, 0x00A8, WORD_LEN, 0}, // DATA_PEDESTAL -{ 0xDC33, 0x2A, BYTE_LEN, 0}, // SYS_FIRST_BLACK_LEVEL -{ 0x3812, 0x212C, WORD_LEN, 0}, // OTPM_CFG -{ 0x0982, 0x0000, WORD_LEN, 0}, // ACCESS_CTL_STAT -{ 0x098A, 0x0000, WORD_LEN, 0}, // PHYSICAL_ADDRESS_ACCESS -{ 0x886C, 0xC0F1, WORD_LEN, 0}, -{ 0x886E, 0xC5E1, WORD_LEN, 0}, -{ 0x8870, 0x246A, WORD_LEN, 0}, -{ 0x8872, 0x1280, WORD_LEN, 0}, -{ 0x8874, 0xC4E1, WORD_LEN, 0}, -{ 0x8876, 0xD20F, WORD_LEN, 0}, -{ 0x8878, 0x2069, WORD_LEN, 0}, -{ 0x887A, 0x0000, WORD_LEN, 0}, -{ 0x887C, 0x6A62, WORD_LEN, 0}, -{ 0x887E, 0x1303, WORD_LEN, 0}, -{ 0x8880, 0x0084, WORD_LEN, 0}, -{ 0x8882, 0x1734, WORD_LEN, 0}, -{ 0x8884, 0x7005, WORD_LEN, 0}, -{ 0x8886, 0xD801, WORD_LEN, 0}, -{ 0x8888, 0x8A41, WORD_LEN, 0}, -{ 0x888A, 0xD900, WORD_LEN, 0}, -{ 0x888C, 0x0D5A, WORD_LEN, 0}, -{ 0x888E, 0x0664, WORD_LEN, 0}, -{ 0x8890, 0x8B61, WORD_LEN, 0}, -{ 0x8892, 0xE80B, WORD_LEN, 0}, -{ 0x8894, 0x000D, WORD_LEN, 0}, -{ 0x8896, 0x0020, WORD_LEN, 0}, -{ 0x8898, 0xD508, WORD_LEN, 0}, -{ 0x889A, 0x1504, WORD_LEN, 0}, -{ 0x889C, 0x1400, WORD_LEN, 0}, -{ 0x889E, 0x7840, WORD_LEN, 0}, -{ 0x88A0, 0xD007, WORD_LEN, 0}, -{ 0x88A2, 0x0DFB, WORD_LEN, 0}, -{ 0x88A4, 0x9004, WORD_LEN, 0}, -{ 0x88A6, 0xC4C1, WORD_LEN, 0}, -{ 0x88A8, 0x2029, WORD_LEN, 0}, -{ 0x88AA, 0x0300, WORD_LEN, 0}, -{ 0x88AC, 0x0219, WORD_LEN, 0}, -{ 0x88AE, 0x06C4, WORD_LEN, 0}, -{ 0x88B0, 0xFF80, WORD_LEN, 0}, -{ 0x88B2, 0x08D4, WORD_LEN, 0}, -{ 0x88B4, 0xFF80, WORD_LEN, 0}, -{ 0x88B6, 0x086C, WORD_LEN, 0}, -{ 0x88B8, 0xFF80, WORD_LEN, 0}, -{ 0x88BA, 0x08C0, WORD_LEN, 0}, -{ 0x88BC, 0xFF80, WORD_LEN, 0}, -{ 0x88BE, 0x08D4, WORD_LEN, 0}, -{ 0x88C0, 0xFF80, WORD_LEN, 0}, -{ 0x88C2, 0x08DC, WORD_LEN, 0}, -{ 0x88C4, 0xFF80, WORD_LEN, 0}, -{ 0x88C6, 0x0F58, WORD_LEN, 0}, -{ 0x88C8, 0xFF80, WORD_LEN, 0}, -{ 0x88CA, 0x0920, WORD_LEN, 0}, -{ 0x88CC, 0xFF80, WORD_LEN, 0}, -{ 0x88CE, 0x1010, WORD_LEN, 0}, -{ 0x88D0, 0xFF80, WORD_LEN, 0}, -{ 0x88D2, 0x1030, WORD_LEN, 0}, -{ 0x88D4, 0x0010, WORD_LEN, 0}, -{ 0x88D6, 0x0008, WORD_LEN, 0}, -{ 0x88D8, 0x0000, WORD_LEN, 0}, -{ 0x88DA, 0x0000, WORD_LEN, 0}, -{ 0x88DC, 0xD102, WORD_LEN, 0}, -{ 0x88DE, 0xD003, WORD_LEN, 0}, -{ 0x88E0, 0x7FE0, WORD_LEN, 0}, -{ 0x88E2, 0xB035, WORD_LEN, 0}, -{ 0x88E4, 0xFF80, WORD_LEN, 0}, -{ 0x88E6, 0x10C8, WORD_LEN, 0}, -{ 0x88E8, 0xFF80, WORD_LEN, 0}, -{ 0x88EA, 0x0118, WORD_LEN, 0}, -{ 0x88EC, 0xC0F1, WORD_LEN, 0}, -{ 0x88EE, 0xC5E1, WORD_LEN, 0}, -{ 0x88F0, 0xD5EC, WORD_LEN, 0}, -{ 0x88F2, 0x8D04, WORD_LEN, 0}, -{ 0x88F4, 0x8D25, WORD_LEN, 0}, -{ 0x88F6, 0xB808, WORD_LEN, 0}, -{ 0x88F8, 0x7825, WORD_LEN, 0}, -{ 0x88FA, 0x0821, WORD_LEN, 0}, -{ 0x88FC, 0x01DE, WORD_LEN, 0}, -{ 0x88FE, 0xD0EA, WORD_LEN, 0}, -{ 0x8900, 0x8000, WORD_LEN, 0}, -{ 0x8902, 0x8008, WORD_LEN, 0}, -{ 0x8904, 0x7840, WORD_LEN, 0}, -{ 0x8906, 0x8D04, WORD_LEN, 0}, -{ 0x8908, 0x8D25, WORD_LEN, 0}, -{ 0x890A, 0xB808, WORD_LEN, 0}, -{ 0x890C, 0x7825, WORD_LEN, 0}, -{ 0x890E, 0xB8A7, WORD_LEN, 0}, -{ 0x8910, 0x2841, WORD_LEN, 0}, -{ 0x8912, 0x0201, WORD_LEN, 0}, -{ 0x8914, 0xAD24, WORD_LEN, 0}, -{ 0x8916, 0xAD05, WORD_LEN, 0}, -{ 0x8918, 0x09A6, WORD_LEN, 0}, -{ 0x891A, 0x0104, WORD_LEN, 0}, -{ 0x891C, 0x01A9, WORD_LEN, 0}, -{ 0x891E, 0x06C4, WORD_LEN, 0}, -{ 0x8920, 0xC0F1, WORD_LEN, 0}, -{ 0x8922, 0x0932, WORD_LEN, 0}, -{ 0x8924, 0x06E4, WORD_LEN, 0}, -{ 0x8926, 0xDA38, WORD_LEN, 0}, -{ 0x8928, 0xD1E0, WORD_LEN, 0}, -{ 0x892A, 0xD5E1, WORD_LEN, 0}, -{ 0x892C, 0x76A9, WORD_LEN, 0}, -{ 0x892E, 0x0EC6, WORD_LEN, 0}, -{ 0x8930, 0x06A4, WORD_LEN, 0}, -{ 0x8932, 0x70C9, WORD_LEN, 0}, -{ 0x8934, 0xD0DF, WORD_LEN, 0}, -{ 0x8936, 0xA501, WORD_LEN, 0}, -{ 0x8938, 0xD0DF, WORD_LEN, 0}, -{ 0x893A, 0xA503, WORD_LEN, 0}, -{ 0x893C, 0xD0DF, WORD_LEN, 0}, -{ 0x893E, 0xA506, WORD_LEN, 0}, -{ 0x8940, 0xD0DF, WORD_LEN, 0}, -{ 0x8942, 0xA509, WORD_LEN, 0}, -{ 0x8944, 0xD0D8, WORD_LEN, 0}, -{ 0x8946, 0xA0C0, WORD_LEN, 0}, -{ 0x8948, 0xD0DE, WORD_LEN, 0}, -{ 0x894A, 0x802E, WORD_LEN, 0}, -{ 0x894C, 0x9117, WORD_LEN, 0}, -{ 0x894E, 0x0171, WORD_LEN, 0}, -{ 0x8950, 0x06E4, WORD_LEN, 0}, -{ 0x8952, 0xB10E, WORD_LEN, 0}, -{ 0x8954, 0xC0F1, WORD_LEN, 0}, -{ 0x8956, 0xD0D3, WORD_LEN, 0}, -{ 0x8958, 0x8806, WORD_LEN, 0}, -{ 0x895A, 0x080F, WORD_LEN, 0}, -{ 0x895C, 0x0051, WORD_LEN, 0}, -{ 0x895E, 0xD0D2, WORD_LEN, 0}, -{ 0x8960, 0x8000, WORD_LEN, 0}, -{ 0x8962, 0x8008, WORD_LEN, 0}, -{ 0x8964, 0x7840, WORD_LEN, 0}, -{ 0x8966, 0x0A1E, WORD_LEN, 0}, -{ 0x8968, 0x0104, WORD_LEN, 0}, -{ 0x896A, 0xC0D1, WORD_LEN, 0}, -{ 0x896C, 0x7EE0, WORD_LEN, 0}, -{ 0x896E, 0x78E0, WORD_LEN, 0}, -{ 0x8970, 0xC0F1, WORD_LEN, 0}, -{ 0x8972, 0x08D6, WORD_LEN, 0}, -{ 0x8974, 0x06C4, WORD_LEN, 0}, -{ 0x8976, 0xD7CC, WORD_LEN, 0}, -{ 0x8978, 0x8700, WORD_LEN, 0}, -{ 0x897A, 0x8009, WORD_LEN, 0}, -{ 0x897C, 0x7840, WORD_LEN, 0}, -{ 0x897E, 0xE080, WORD_LEN, 0}, -{ 0x8980, 0x0276, WORD_LEN, 0}, -{ 0x8982, 0x0002, WORD_LEN, 0}, -{ 0x8984, 0xD5C7, WORD_LEN, 0}, -{ 0x8986, 0xD6D0, WORD_LEN, 0}, -{ 0x8988, 0x1530, WORD_LEN, 0}, -{ 0x898A, 0x1081, WORD_LEN, 0}, -{ 0x898C, 0x1531, WORD_LEN, 0}, -{ 0x898E, 0x1080, WORD_LEN, 0}, -{ 0x8990, 0xB908, WORD_LEN, 0}, -{ 0x8992, 0x7905, WORD_LEN, 0}, -{ 0x8994, 0x2941, WORD_LEN, 0}, -{ 0x8996, 0x0200, WORD_LEN, 0}, -{ 0x8998, 0x1D32, WORD_LEN, 0}, -{ 0x899A, 0x1002, WORD_LEN, 0}, -{ 0x899C, 0x1D33, WORD_LEN, 0}, -{ 0x899E, 0x1042, WORD_LEN, 0}, -{ 0x89A0, 0x962D, WORD_LEN, 0}, -{ 0x89A2, 0x2540, WORD_LEN, 0}, -{ 0x89A4, 0x15D1, WORD_LEN, 0}, -{ 0x89A6, 0x2941, WORD_LEN, 0}, -{ 0x89A8, 0x0200, WORD_LEN, 0}, -{ 0x89AA, 0x1D30, WORD_LEN, 0}, -{ 0x89AC, 0x1002, WORD_LEN, 0}, -{ 0x89AE, 0x8D06, WORD_LEN, 0}, -{ 0x89B0, 0x2540, WORD_LEN, 0}, -{ 0x89B2, 0x1610, WORD_LEN, 0}, -{ 0x89B4, 0x1D31, WORD_LEN, 0}, -{ 0x89B6, 0x1042, WORD_LEN, 0}, -{ 0x89B8, 0x081B, WORD_LEN, 0}, -{ 0x89BA, 0x0051, WORD_LEN, 0}, -{ 0x89BC, 0x8700, WORD_LEN, 0}, -{ 0x89BE, 0x8008, WORD_LEN, 0}, -{ 0x89C0, 0x7840, WORD_LEN, 0}, -{ 0x89C2, 0xD900, WORD_LEN, 0}, -{ 0x89C4, 0x2941, WORD_LEN, 0}, -{ 0x89C6, 0x0200, WORD_LEN, 0}, -{ 0x89C8, 0xAD00, WORD_LEN, 0}, -{ 0x89CA, 0xAD21, WORD_LEN, 0}, -{ 0x89CC, 0xD801, WORD_LEN, 0}, -{ 0x89CE, 0x1D4D, WORD_LEN, 0}, -{ 0x89D0, 0x1002, WORD_LEN, 0}, -{ 0x89D2, 0x154D, WORD_LEN, 0}, -{ 0x89D4, 0x1080, WORD_LEN, 0}, -{ 0x89D6, 0xB861, WORD_LEN, 0}, -{ 0x89D8, 0xE085, WORD_LEN, 0}, -{ 0x89DA, 0x0218, WORD_LEN, 0}, -{ 0x89DC, 0x000D, WORD_LEN, 0}, -{ 0x89DE, 0x2740, WORD_LEN, 0}, -{ 0x89E0, 0x7381, WORD_LEN, 0}, -{ 0x89E2, 0x2132, WORD_LEN, 0}, -{ 0x89E4, 0x0000, WORD_LEN, 0}, -{ 0x89E6, 0x7914, WORD_LEN, 0}, -{ 0x89E8, 0x7900, WORD_LEN, 0}, -{ 0x89EA, 0x0323, WORD_LEN, 0}, -{ 0x89EC, 0x67BB, WORD_LEN, 0}, -{ 0x89EE, 0xD62E, WORD_LEN, 0}, -{ 0x89F0, 0x8D11, WORD_LEN, 0}, -{ 0x89F2, 0xD1B6, WORD_LEN, 0}, -{ 0x89F4, 0x8924, WORD_LEN, 0}, -{ 0x89F6, 0x2032, WORD_LEN, 0}, -{ 0x89F8, 0x2000, WORD_LEN, 0}, -{ 0x89FA, 0xDE02, WORD_LEN, 0}, -{ 0x89FC, 0x082B, WORD_LEN, 0}, -{ 0x89FE, 0x0040, WORD_LEN, 0}, -{ 0x8A00, 0x8D20, WORD_LEN, 0}, -{ 0x8A02, 0x8D41, WORD_LEN, 0}, -{ 0x8A04, 0xB908, WORD_LEN, 0}, -{ 0x8A06, 0x7945, WORD_LEN, 0}, -{ 0x8A08, 0xB983, WORD_LEN, 0}, -{ 0x8A0A, 0x2941, WORD_LEN, 0}, -{ 0x8A0C, 0x0202, WORD_LEN, 0}, -{ 0x8A0E, 0xAD40, WORD_LEN, 0}, -{ 0x8A10, 0xAD21, WORD_LEN, 0}, -{ 0x8A12, 0xD1AF, WORD_LEN, 0}, -{ 0x8A14, 0x8120, WORD_LEN, 0}, -{ 0x8A16, 0x8121, WORD_LEN, 0}, -{ 0x8A18, 0x7940, WORD_LEN, 0}, -{ 0x8A1A, 0x8D06, WORD_LEN, 0}, -{ 0x8A1C, 0xE001, WORD_LEN, 0}, -{ 0x8A1E, 0xAD06, WORD_LEN, 0}, -{ 0x8A20, 0x1D4D, WORD_LEN, 0}, -{ 0x8A22, 0x1382, WORD_LEN, 0}, -{ 0x8A24, 0xF0E9, WORD_LEN, 0}, -{ 0x8A26, 0x8D06, WORD_LEN, 0}, -{ 0x8A28, 0x1D4D, WORD_LEN, 0}, -{ 0x8A2A, 0x1382, WORD_LEN, 0}, -{ 0x8A2C, 0xE001, WORD_LEN, 0}, -{ 0x8A2E, 0xAD06, WORD_LEN, 0}, -{ 0x8A30, 0x8D00, WORD_LEN, 0}, -{ 0x8A32, 0x8D21, WORD_LEN, 0}, -{ 0x8A34, 0xB808, WORD_LEN, 0}, -{ 0x8A36, 0x7825, WORD_LEN, 0}, -{ 0x8A38, 0xB885, WORD_LEN, 0}, -{ 0x8A3A, 0x2841, WORD_LEN, 0}, -{ 0x8A3C, 0x0201, WORD_LEN, 0}, -{ 0x8A3E, 0xAD20, WORD_LEN, 0}, -{ 0x8A40, 0xAD01, WORD_LEN, 0}, -{ 0x8A42, 0x8D31, WORD_LEN, 0}, -{ 0x8A44, 0xF01A, WORD_LEN, 0}, -{ 0x8A46, 0x8D31, WORD_LEN, 0}, -{ 0x8A48, 0x8D12, WORD_LEN, 0}, -{ 0x8A4A, 0x8D46, WORD_LEN, 0}, -{ 0x8A4C, 0x7822, WORD_LEN, 0}, -{ 0x8A4E, 0x0863, WORD_LEN, 0}, -{ 0x8A50, 0x0082, WORD_LEN, 0}, -{ 0x8A52, 0x1532, WORD_LEN, 0}, -{ 0x8A54, 0x1080, WORD_LEN, 0}, -{ 0x8A56, 0x1533, WORD_LEN, 0}, -{ 0x8A58, 0x1081, WORD_LEN, 0}, -{ 0x8A5A, 0x1531, WORD_LEN, 0}, -{ 0x8A5C, 0x1082, WORD_LEN, 0}, -{ 0x8A5E, 0xB808, WORD_LEN, 0}, -{ 0x8A60, 0x7825, WORD_LEN, 0}, -{ 0x8A62, 0x1530, WORD_LEN, 0}, -{ 0x8A64, 0x1081, WORD_LEN, 0}, -{ 0x8A66, 0xB908, WORD_LEN, 0}, -{ 0x8A68, 0x7945, WORD_LEN, 0}, -{ 0x8A6A, 0xD29A, WORD_LEN, 0}, -{ 0x8A6C, 0x0992, WORD_LEN, 0}, -{ 0x8A6E, 0x0020, WORD_LEN, 0}, -{ 0x8A70, 0x8A40, WORD_LEN, 0}, -{ 0x8A72, 0x8D31, WORD_LEN, 0}, -{ 0x8A74, 0x081F, WORD_LEN, 0}, -{ 0x8A76, 0x0051, WORD_LEN, 0}, -{ 0x8A78, 0x8D06, WORD_LEN, 0}, -{ 0x8A7A, 0x6038, WORD_LEN, 0}, -{ 0x8A7C, 0xD194, WORD_LEN, 0}, -{ 0x8A7E, 0x8120, WORD_LEN, 0}, -{ 0x8A80, 0x8121, WORD_LEN, 0}, -{ 0x8A82, 0x7960, WORD_LEN, 0}, -{ 0x8A84, 0x2132, WORD_LEN, 0}, -{ 0x8A86, 0x2000, WORD_LEN, 0}, -{ 0x8A88, 0x8D06, WORD_LEN, 0}, -{ 0x8A8A, 0xE001, WORD_LEN, 0}, -{ 0x8A8C, 0xAD06, WORD_LEN, 0}, -{ 0x8A8E, 0xD806, WORD_LEN, 0}, -{ 0x8A90, 0xF0B1, WORD_LEN, 0}, -{ 0x8A92, 0xE88F, WORD_LEN, 0}, -{ 0x8A94, 0x8D66, WORD_LEN, 0}, -{ 0x8A96, 0x633B, WORD_LEN, 0}, -{ 0x8A98, 0x63BB, WORD_LEN, 0}, -{ 0x8A9A, 0xD08D, WORD_LEN, 0}, -{ 0x8A9C, 0x8000, WORD_LEN, 0}, -{ 0x8A9E, 0x8021, WORD_LEN, 0}, -{ 0x8AA0, 0x7960, WORD_LEN, 0}, -{ 0x8AA2, 0x8B17, WORD_LEN, 0}, -{ 0x8AA4, 0x8D06, WORD_LEN, 0}, -{ 0x8AA6, 0xE001, WORD_LEN, 0}, -{ 0x8AA8, 0xAD06, WORD_LEN, 0}, -{ 0x8AAA, 0xD803, WORD_LEN, 0}, -{ 0x8AAC, 0xF0A3, WORD_LEN, 0}, -{ 0x8AAE, 0x2032, WORD_LEN, 0}, -{ 0x8AB0, 0x2040, WORD_LEN, 0}, -{ 0x8AB2, 0xAD07, WORD_LEN, 0}, -{ 0x8AB4, 0xD804, WORD_LEN, 0}, -{ 0x8AB6, 0xF09F, WORD_LEN, 0}, -{ 0x8AB8, 0x1532, WORD_LEN, 0}, -{ 0x8ABA, 0x1080, WORD_LEN, 0}, -{ 0x8ABC, 0x1533, WORD_LEN, 0}, -{ 0x8ABE, 0x1081, WORD_LEN, 0}, -{ 0x8AC0, 0x1531, WORD_LEN, 0}, -{ 0x8AC2, 0x1082, WORD_LEN, 0}, -{ 0x8AC4, 0xB808, WORD_LEN, 0}, -{ 0x8AC6, 0x7825, WORD_LEN, 0}, -{ 0x8AC8, 0x1530, WORD_LEN, 0}, -{ 0x8ACA, 0x1081, WORD_LEN, 0}, -{ 0x8ACC, 0xB908, WORD_LEN, 0}, -{ 0x8ACE, 0x7945, WORD_LEN, 0}, -{ 0x8AD0, 0xD280, WORD_LEN, 0}, -{ 0x8AD2, 0x092E, WORD_LEN, 0}, -{ 0x8AD4, 0x0020, WORD_LEN, 0}, -{ 0x8AD6, 0x8A41, WORD_LEN, 0}, -{ 0x8AD8, 0x8D51, WORD_LEN, 0}, -{ 0x8ADA, 0x8D32, WORD_LEN, 0}, -{ 0x8ADC, 0x8DC6, WORD_LEN, 0}, -{ 0x8ADE, 0x7942, WORD_LEN, 0}, -{ 0x8AE0, 0x62DB, WORD_LEN, 0}, -{ 0x8AE2, 0x091F, WORD_LEN, 0}, -{ 0x8AE4, 0x03A2, WORD_LEN, 0}, -{ 0x8AE6, 0x63BB, WORD_LEN, 0}, -{ 0x8AE8, 0xE88B, WORD_LEN, 0}, -{ 0x8AEA, 0x8D00, WORD_LEN, 0}, -{ 0x8AEC, 0x8D21, WORD_LEN, 0}, -{ 0x8AEE, 0xB808, WORD_LEN, 0}, -{ 0x8AF0, 0x7825, WORD_LEN, 0}, -{ 0x8AF2, 0xB885, WORD_LEN, 0}, -{ 0x8AF4, 0x2841, WORD_LEN, 0}, -{ 0x8AF6, 0x0201, WORD_LEN, 0}, -{ 0x8AF8, 0xAD20, WORD_LEN, 0}, -{ 0x8AFA, 0xAD01, WORD_LEN, 0}, -{ 0x8AFC, 0xF1CF, WORD_LEN, 0}, -{ 0x8AFE, 0xDF04, WORD_LEN, 0}, -{ 0x8B00, 0x092B, WORD_LEN, 0}, -{ 0x8B02, 0x03A3, WORD_LEN, 0}, -{ 0x8B04, 0x1D4D, WORD_LEN, 0}, -{ 0x8B06, 0x13C2, WORD_LEN, 0}, -{ 0x8B08, 0x1530, WORD_LEN, 0}, -{ 0x8B0A, 0x108E, WORD_LEN, 0}, -{ 0x8B0C, 0x1531, WORD_LEN, 0}, -{ 0x8B0E, 0x1081, WORD_LEN, 0}, -{ 0x8B10, 0x1533, WORD_LEN, 0}, -{ 0x8B12, 0x108F, WORD_LEN, 0}, -{ 0x8B14, 0xBE08, WORD_LEN, 0}, -{ 0x8B16, 0x7E25, WORD_LEN, 0}, -{ 0x8B18, 0x1532, WORD_LEN, 0}, -{ 0x8B1A, 0x1081, WORD_LEN, 0}, -{ 0x8B1C, 0xB908, WORD_LEN, 0}, -{ 0x8B1E, 0x79E5, WORD_LEN, 0}, -{ 0x8B20, 0x0907, WORD_LEN, 0}, -{ 0x8B22, 0x0382, WORD_LEN, 0}, -{ 0x8B24, 0xE883, WORD_LEN, 0}, -{ 0x8B26, 0x8B16, WORD_LEN, 0}, -{ 0x8B28, 0xF002, WORD_LEN, 0}, -{ 0x8B2A, 0x8B15, WORD_LEN, 0}, -{ 0x8B2C, 0x8D22, WORD_LEN, 0}, -{ 0x8B2E, 0xAD07, WORD_LEN, 0}, -{ 0x8B30, 0x8D03, WORD_LEN, 0}, -{ 0x8B32, 0xD367, WORD_LEN, 0}, -{ 0x8B34, 0xB908, WORD_LEN, 0}, -{ 0x8B36, 0x8DC1, WORD_LEN, 0}, -{ 0x8B38, 0x7905, WORD_LEN, 0}, -{ 0x8B3A, 0x8D00, WORD_LEN, 0}, -{ 0x8B3C, 0xB808, WORD_LEN, 0}, -{ 0x8B3E, 0x78C5, WORD_LEN, 0}, -{ 0x8B40, 0x0921, WORD_LEN, 0}, -{ 0x8B42, 0x011E, WORD_LEN, 0}, -{ 0x8B44, 0xB883, WORD_LEN, 0}, -{ 0x8B46, 0x2841, WORD_LEN, 0}, -{ 0x8B48, 0x0201, WORD_LEN, 0}, -{ 0x8B4A, 0xAD20, WORD_LEN, 0}, -{ 0x8B4C, 0x8320, WORD_LEN, 0}, -{ 0x8B4E, 0xAD01, WORD_LEN, 0}, -{ 0x8B50, 0x8121, WORD_LEN, 0}, -{ 0x8B52, 0x7960, WORD_LEN, 0}, -{ 0x8B54, 0x2032, WORD_LEN, 0}, -{ 0x8B56, 0x2080, WORD_LEN, 0}, -{ 0x8B58, 0x8D06, WORD_LEN, 0}, -{ 0x8B5A, 0xE001, WORD_LEN, 0}, -{ 0x8B5C, 0xAD06, WORD_LEN, 0}, -{ 0x8B5E, 0xF04D, WORD_LEN, 0}, -{ 0x8B60, 0x8D00, WORD_LEN, 0}, -{ 0x8B62, 0x8D21, WORD_LEN, 0}, -{ 0x8B64, 0xB808, WORD_LEN, 0}, -{ 0x8B66, 0x7825, WORD_LEN, 0}, -{ 0x8B68, 0xB886, WORD_LEN, 0}, -{ 0x8B6A, 0x2841, WORD_LEN, 0}, -{ 0x8B6C, 0x0201, WORD_LEN, 0}, -{ 0x8B6E, 0xAD20, WORD_LEN, 0}, -{ 0x8B70, 0xAD01, WORD_LEN, 0}, -{ 0x8B72, 0xD057, WORD_LEN, 0}, -{ 0x8B74, 0x8000, WORD_LEN, 0}, -{ 0x8B76, 0x8021, WORD_LEN, 0}, -{ 0x8B78, 0x7960, WORD_LEN, 0}, -{ 0x8B7A, 0x8D07, WORD_LEN, 0}, -{ 0x8B7C, 0x1545, WORD_LEN, 0}, -{ 0x8B7E, 0x1080, WORD_LEN, 0}, -{ 0x8B80, 0x1546, WORD_LEN, 0}, -{ 0x8B82, 0x1081, WORD_LEN, 0}, -{ 0x8B84, 0xB808, WORD_LEN, 0}, -{ 0x8B86, 0x7825, WORD_LEN, 0}, -{ 0x8B88, 0x085D, WORD_LEN, 0}, -{ 0x8B8A, 0x005E, WORD_LEN, 0}, -{ 0x8B8C, 0x8D06, WORD_LEN, 0}, -{ 0x8B8E, 0xE001, WORD_LEN, 0}, -{ 0x8B90, 0xAD06, WORD_LEN, 0}, -{ 0x8B92, 0xD805, WORD_LEN, 0}, -{ 0x8B94, 0xF02F, WORD_LEN, 0}, -{ 0x8B96, 0x1530, WORD_LEN, 0}, -{ 0x8B98, 0x1082, WORD_LEN, 0}, -{ 0x8B9A, 0x1531, WORD_LEN, 0}, -{ 0x8B9C, 0x1080, WORD_LEN, 0}, -{ 0x8B9E, 0xD14D, WORD_LEN, 0}, -{ 0x8BA0, 0xBA08, WORD_LEN, 0}, -{ 0x8BA2, 0x7A05, WORD_LEN, 0}, -{ 0x8BA4, 0x8903, WORD_LEN, 0}, -{ 0x8BA6, 0x080F, WORD_LEN, 0}, -{ 0x8BA8, 0x0083, WORD_LEN, 0}, -{ 0x8BAA, 0x8902, WORD_LEN, 0}, -{ 0x8BAC, 0x8E44, WORD_LEN, 0}, -{ 0x8BAE, 0x0839, WORD_LEN, 0}, -{ 0x8BB0, 0x0082, WORD_LEN, 0}, -{ 0x8BB2, 0x1545, WORD_LEN, 0}, -{ 0x8BB4, 0x1082, WORD_LEN, 0}, -{ 0x8BB6, 0x1546, WORD_LEN, 0}, -{ 0x8BB8, 0x1080, WORD_LEN, 0}, -{ 0x8BBA, 0xBA08, WORD_LEN, 0}, -{ 0x8BBC, 0x7A05, WORD_LEN, 0}, -{ 0x8BBE, 0x0A29, WORD_LEN, 0}, -{ 0x8BC0, 0x005E, WORD_LEN, 0}, -{ 0x8BC2, 0x8D00, WORD_LEN, 0}, -{ 0x8BC4, 0x8D21, WORD_LEN, 0}, -{ 0x8BC6, 0xB808, WORD_LEN, 0}, -{ 0x8BC8, 0x7825, WORD_LEN, 0}, -{ 0x8BCA, 0xB88D, WORD_LEN, 0}, -{ 0x8BCC, 0x2841, WORD_LEN, 0}, -{ 0x8BCE, 0x0201, WORD_LEN, 0}, -{ 0x8BD0, 0xAD20, WORD_LEN, 0}, -{ 0x8BD2, 0xAD01, WORD_LEN, 0}, -{ 0x8BD4, 0x0A11, WORD_LEN, 0}, -{ 0x8BD6, 0x009E, WORD_LEN, 0}, -{ 0x8BD8, 0xD03D, WORD_LEN, 0}, -{ 0x8BDA, 0x8000, WORD_LEN, 0}, -{ 0x8BDC, 0x8021, WORD_LEN, 0}, -{ 0x8BDE, 0x7960, WORD_LEN, 0}, -{ 0x8BE0, 0x1550, WORD_LEN, 0}, -{ 0x8BE2, 0x1080, WORD_LEN, 0}, -{ 0x8BE4, 0xD800, WORD_LEN, 0}, -{ 0x8BE6, 0x09AA, WORD_LEN, 0}, -{ 0x8BE8, 0x0164, WORD_LEN, 0}, -{ 0x8BEA, 0x1D4D, WORD_LEN, 0}, -{ 0x8BEC, 0x1002, WORD_LEN, 0}, -{ 0x8BEE, 0xF005, WORD_LEN, 0}, -{ 0x8BF0, 0xD800, WORD_LEN, 0}, -{ 0x8BF2, 0x1D4D, WORD_LEN, 0}, -{ 0x8BF4, 0x1002, WORD_LEN, 0}, -{ 0x8BF6, 0x06B1, WORD_LEN, 0}, -{ 0x8BF8, 0x0684, WORD_LEN, 0}, -{ 0x8BFA, 0x78E0, WORD_LEN, 0}, -{ 0x8BFC, 0xC0F1, WORD_LEN, 0}, -{ 0x8BFE, 0x0E4E, WORD_LEN, 0}, -{ 0x8C00, 0x06A4, WORD_LEN, 0}, -{ 0x8C02, 0x7308, WORD_LEN, 0}, -{ 0x8C04, 0x0919, WORD_LEN, 0}, -{ 0x8C06, 0x0023, WORD_LEN, 0}, -{ 0x8C08, 0x721A, WORD_LEN, 0}, -{ 0x8C0A, 0xD026, WORD_LEN, 0}, -{ 0x8C0C, 0x1030, WORD_LEN, 0}, -{ 0x8C0E, 0x0082, WORD_LEN, 0}, -{ 0x8C10, 0x1031, WORD_LEN, 0}, -{ 0x8C12, 0x0081, WORD_LEN, 0}, -{ 0x8C14, 0xBA08, WORD_LEN, 0}, -{ 0x8C16, 0x7A25, WORD_LEN, 0}, -{ 0x8C18, 0xDD00, WORD_LEN, 0}, -{ 0x8C1A, 0xF005, WORD_LEN, 0}, -{ 0x8C1C, 0xDD01, WORD_LEN, 0}, -{ 0x8C1E, 0x7268, WORD_LEN, 0}, -{ 0x8C20, 0x7328, WORD_LEN, 0}, -{ 0x8C22, 0x2302, WORD_LEN, 0}, -{ 0x8C24, 0x0080, WORD_LEN, 0}, -{ 0x8C26, 0x2885, WORD_LEN, 0}, -{ 0x8C28, 0x0901, WORD_LEN, 0}, -{ 0x8C2A, 0x702F, WORD_LEN, 0}, -{ 0x8C2C, 0x0EFA, WORD_LEN, 0}, -{ 0x8C2E, 0x06A4, WORD_LEN, 0}, -{ 0x8C30, 0x7168, WORD_LEN, 0}, -{ 0x8C32, 0xD31C, WORD_LEN, 0}, -{ 0x8C34, 0x8BC6, WORD_LEN, 0}, -{ 0x8C36, 0x8B31, WORD_LEN, 0}, -{ 0x8C38, 0x780F, WORD_LEN, 0}, -{ 0x8C3A, 0xD226, WORD_LEN, 0}, -{ 0x8C3C, 0x663E, WORD_LEN, 0}, -{ 0x8C3E, 0xD123, WORD_LEN, 0}, -{ 0x8C40, 0xBE62, WORD_LEN, 0}, -{ 0x8C42, 0x7ECF, WORD_LEN, 0}, -{ 0x8C44, 0x89E4, WORD_LEN, 0}, -{ 0x8C46, 0x2214, WORD_LEN, 0}, -{ 0x8C48, 0x0381, WORD_LEN, 0}, -{ 0x8C4A, 0xED07, WORD_LEN, 0}, -{ 0x8C4C, 0x2840, WORD_LEN, 0}, -{ 0x8C4E, 0x020E, WORD_LEN, 0}, -{ 0x8C50, 0x7EE5, WORD_LEN, 0}, -{ 0x8C52, 0xB1CC, WORD_LEN, 0}, -{ 0x8C54, 0xF007, WORD_LEN, 0}, -{ 0x8C56, 0x7E12, WORD_LEN, 0}, -{ 0x8C58, 0xE601, WORD_LEN, 0}, -{ 0x8C5A, 0x7ECF, WORD_LEN, 0}, -{ 0x8C5C, 0xBE08, WORD_LEN, 0}, -{ 0x8C5E, 0x7FC5, WORD_LEN, 0}, -{ 0x8C60, 0xB1EC, WORD_LEN, 0}, -{ 0x8C62, 0x080D, WORD_LEN, 0}, -{ 0x8C64, 0x2003, WORD_LEN, 0}, -{ 0x8C66, 0xED0D, WORD_LEN, 0}, -{ 0x8C68, 0xD800, WORD_LEN, 0}, -{ 0x8C6A, 0xF01A, WORD_LEN, 0}, -{ 0x8C6C, 0x134D, WORD_LEN, 0}, -{ 0x8C6E, 0x0080, WORD_LEN, 0}, -{ 0x8C70, 0x080B, WORD_LEN, 0}, -{ 0x8C72, 0x0190, WORD_LEN, 0}, -{ 0x8C74, 0x8A0E, WORD_LEN, 0}, -{ 0x8C76, 0x080B, WORD_LEN, 0}, -{ 0x8C78, 0x0291, WORD_LEN, 0}, -{ 0x8C7A, 0xD801, WORD_LEN, 0}, -{ 0x8C7C, 0xF010, WORD_LEN, 0}, -{ 0x8C7E, 0x1330, WORD_LEN, 0}, -{ 0x8C80, 0x0081, WORD_LEN, 0}, -{ 0x8C82, 0x1331, WORD_LEN, 0}, -{ 0x8C84, 0x008D, WORD_LEN, 0}, -{ 0x8C86, 0xD802, WORD_LEN, 0}, -{ 0x8C88, 0xB908, WORD_LEN, 0}, -{ 0x8C8A, 0x79A5, WORD_LEN, 0}, -{ 0x8C8C, 0xB22A, WORD_LEN, 0}, -{ 0x8C8E, 0x1332, WORD_LEN, 0}, -{ 0x8C90, 0x0081, WORD_LEN, 0}, -{ 0x8C92, 0x1333, WORD_LEN, 0}, -{ 0x8C94, 0x008D, WORD_LEN, 0}, -{ 0x8C96, 0xB908, WORD_LEN, 0}, -{ 0x8C98, 0x79A5, WORD_LEN, 0}, -{ 0x8C9A, 0xB22B, WORD_LEN, 0}, -{ 0x8C9C, 0x0611, WORD_LEN, 0}, -{ 0x8C9E, 0x0684, WORD_LEN, 0}, -{ 0x8CA0, 0xFF80, WORD_LEN, 0}, -{ 0x8CA2, 0x0290, WORD_LEN, 0}, -{ 0x8CA4, 0x8000, WORD_LEN, 0}, -{ 0x8CA6, 0x008C, WORD_LEN, 0}, -{ 0x8CA8, 0x0000, WORD_LEN, 0}, -{ 0x8CAA, 0xF3BC, WORD_LEN, 0}, -{ 0x8CAC, 0xFF80, WORD_LEN, 0}, -{ 0x8CAE, 0x1120, WORD_LEN, 0}, -{ 0x8CB0, 0xFF80, WORD_LEN, 0}, -{ 0x8CB2, 0x08EC, WORD_LEN, 0}, -{ 0x8CB4, 0xFF80, WORD_LEN, 0}, -{ 0x8CB6, 0x0954, WORD_LEN, 0}, -{ 0x8CB8, 0xFF80, WORD_LEN, 0}, -{ 0x8CBA, 0x0970, WORD_LEN, 0}, -{ 0x8CBC, 0xFF80, WORD_LEN, 0}, -{ 0x8CBE, 0x0CD4, WORD_LEN, 0}, -{ 0x8CC0, 0xFF80, WORD_LEN, 0}, -{ 0x8CC2, 0x06C8, WORD_LEN, 0}, -{ 0x8CC4, 0xFF80, WORD_LEN, 0}, -{ 0x8CC6, 0x050C, WORD_LEN, 0}, -{ 0x8CC8, 0xFF80, WORD_LEN, 0}, -{ 0x8CCA, 0x0158, WORD_LEN, 0}, -{ 0x8CCC, 0x8000, WORD_LEN, 0}, -{ 0x8CCE, 0x0008, WORD_LEN, 0}, -{ 0x8CD0, 0xFF80, WORD_LEN, 0}, -{ 0x8CD2, 0x10C8, WORD_LEN, 0}, -{ 0x8CD4, 0xC0F1, WORD_LEN, 0}, -{ 0x8CD6, 0x0D7E, WORD_LEN, 0}, -{ 0x8CD8, 0x0684, WORD_LEN, 0}, -{ 0x8CDA, 0x17C8, WORD_LEN, 0}, -{ 0x8CDC, 0xF00D, WORD_LEN, 0}, -{ 0x8CDE, 0x1545, WORD_LEN, 0}, -{ 0x8CE0, 0x1080, WORD_LEN, 0}, -{ 0x8CE2, 0x1546, WORD_LEN, 0}, -{ 0x8CE4, 0x1081, WORD_LEN, 0}, -{ 0x8CE6, 0xB808, WORD_LEN, 0}, -{ 0x8CE8, 0x7825, WORD_LEN, 0}, -{ 0x8CEA, 0xB8E0, WORD_LEN, 0}, -{ 0x8CEC, 0xDE00, WORD_LEN, 0}, -{ 0x8CEE, 0xF208, WORD_LEN, 0}, -{ 0x8CF0, 0x8D00, WORD_LEN, 0}, -{ 0x8CF2, 0x8D21, WORD_LEN, 0}, -{ 0x8CF4, 0xB808, WORD_LEN, 0}, -{ 0x8CF6, 0x7825, WORD_LEN, 0}, -{ 0x8CF8, 0x2044, WORD_LEN, 0}, -{ 0x8CFA, 0x020E, WORD_LEN, 0}, -{ 0x8CFC, 0x8D00, WORD_LEN, 0}, -{ 0x8CFE, 0x8D21, WORD_LEN, 0}, -{ 0x8D00, 0xB808, WORD_LEN, 0}, -{ 0x8D02, 0x7825, WORD_LEN, 0}, -{ 0x8D04, 0x082F, WORD_LEN, 0}, -{ 0x8D06, 0x00DE, WORD_LEN, 0}, -{ 0x8D08, 0x7108, WORD_LEN, 0}, -{ 0x8D0A, 0x2186, WORD_LEN, 0}, -{ 0x8D0C, 0x0FFE, WORD_LEN, 0}, -{ 0x8D0E, 0x262F, WORD_LEN, 0}, -{ 0x8D10, 0xF04A, WORD_LEN, 0}, -{ 0x8D12, 0xF211, WORD_LEN, 0}, -{ 0x8D14, 0x17BC, WORD_LEN, 0}, -{ 0x8D16, 0xF002, WORD_LEN, 0}, -{ 0x8D18, 0x8A25, WORD_LEN, 0}, -{ 0x8D1A, 0xE906, WORD_LEN, 0}, -{ 0x8D1C, 0xB961, WORD_LEN, 0}, -{ 0x8D1E, 0xAA25, WORD_LEN, 0}, -{ 0x8D20, 0xD806, WORD_LEN, 0}, -{ 0x8D22, 0xF01E, WORD_LEN, 0}, -{ 0x8D24, 0x8A24, WORD_LEN, 0}, -{ 0x8D26, 0xB8A3, WORD_LEN, 0}, -{ 0x8D28, 0xAA25, WORD_LEN, 0}, -{ 0x8D2A, 0x2841, WORD_LEN, 0}, -{ 0x8D2C, 0x0201, WORD_LEN, 0}, -{ 0x8D2E, 0xAD20, WORD_LEN, 0}, -{ 0x8D30, 0xAD01, WORD_LEN, 0}, -{ 0x8D32, 0x0D56, WORD_LEN, 0}, -{ 0x8D34, 0x0144, WORD_LEN, 0}, -{ 0x8D36, 0x1545, WORD_LEN, 0}, -{ 0x8D38, 0x1081, WORD_LEN, 0}, -{ 0x8D3A, 0x1546, WORD_LEN, 0}, -{ 0x8D3C, 0x1082, WORD_LEN, 0}, -{ 0x8D3E, 0xB908, WORD_LEN, 0}, -{ 0x8D40, 0x7945, WORD_LEN, 0}, -{ 0x8D42, 0xB9E0, WORD_LEN, 0}, -{ 0x8D44, 0x26CC, WORD_LEN, 0}, -{ 0x8D46, 0x9022, WORD_LEN, 0}, -{ 0x8D48, 0xF20A, WORD_LEN, 0}, -{ 0x8D4A, 0x8D20, WORD_LEN, 0}, -{ 0x8D4C, 0x8D41, WORD_LEN, 0}, -{ 0x8D4E, 0xB908, WORD_LEN, 0}, -{ 0x8D50, 0x7945, WORD_LEN, 0}, -{ 0x8D52, 0xB983, WORD_LEN, 0}, -{ 0x8D54, 0x2941, WORD_LEN, 0}, -{ 0x8D56, 0x0202, WORD_LEN, 0}, -{ 0x8D58, 0xAD40, WORD_LEN, 0}, -{ 0x8D5A, 0xAD21, WORD_LEN, 0}, -{ 0x8D5C, 0x0561, WORD_LEN, 0}, -{ 0x8D5E, 0x0684, WORD_LEN, 0}, -{ 0x8D60, 0xC0F1, WORD_LEN, 0}, -{ 0x8D62, 0x0CEE, WORD_LEN, 0}, -{ 0x8D64, 0x06A4, WORD_LEN, 0}, -{ 0x8D66, 0x7098, WORD_LEN, 0}, -{ 0x8D68, 0xD284, WORD_LEN, 0}, -{ 0x8D6A, 0x1206, WORD_LEN, 0}, -{ 0x8D6C, 0x0086, WORD_LEN, 0}, -{ 0x8D6E, 0x2240, WORD_LEN, 0}, -{ 0x8D70, 0x0205, WORD_LEN, 0}, -{ 0x8D72, 0x264C, WORD_LEN, 0}, -{ 0x8D74, 0x8000, WORD_LEN, 0}, -{ 0x8D76, 0x20CA, WORD_LEN, 0}, -{ 0x8D78, 0x0101, WORD_LEN, 0}, -{ 0x8D7A, 0xF237, WORD_LEN, 0}, -{ 0x8D7C, 0x8AA7, WORD_LEN, 0}, -{ 0x8D7E, 0x6D69, WORD_LEN, 0}, -{ 0x8D80, 0x7B6D, WORD_LEN, 0}, -{ 0x8D82, 0x0B3F, WORD_LEN, 0}, -{ 0x8D84, 0x0012, WORD_LEN, 0}, -{ 0x8D86, 0x7068, WORD_LEN, 0}, -{ 0x8D88, 0x780D, WORD_LEN, 0}, -{ 0x8D8A, 0x2040, WORD_LEN, 0}, -{ 0x8D8C, 0x007C, WORD_LEN, 0}, -{ 0x8D8E, 0x20A8, WORD_LEN, 0}, -{ 0x8D90, 0x0640, WORD_LEN, 0}, -{ 0x8D92, 0x71CF, WORD_LEN, 0}, -{ 0x8D94, 0xFF80, WORD_LEN, 0}, -{ 0x8D96, 0x0158, WORD_LEN, 0}, -{ 0x8D98, 0x8924, WORD_LEN, 0}, -{ 0x8D9A, 0x2532, WORD_LEN, 0}, -{ 0x8D9C, 0x00C0, WORD_LEN, 0}, -{ 0x8D9E, 0xBD61, WORD_LEN, 0}, -{ 0x8DA0, 0x0819, WORD_LEN, 0}, -{ 0x8DA2, 0x0063, WORD_LEN, 0}, -{ 0x8DA4, 0x7DAF, WORD_LEN, 0}, -{ 0x8DA6, 0x76CF, WORD_LEN, 0}, -{ 0x8DA8, 0xFF80, WORD_LEN, 0}, -{ 0x8DAA, 0x0290, WORD_LEN, 0}, -{ 0x8DAC, 0x8EF1, WORD_LEN, 0}, -{ 0x8DAE, 0x2640, WORD_LEN, 0}, -{ 0x8DB0, 0x1601, WORD_LEN, 0}, -{ 0x8DB2, 0x61E9, WORD_LEN, 0}, -{ 0x8DB4, 0x090F, WORD_LEN, 0}, -{ 0x8DB6, 0x0002, WORD_LEN, 0}, -{ 0x8DB8, 0xAAA7, WORD_LEN, 0}, -{ 0x8DBA, 0xBB61, WORD_LEN, 0}, -{ 0x8DBC, 0x7B6D, WORD_LEN, 0}, -{ 0x8DBE, 0x7088, WORD_LEN, 0}, -{ 0x8DC0, 0xF005, WORD_LEN, 0}, -{ 0x8DC2, 0x8E26, WORD_LEN, 0}, -{ 0x8DC4, 0xAAA7, WORD_LEN, 0}, -{ 0x8DC6, 0xB961, WORD_LEN, 0}, -{ 0x8DC8, 0xAE26, WORD_LEN, 0}, -{ 0x8DCA, 0x0B1F, WORD_LEN, 0}, -{ 0x8DCC, 0x0013, WORD_LEN, 0}, -{ 0x8DCE, 0x1A07, WORD_LEN, 0}, -{ 0x8DD0, 0x0182, WORD_LEN, 0}, -{ 0x8DD2, 0xD26B, WORD_LEN, 0}, -{ 0x8DD4, 0x8A20, WORD_LEN, 0}, -{ 0x8DD6, 0x8A61, WORD_LEN, 0}, -{ 0x8DD8, 0xB908, WORD_LEN, 0}, -{ 0x8DDA, 0x7965, WORD_LEN, 0}, -{ 0x8DDC, 0xB9A3, WORD_LEN, 0}, -{ 0x8DDE, 0x2941, WORD_LEN, 0}, -{ 0x8DE0, 0x020C, WORD_LEN, 0}, -{ 0x8DE2, 0xAA80, WORD_LEN, 0}, -{ 0x8DE4, 0xAA21, WORD_LEN, 0}, -{ 0x8DE6, 0x04D1, WORD_LEN, 0}, -{ 0x8DE8, 0x0684, WORD_LEN, 0}, -{ 0x8DEA, 0x78E0, WORD_LEN, 0}, -{ 0x8DEC, 0xC0F1, WORD_LEN, 0}, -{ 0x8DEE, 0xC5E1, WORD_LEN, 0}, -{ 0x8DF0, 0xD363, WORD_LEN, 0}, -{ 0x8DF2, 0x8B24, WORD_LEN, 0}, -{ 0x8DF4, 0x8B45, WORD_LEN, 0}, -{ 0x8DF6, 0xB908, WORD_LEN, 0}, -{ 0x8DF8, 0x7945, WORD_LEN, 0}, -{ 0x8DFA, 0xE188, WORD_LEN, 0}, -{ 0x8DFC, 0x21CC, WORD_LEN, 0}, -{ 0x8DFE, 0x8422, WORD_LEN, 0}, -{ 0x8E00, 0xF41F, WORD_LEN, 0}, -{ 0x8E02, 0x8B26, WORD_LEN, 0}, -{ 0x8E04, 0x093B, WORD_LEN, 0}, -{ 0x8E06, 0x0051, WORD_LEN, 0}, -{ 0x8E08, 0xD15C, WORD_LEN, 0}, -{ 0x8E0A, 0xD80A, WORD_LEN, 0}, -{ 0x8E0C, 0xA90E, WORD_LEN, 0}, -{ 0x8E0E, 0xD05D, WORD_LEN, 0}, -{ 0x8E10, 0x8804, WORD_LEN, 0}, -{ 0x8E12, 0x1330, WORD_LEN, 0}, -{ 0x8E14, 0x0082, WORD_LEN, 0}, -{ 0x8E16, 0x1331, WORD_LEN, 0}, -{ 0x8E18, 0x008D, WORD_LEN, 0}, -{ 0x8E1A, 0xBA08, WORD_LEN, 0}, -{ 0x8E1C, 0x7AA5, WORD_LEN, 0}, -{ 0x8E1E, 0xB148, WORD_LEN, 0}, -{ 0x8E20, 0x8952, WORD_LEN, 0}, -{ 0x8E22, 0xA90F, WORD_LEN, 0}, -{ 0x8E24, 0x0813, WORD_LEN, 0}, -{ 0x8E26, 0x00A2, WORD_LEN, 0}, -{ 0x8E28, 0x132C, WORD_LEN, 0}, -{ 0x8E2A, 0x0083, WORD_LEN, 0}, -{ 0x8E2C, 0xDA00, WORD_LEN, 0}, -{ 0x8E2E, 0xA953, WORD_LEN, 0}, -{ 0x8E30, 0x7862, WORD_LEN, 0}, -{ 0x8E32, 0x780F, WORD_LEN, 0}, -{ 0x8E34, 0xF005, WORD_LEN, 0}, -{ 0x8E36, 0xDA01, WORD_LEN, 0}, -{ 0x8E38, 0xA953, WORD_LEN, 0}, -{ 0x8E3A, 0x6078, WORD_LEN, 0}, -{ 0x8E3C, 0x780F, WORD_LEN, 0}, -{ 0x8E3E, 0x080E, WORD_LEN, 0}, -{ 0x8E40, 0x0000, WORD_LEN, 0}, -{ 0x8E42, 0x0485, WORD_LEN, 0}, -{ 0x8E44, 0x0684, WORD_LEN, 0}, -{ 0x8E46, 0x78E0, WORD_LEN, 0}, -{ 0x8E48, 0xC0F1, WORD_LEN, 0}, -{ 0x8E4A, 0x0BFE, WORD_LEN, 0}, -{ 0x8E4C, 0x0684, WORD_LEN, 0}, -{ 0x8E4E, 0xD64D, WORD_LEN, 0}, -{ 0x8E50, 0x7508, WORD_LEN, 0}, -{ 0x8E52, 0x8E01, WORD_LEN, 0}, -{ 0x8E54, 0xD14A, WORD_LEN, 0}, -{ 0x8E56, 0x2046, WORD_LEN, 0}, -{ 0x8E58, 0x00C0, WORD_LEN, 0}, -{ 0x8E5A, 0xAE01, WORD_LEN, 0}, -{ 0x8E5C, 0x1145, WORD_LEN, 0}, -{ 0x8E5E, 0x0080, WORD_LEN, 0}, -{ 0x8E60, 0x1146, WORD_LEN, 0}, -{ 0x8E62, 0x0082, WORD_LEN, 0}, -{ 0x8E64, 0xB808, WORD_LEN, 0}, -{ 0x8E66, 0x7845, WORD_LEN, 0}, -{ 0x8E68, 0x0817, WORD_LEN, 0}, -{ 0x8E6A, 0x001E, WORD_LEN, 0}, -{ 0x8E6C, 0x8900, WORD_LEN, 0}, -{ 0x8E6E, 0x8941, WORD_LEN, 0}, -{ 0x8E70, 0xB808, WORD_LEN, 0}, -{ 0x8E72, 0x7845, WORD_LEN, 0}, -{ 0x8E74, 0x080B, WORD_LEN, 0}, -{ 0x8E76, 0x00DE, WORD_LEN, 0}, -{ 0x8E78, 0x70A9, WORD_LEN, 0}, -{ 0x8E7A, 0xFFBA, WORD_LEN, 0}, -{ 0x8E7C, 0x7508, WORD_LEN, 0}, -{ 0x8E7E, 0x1604, WORD_LEN, 0}, -{ 0x8E80, 0x1090, WORD_LEN, 0}, -{ 0x8E82, 0x0D93, WORD_LEN, 0}, -{ 0x8E84, 0x1400, WORD_LEN, 0}, -{ 0x8E86, 0x8EEA, WORD_LEN, 0}, -{ 0x8E88, 0x8E0B, WORD_LEN, 0}, -{ 0x8E8A, 0x214A, WORD_LEN, 0}, -{ 0x8E8C, 0x2040, WORD_LEN, 0}, -{ 0x8E8E, 0x8E2D, WORD_LEN, 0}, -{ 0x8E90, 0xBF08, WORD_LEN, 0}, -{ 0x8E92, 0x7F05, WORD_LEN, 0}, -{ 0x8E94, 0x8E0C, WORD_LEN, 0}, -{ 0x8E96, 0xB808, WORD_LEN, 0}, -{ 0x8E98, 0x7825, WORD_LEN, 0}, -{ 0x8E9A, 0x7710, WORD_LEN, 0}, -{ 0x8E9C, 0x21C2, WORD_LEN, 0}, -{ 0x8E9E, 0x244C, WORD_LEN, 0}, -{ 0x8EA0, 0x081D, WORD_LEN, 0}, -{ 0x8EA2, 0x03E3, WORD_LEN, 0}, -{ 0x8EA4, 0xD9FF, WORD_LEN, 0}, -{ 0x8EA6, 0x2702, WORD_LEN, 0}, -{ 0x8EA8, 0x1002, WORD_LEN, 0}, -{ 0x8EAA, 0x2A05, WORD_LEN, 0}, -{ 0x8EAC, 0x037E, WORD_LEN, 0}, -{ 0x8EAE, 0x0C7A, WORD_LEN, 0}, -{ 0x8EB0, 0x06A4, WORD_LEN, 0}, -{ 0x8EB2, 0x702F, WORD_LEN, 0}, -{ 0x8EB4, 0x7810, WORD_LEN, 0}, -{ 0x8EB6, 0x7F02, WORD_LEN, 0}, -{ 0x8EB8, 0x7FF0, WORD_LEN, 0}, -{ 0x8EBA, 0xF00B, WORD_LEN, 0}, -{ 0x8EBC, 0x78E2, WORD_LEN, 0}, -{ 0x8EBE, 0x2805, WORD_LEN, 0}, -{ 0x8EC0, 0x037E, WORD_LEN, 0}, -{ 0x8EC2, 0x0C66, WORD_LEN, 0}, -{ 0x8EC4, 0x06A4, WORD_LEN, 0}, -{ 0x8EC6, 0x702F, WORD_LEN, 0}, -{ 0x8EC8, 0x7810, WORD_LEN, 0}, -{ 0x8ECA, 0x671F, WORD_LEN, 0}, -{ 0x8ECC, 0x7FF0, WORD_LEN, 0}, -{ 0x8ECE, 0x7FEF, WORD_LEN, 0}, -{ 0x8ED0, 0x8E08, WORD_LEN, 0}, -{ 0x8ED2, 0xBF06, WORD_LEN, 0}, -{ 0x8ED4, 0xD12C, WORD_LEN, 0}, -{ 0x8ED6, 0xB8C3, WORD_LEN, 0}, -{ 0x8ED8, 0x78E5, WORD_LEN, 0}, -{ 0x8EDA, 0xB88F, WORD_LEN, 0}, -{ 0x8EDC, 0x1908, WORD_LEN, 0}, -{ 0x8EDE, 0x0024, WORD_LEN, 0}, -{ 0x8EE0, 0x2841, WORD_LEN, 0}, -{ 0x8EE2, 0x0201, WORD_LEN, 0}, -{ 0x8EE4, 0x1E26, WORD_LEN, 0}, -{ 0x8EE6, 0x1042, WORD_LEN, 0}, -{ 0x8EE8, 0x0D15, WORD_LEN, 0}, -{ 0x8EEA, 0x1423, WORD_LEN, 0}, -{ 0x8EEC, 0x1E27, WORD_LEN, 0}, -{ 0x8EEE, 0x1002, WORD_LEN, 0}, -{ 0x8EF0, 0x214C, WORD_LEN, 0}, -{ 0x8EF2, 0xA000, WORD_LEN, 0}, -{ 0x8EF4, 0x214A, WORD_LEN, 0}, -{ 0x8EF6, 0x2040, WORD_LEN, 0}, -{ 0x8EF8, 0x21C2, WORD_LEN, 0}, -{ 0x8EFA, 0x2442, WORD_LEN, 0}, -{ 0x8EFC, 0x8E21, WORD_LEN, 0}, -{ 0x8EFE, 0x214F, WORD_LEN, 0}, -{ 0x8F00, 0x0040, WORD_LEN, 0}, -{ 0x8F02, 0x090F, WORD_LEN, 0}, -{ 0x8F04, 0x2010, WORD_LEN, 0}, -{ 0x8F06, 0x2145, WORD_LEN, 0}, -{ 0x8F08, 0x0181, WORD_LEN, 0}, -{ 0x8F0A, 0xAE21, WORD_LEN, 0}, -{ 0x8F0C, 0xF003, WORD_LEN, 0}, -{ 0x8F0E, 0xB8A2, WORD_LEN, 0}, -{ 0x8F10, 0xAE01, WORD_LEN, 0}, -{ 0x8F12, 0x0FFE, WORD_LEN, 0}, -{ 0x8F14, 0xFFA3, WORD_LEN, 0}, -{ 0x8F16, 0x70A9, WORD_LEN, 0}, -{ 0x8F18, 0x038D, WORD_LEN, 0}, -{ 0x8F1A, 0x0684, WORD_LEN, 0}, -{ 0x8F1C, 0xC0F1, WORD_LEN, 0}, -{ 0x8F1E, 0xC5E1, WORD_LEN, 0}, -{ 0x8F20, 0xD518, WORD_LEN, 0}, -{ 0x8F22, 0x8D00, WORD_LEN, 0}, -{ 0x8F24, 0xB8E7, WORD_LEN, 0}, -{ 0x8F26, 0x20D1, WORD_LEN, 0}, -{ 0x8F28, 0x80E2, WORD_LEN, 0}, -{ 0x8F2A, 0xF20D, WORD_LEN, 0}, -{ 0x8F2C, 0xD117, WORD_LEN, 0}, -{ 0x8F2E, 0xB8A7, WORD_LEN, 0}, -{ 0x8F30, 0xAD00, WORD_LEN, 0}, -{ 0x8F32, 0xD017, WORD_LEN, 0}, -{ 0x8F34, 0x7228, WORD_LEN, 0}, -{ 0x8F36, 0x8123, WORD_LEN, 0}, -{ 0x8F38, 0xA040, WORD_LEN, 0}, -{ 0x8F3A, 0x7960, WORD_LEN, 0}, -{ 0x8F3C, 0xD801, WORD_LEN, 0}, -{ 0x8F3E, 0xD800, WORD_LEN, 0}, -{ 0x8F40, 0xAD05, WORD_LEN, 0}, -{ 0x8F42, 0x0F56, WORD_LEN, 0}, -{ 0x8F44, 0xFF83, WORD_LEN, 0}, -{ 0x8F46, 0x0381, WORD_LEN, 0}, -{ 0x8F48, 0x0684, WORD_LEN, 0}, -{ 0x8F4A, 0x78E0, WORD_LEN, 0}, -{ 0x8F4C, 0xD20D, WORD_LEN, 0}, -{ 0x8F4E, 0x8A21, WORD_LEN, 0}, -{ 0x8F50, 0xB9A1, WORD_LEN, 0}, -{ 0x8F52, 0x782F, WORD_LEN, 0}, -{ 0x8F54, 0x7FE0, WORD_LEN, 0}, -{ 0x8F56, 0xAA21, WORD_LEN, 0}, -{ 0x8F58, 0xD00E, WORD_LEN, 0}, -{ 0x8F5A, 0xD10C, WORD_LEN, 0}, -{ 0x8F5C, 0xA100, WORD_LEN, 0}, -{ 0x8F5E, 0xD00E, WORD_LEN, 0}, -{ 0x8F60, 0xA101, WORD_LEN, 0}, -{ 0x8F62, 0xD00E, WORD_LEN, 0}, -{ 0x8F64, 0xA102, WORD_LEN, 0}, -{ 0x8F66, 0xD00E, WORD_LEN, 0}, -{ 0x8F68, 0xA103, WORD_LEN, 0}, -{ 0x8F6A, 0xD009, WORD_LEN, 0}, -{ 0x8F6C, 0xA020, WORD_LEN, 0}, -{ 0x8F6E, 0xD005, WORD_LEN, 0}, -{ 0x8F70, 0xD988, WORD_LEN, 0}, -{ 0x8F72, 0xA820, WORD_LEN, 0}, -{ 0x8F74, 0xF1D4, WORD_LEN, 0}, -{ 0x8F76, 0x78E0, WORD_LEN, 0}, -{ 0x8F78, 0xFF80, WORD_LEN, 0}, -{ 0x8F7A, 0x10C8, WORD_LEN, 0}, -{ 0x8F7C, 0xFF80, WORD_LEN, 0}, -{ 0x8F7E, 0x0290, WORD_LEN, 0}, -{ 0x8F80, 0xFF80, WORD_LEN, 0}, -{ 0x8F82, 0x0158, WORD_LEN, 0}, -{ 0x8F84, 0xFF00, WORD_LEN, 0}, -{ 0x8F86, 0x0618, WORD_LEN, 0}, -{ 0x8F88, 0xFF80, WORD_LEN, 0}, -{ 0x8F8A, 0x1158, WORD_LEN, 0}, -{ 0x8F8C, 0x8000, WORD_LEN, 0}, -{ 0x8F8E, 0x0008, WORD_LEN, 0}, -{ 0x8F90, 0xFF80, WORD_LEN, 0}, -{ 0x8F92, 0x0F1C, WORD_LEN, 0}, -{ 0x8F94, 0xFF80, WORD_LEN, 0}, -{ 0x8F96, 0x0DEC, WORD_LEN, 0}, -{ 0x8F98, 0xFF80, WORD_LEN, 0}, -{ 0x8F9A, 0x0F4C, WORD_LEN, 0}, -{ 0x8F9C, 0x0000, WORD_LEN, 0}, -{ 0x8F9E, 0x0998, WORD_LEN, 0}, -{ 0x8FA0, 0xC0F1, WORD_LEN, 0}, -{ 0x8FA2, 0xC5E1, WORD_LEN, 0}, -{ 0x8FA4, 0xD02C, WORD_LEN, 0}, -{ 0x8FA6, 0x0982, WORD_LEN, 0}, -{ 0x8FA8, 0x0664, WORD_LEN, 0}, -{ 0x8FAA, 0x88AE, WORD_LEN, 0}, -{ 0x8FAC, 0x0D23, WORD_LEN, 0}, -{ 0x8FAE, 0x1051, WORD_LEN, 0}, -{ 0x8FB0, 0xD12A, WORD_LEN, 0}, -{ 0x8FB2, 0x1145, WORD_LEN, 0}, -{ 0x8FB4, 0x0080, WORD_LEN, 0}, -{ 0x8FB6, 0x1146, WORD_LEN, 0}, -{ 0x8FB8, 0x0082, WORD_LEN, 0}, -{ 0x8FBA, 0xB808, WORD_LEN, 0}, -{ 0x8FBC, 0x7845, WORD_LEN, 0}, -{ 0x8FBE, 0x0813, WORD_LEN, 0}, -{ 0x8FC0, 0x00DE, WORD_LEN, 0}, -{ 0x8FC2, 0xD027, WORD_LEN, 0}, -{ 0x8FC4, 0x8000, WORD_LEN, 0}, -{ 0x8FC6, 0x8041, WORD_LEN, 0}, -{ 0x8FC8, 0x7A60, WORD_LEN, 0}, -{ 0x8FCA, 0x1150, WORD_LEN, 0}, -{ 0x8FCC, 0x0080, WORD_LEN, 0}, -{ 0x8FCE, 0x02F9, WORD_LEN, 0}, -{ 0x8FD0, 0x0684, WORD_LEN, 0}, -{ 0x8FD2, 0x78E0, WORD_LEN, 0}, -{ 0x8FD4, 0xC0F1, WORD_LEN, 0}, -{ 0x8FD6, 0x0A7E, WORD_LEN, 0}, -{ 0x8FD8, 0x0684, WORD_LEN, 0}, -{ 0x8FDA, 0xD622, WORD_LEN, 0}, -{ 0x8FDC, 0x8EA9, WORD_LEN, 0}, -{ 0x8FDE, 0x8E2A, WORD_LEN, 0}, -{ 0x8FE0, 0xBD08, WORD_LEN, 0}, -{ 0x8FE2, 0x7D25, WORD_LEN, 0}, -{ 0x8FE4, 0x2550, WORD_LEN, 0}, -{ 0x8FE6, 0x10C2, WORD_LEN, 0}, -{ 0x8FE8, 0x2A41, WORD_LEN, 0}, -{ 0x8FEA, 0x0201, WORD_LEN, 0}, -{ 0x8FEC, 0xAE29, WORD_LEN, 0}, -{ 0x8FEE, 0x0F9A, WORD_LEN, 0}, -{ 0x8FF0, 0x05A4, WORD_LEN, 0}, -{ 0x8FF2, 0xAE4A, WORD_LEN, 0}, -{ 0x8FF4, 0x0D17, WORD_LEN, 0}, -{ 0x8FF6, 0x10DE, WORD_LEN, 0}, -{ 0x8FF8, 0x8E09, WORD_LEN, 0}, -{ 0x8FFA, 0x8E2A, WORD_LEN, 0}, -{ 0x8FFC, 0xB808, WORD_LEN, 0}, -{ 0x8FFE, 0x7825, WORD_LEN, 0}, -{ 0x9000, 0xB883, WORD_LEN, 0}, -{ 0x9002, 0x2841, WORD_LEN, 0}, -{ 0x9004, 0x0201, WORD_LEN, 0}, -{ 0x9006, 0xAE29, WORD_LEN, 0}, -{ 0x9008, 0xAE0A, WORD_LEN, 0}, -{ 0x900A, 0x02B5, WORD_LEN, 0}, -{ 0x900C, 0x0684, WORD_LEN, 0}, -{ 0x900E, 0x78E0, WORD_LEN, 0}, -{ 0x9010, 0xC0F1, WORD_LEN, 0}, -{ 0x9012, 0x0A42, WORD_LEN, 0}, -{ 0x9014, 0x06A4, WORD_LEN, 0}, -{ 0x9016, 0xDA34, WORD_LEN, 0}, -{ 0x9018, 0xD113, WORD_LEN, 0}, -{ 0x901A, 0xD514, WORD_LEN, 0}, -{ 0x901C, 0x76A9, WORD_LEN, 0}, -{ 0x901E, 0x0FD6, WORD_LEN, 0}, -{ 0x9020, 0x0664, WORD_LEN, 0}, -{ 0x9022, 0x70C9, WORD_LEN, 0}, -{ 0x9024, 0xD012, WORD_LEN, 0}, -{ 0x9026, 0xA504, WORD_LEN, 0}, -{ 0x9028, 0xD012, WORD_LEN, 0}, -{ 0x902A, 0x0295, WORD_LEN, 0}, -{ 0x902C, 0x06A4, WORD_LEN, 0}, -{ 0x902E, 0xA0C0, WORD_LEN, 0}, -{ 0x9030, 0xC0F1, WORD_LEN, 0}, -{ 0x9032, 0xC5E1, WORD_LEN, 0}, -{ 0x9034, 0xD50D, WORD_LEN, 0}, -{ 0x9036, 0xD110, WORD_LEN, 0}, -{ 0x9038, 0x2540, WORD_LEN, 0}, -{ 0x903A, 0x1D00, WORD_LEN, 0}, -{ 0x903C, 0x0FB6, WORD_LEN, 0}, -{ 0x903E, 0x0664, WORD_LEN, 0}, -{ 0x9040, 0xDA50, WORD_LEN, 0}, -{ 0x9042, 0xD00E, WORD_LEN, 0}, -{ 0x9044, 0x2540, WORD_LEN, 0}, -{ 0x9046, 0x1D01, WORD_LEN, 0}, -{ 0x9048, 0xA517, WORD_LEN, 0}, -{ 0x904A, 0xD00D, WORD_LEN, 0}, -{ 0x904C, 0x0279, WORD_LEN, 0}, -{ 0x904E, 0x06A4, WORD_LEN, 0}, -{ 0x9050, 0xA020, WORD_LEN, 0}, -{ 0x9052, 0x78E0, WORD_LEN, 0}, -{ 0x9054, 0xFF80, WORD_LEN, 0}, -{ 0x9056, 0x07A8, WORD_LEN, 0}, -{ 0x9058, 0xFF80, WORD_LEN, 0}, -{ 0x905A, 0x0290, WORD_LEN, 0}, -{ 0x905C, 0x8000, WORD_LEN, 0}, -{ 0x905E, 0x0008, WORD_LEN, 0}, -{ 0x9060, 0xFF80, WORD_LEN, 0}, -{ 0x9062, 0x02CC, WORD_LEN, 0}, -{ 0x9064, 0x0000, WORD_LEN, 0}, -{ 0x9066, 0xFA88, WORD_LEN, 0}, -{ 0x9068, 0xFF80, WORD_LEN, 0}, -{ 0x906A, 0x1168, WORD_LEN, 0}, -{ 0x906C, 0xFF80, WORD_LEN, 0}, -{ 0x906E, 0x0FD4, WORD_LEN, 0}, -{ 0x9070, 0x8000, WORD_LEN, 0}, -{ 0x9072, 0x0194, WORD_LEN, 0}, -{ 0x9074, 0x0000, WORD_LEN, 0}, -{ 0x9076, 0xFB08, WORD_LEN, 0}, -{ 0x9078, 0xFF80, WORD_LEN, 0}, -{ 0x907A, 0x0FA0, WORD_LEN, 0}, -{ 0x907C, 0x8000, WORD_LEN, 0}, -{ 0x907E, 0x01A0, WORD_LEN, 0}, -{ 0x9080, 0xE280, WORD_LEN, 0}, -{ 0x9082, 0x24CA, WORD_LEN, 0}, -{ 0x9084, 0x7082, WORD_LEN, 0}, -{ 0x9086, 0x78E0, WORD_LEN, 0}, -{ 0x9088, 0x20E8, WORD_LEN, 0}, -{ 0x908A, 0x01A2, WORD_LEN, 0}, -{ 0x908C, 0x1002, WORD_LEN, 0}, -{ 0x908E, 0x0D02, WORD_LEN, 0}, -{ 0x9090, 0x1902, WORD_LEN, 0}, -{ 0x9092, 0x0094, WORD_LEN, 0}, -{ 0x9094, 0x7FE0, WORD_LEN, 0}, -{ 0x9096, 0x7028, WORD_LEN, 0}, -{ 0x9098, 0x7308, WORD_LEN, 0}, -{ 0x909A, 0x1000, WORD_LEN, 0}, -{ 0x909C, 0x0900, WORD_LEN, 0}, -{ 0x909E, 0x7904, WORD_LEN, 0}, -{ 0x90A0, 0x7947, WORD_LEN, 0}, -{ 0x90A2, 0x1B00, WORD_LEN, 0}, -{ 0x90A4, 0x0064, WORD_LEN, 0}, -{ 0x90A6, 0x7EE0, WORD_LEN, 0}, -{ 0x90A8, 0xE280, WORD_LEN, 0}, -{ 0x90AA, 0x24CA, WORD_LEN, 0}, -{ 0x90AC, 0x7082, WORD_LEN, 0}, -{ 0x90AE, 0x78E0, WORD_LEN, 0}, -{ 0x90B0, 0x20E8, WORD_LEN, 0}, -{ 0x90B2, 0x01A2, WORD_LEN, 0}, -{ 0x90B4, 0x1102, WORD_LEN, 0}, -{ 0x90B6, 0x0502, WORD_LEN, 0}, -{ 0x90B8, 0x1802, WORD_LEN, 0}, -{ 0x90BA, 0x00B4, WORD_LEN, 0}, -{ 0x90BC, 0x7FE0, WORD_LEN, 0}, -{ 0x90BE, 0x7028, WORD_LEN, 0}, -{ 0x90C0, 0x0000, WORD_LEN, 0}, -{ 0x90C2, 0x0000, WORD_LEN, 0}, -{ 0x90C4, 0x0000, WORD_LEN, 0}, -{ 0x90C6, 0x0000, WORD_LEN, 0}, -{ 0x098E, 0x0000, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS -{ 0x8016, 0x086C, WORD_LEN, 0}, // MON_ADDRESS_LO -{ 0x8018, 0xFF80, WORD_LEN, 0}, // MON_ADDRESS_HI -{ 0x8002, 0x0001, WORD_LEN, 0}, // MON_CMD +{ 0x098E, 0x0000, 0xffff,0xffff}, // LOGICAL_ADDRESS_ACCESS +{ 0x301A, 0x0030, 0xffff,0xffff}, // RESET_REGISTER +{ 0x316C, 0xB430, 0xffff,0xffff}, // DAC_TXLO +{ 0x31E0, 0x0003, 0xffff,0xffff}, // PIX_DEF_ID +{ 0x3E2E, 0xF319, 0xffff,0xffff}, // SAMP_SPARE +{ 0x3EE6, 0xA7C1, 0xffff,0xffff}, // DAC_LD_26_27 +{ 0x301E, 0x00A8, 0xffff,0xffff}, // DATA_PEDESTAL +{ 0xDC33, 0x2A, 0xffff,0xff}, // SYS_FIRST_BLACK_LEVEL +{ 0x3812, 0x212C, 0xffff,0xffff}, // OTPM_CFG +{ 0x0982, 0x0000, 0xffff,0xffff}, // ACCESS_CTL_STAT +{ 0x098A, 0x0000, 0xffff,0xffff}, // PHYSICAL_ADDRESS_ACCESS +{ 0x886C, 0xC0F1, 0xffff,0xffff}, +{ 0x886E, 0xC5E1, 0xffff,0xffff}, +{ 0x8870, 0x246A, 0xffff,0xffff}, +{ 0x8872, 0x1280, 0xffff,0xffff}, +{ 0x8874, 0xC4E1, 0xffff,0xffff}, +{ 0x8876, 0xD20F, 0xffff,0xffff}, +{ 0x8878, 0x2069, 0xffff,0xffff}, +{ 0x887A, 0x0000, 0xffff,0xffff}, +{ 0x887C, 0x6A62, 0xffff,0xffff}, +{ 0x887E, 0x1303, 0xffff,0xffff}, +{ 0x8880, 0x0084, 0xffff,0xffff}, +{ 0x8882, 0x1734, 0xffff,0xffff}, +{ 0x8884, 0x7005, 0xffff,0xffff}, +{ 0x8886, 0xD801, 0xffff,0xffff}, +{ 0x8888, 0x8A41, 0xffff,0xffff}, +{ 0x888A, 0xD900, 0xffff,0xffff}, +{ 0x888C, 0x0D5A, 0xffff,0xffff}, +{ 0x888E, 0x0664, 0xffff,0xffff}, +{ 0x8890, 0x8B61, 0xffff,0xffff}, +{ 0x8892, 0xE80B, 0xffff,0xffff}, +{ 0x8894, 0x000D, 0xffff,0xffff}, +{ 0x8896, 0x0020, 0xffff,0xffff}, +{ 0x8898, 0xD508, 0xffff,0xffff}, +{ 0x889A, 0x1504, 0xffff,0xffff}, +{ 0x889C, 0x1400, 0xffff,0xffff}, +{ 0x889E, 0x7840, 0xffff,0xffff}, +{ 0x88A0, 0xD007, 0xffff,0xffff}, +{ 0x88A2, 0x0DFB, 0xffff,0xffff}, +{ 0x88A4, 0x9004, 0xffff,0xffff}, +{ 0x88A6, 0xC4C1, 0xffff,0xffff}, +{ 0x88A8, 0x2029, 0xffff,0xffff}, +{ 0x88AA, 0x0300, 0xffff,0xffff}, +{ 0x88AC, 0x0219, 0xffff,0xffff}, +{ 0x88AE, 0x06C4, 0xffff,0xffff}, +{ 0x88B0, 0xFF80, 0xffff,0xffff}, +{ 0x88B2, 0x08D4, 0xffff,0xffff}, +{ 0x88B4, 0xFF80, 0xffff,0xffff}, +{ 0x88B6, 0x086C, 0xffff,0xffff}, +{ 0x88B8, 0xFF80, 0xffff,0xffff}, +{ 0x88BA, 0x08C0, 0xffff,0xffff}, +{ 0x88BC, 0xFF80, 0xffff,0xffff}, +{ 0x88BE, 0x08D4, 0xffff,0xffff}, +{ 0x88C0, 0xFF80, 0xffff,0xffff}, +{ 0x88C2, 0x08DC, 0xffff,0xffff}, +{ 0x88C4, 0xFF80, 0xffff,0xffff}, +{ 0x88C6, 0x0F58, 0xffff,0xffff}, +{ 0x88C8, 0xFF80, 0xffff,0xffff}, +{ 0x88CA, 0x0920, 0xffff,0xffff}, +{ 0x88CC, 0xFF80, 0xffff,0xffff}, +{ 0x88CE, 0x1010, 0xffff,0xffff}, +{ 0x88D0, 0xFF80, 0xffff,0xffff}, +{ 0x88D2, 0x1030, 0xffff,0xffff}, +{ 0x88D4, 0x0010, 0xffff,0xffff}, +{ 0x88D6, 0x0008, 0xffff,0xffff}, +{ 0x88D8, 0x0000, 0xffff,0xffff}, +{ 0x88DA, 0x0000, 0xffff,0xffff}, +{ 0x88DC, 0xD102, 0xffff,0xffff}, +{ 0x88DE, 0xD003, 0xffff,0xffff}, +{ 0x88E0, 0x7FE0, 0xffff,0xffff}, +{ 0x88E2, 0xB035, 0xffff,0xffff}, +{ 0x88E4, 0xFF80, 0xffff,0xffff}, +{ 0x88E6, 0x10C8, 0xffff,0xffff}, +{ 0x88E8, 0xFF80, 0xffff,0xffff}, +{ 0x88EA, 0x0118, 0xffff,0xffff}, +{ 0x88EC, 0xC0F1, 0xffff,0xffff}, +{ 0x88EE, 0xC5E1, 0xffff,0xffff}, +{ 0x88F0, 0xD5EC, 0xffff,0xffff}, +{ 0x88F2, 0x8D04, 0xffff,0xffff}, +{ 0x88F4, 0x8D25, 0xffff,0xffff}, +{ 0x88F6, 0xB808, 0xffff,0xffff}, +{ 0x88F8, 0x7825, 0xffff,0xffff}, +{ 0x88FA, 0x0821, 0xffff,0xffff}, +{ 0x88FC, 0x01DE, 0xffff,0xffff}, +{ 0x88FE, 0xD0EA, 0xffff,0xffff}, +{ 0x8900, 0x8000, 0xffff,0xffff}, +{ 0x8902, 0x8008, 0xffff,0xffff}, +{ 0x8904, 0x7840, 0xffff,0xffff}, +{ 0x8906, 0x8D04, 0xffff,0xffff}, +{ 0x8908, 0x8D25, 0xffff,0xffff}, +{ 0x890A, 0xB808, 0xffff,0xffff}, +{ 0x890C, 0x7825, 0xffff,0xffff}, +{ 0x890E, 0xB8A7, 0xffff,0xffff}, +{ 0x8910, 0x2841, 0xffff,0xffff}, +{ 0x8912, 0x0201, 0xffff,0xffff}, +{ 0x8914, 0xAD24, 0xffff,0xffff}, +{ 0x8916, 0xAD05, 0xffff,0xffff}, +{ 0x8918, 0x09A6, 0xffff,0xffff}, +{ 0x891A, 0x0104, 0xffff,0xffff}, +{ 0x891C, 0x01A9, 0xffff,0xffff}, +{ 0x891E, 0x06C4, 0xffff,0xffff}, +{ 0x8920, 0xC0F1, 0xffff,0xffff}, +{ 0x8922, 0x0932, 0xffff,0xffff}, +{ 0x8924, 0x06E4, 0xffff,0xffff}, +{ 0x8926, 0xDA38, 0xffff,0xffff}, +{ 0x8928, 0xD1E0, 0xffff,0xffff}, +{ 0x892A, 0xD5E1, 0xffff,0xffff}, +{ 0x892C, 0x76A9, 0xffff,0xffff}, +{ 0x892E, 0x0EC6, 0xffff,0xffff}, +{ 0x8930, 0x06A4, 0xffff,0xffff}, +{ 0x8932, 0x70C9, 0xffff,0xffff}, +{ 0x8934, 0xD0DF, 0xffff,0xffff}, +{ 0x8936, 0xA501, 0xffff,0xffff}, +{ 0x8938, 0xD0DF, 0xffff,0xffff}, +{ 0x893A, 0xA503, 0xffff,0xffff}, +{ 0x893C, 0xD0DF, 0xffff,0xffff}, +{ 0x893E, 0xA506, 0xffff,0xffff}, +{ 0x8940, 0xD0DF, 0xffff,0xffff}, +{ 0x8942, 0xA509, 0xffff,0xffff}, +{ 0x8944, 0xD0D8, 0xffff,0xffff}, +{ 0x8946, 0xA0C0, 0xffff,0xffff}, +{ 0x8948, 0xD0DE, 0xffff,0xffff}, +{ 0x894A, 0x802E, 0xffff,0xffff}, +{ 0x894C, 0x9117, 0xffff,0xffff}, +{ 0x894E, 0x0171, 0xffff,0xffff}, +{ 0x8950, 0x06E4, 0xffff,0xffff}, +{ 0x8952, 0xB10E, 0xffff,0xffff}, +{ 0x8954, 0xC0F1, 0xffff,0xffff}, +{ 0x8956, 0xD0D3, 0xffff,0xffff}, +{ 0x8958, 0x8806, 0xffff,0xffff}, +{ 0x895A, 0x080F, 0xffff,0xffff}, +{ 0x895C, 0x0051, 0xffff,0xffff}, +{ 0x895E, 0xD0D2, 0xffff,0xffff}, +{ 0x8960, 0x8000, 0xffff,0xffff}, +{ 0x8962, 0x8008, 0xffff,0xffff}, +{ 0x8964, 0x7840, 0xffff,0xffff}, +{ 0x8966, 0x0A1E, 0xffff,0xffff}, +{ 0x8968, 0x0104, 0xffff,0xffff}, +{ 0x896A, 0xC0D1, 0xffff,0xffff}, +{ 0x896C, 0x7EE0, 0xffff,0xffff}, +{ 0x896E, 0x78E0, 0xffff,0xffff}, +{ 0x8970, 0xC0F1, 0xffff,0xffff}, +{ 0x8972, 0x08D6, 0xffff,0xffff}, +{ 0x8974, 0x06C4, 0xffff,0xffff}, +{ 0x8976, 0xD7CC, 0xffff,0xffff}, +{ 0x8978, 0x8700, 0xffff,0xffff}, +{ 0x897A, 0x8009, 0xffff,0xffff}, +{ 0x897C, 0x7840, 0xffff,0xffff}, +{ 0x897E, 0xE080, 0xffff,0xffff}, +{ 0x8980, 0x0276, 0xffff,0xffff}, +{ 0x8982, 0x0002, 0xffff,0xffff}, +{ 0x8984, 0xD5C7, 0xffff,0xffff}, +{ 0x8986, 0xD6D0, 0xffff,0xffff}, +{ 0x8988, 0x1530, 0xffff,0xffff}, +{ 0x898A, 0x1081, 0xffff,0xffff}, +{ 0x898C, 0x1531, 0xffff,0xffff}, +{ 0x898E, 0x1080, 0xffff,0xffff}, +{ 0x8990, 0xB908, 0xffff,0xffff}, +{ 0x8992, 0x7905, 0xffff,0xffff}, +{ 0x8994, 0x2941, 0xffff,0xffff}, +{ 0x8996, 0x0200, 0xffff,0xffff}, +{ 0x8998, 0x1D32, 0xffff,0xffff}, +{ 0x899A, 0x1002, 0xffff,0xffff}, +{ 0x899C, 0x1D33, 0xffff,0xffff}, +{ 0x899E, 0x1042, 0xffff,0xffff}, +{ 0x89A0, 0x962D, 0xffff,0xffff}, +{ 0x89A2, 0x2540, 0xffff,0xffff}, +{ 0x89A4, 0x15D1, 0xffff,0xffff}, +{ 0x89A6, 0x2941, 0xffff,0xffff}, +{ 0x89A8, 0x0200, 0xffff,0xffff}, +{ 0x89AA, 0x1D30, 0xffff,0xffff}, +{ 0x89AC, 0x1002, 0xffff,0xffff}, +{ 0x89AE, 0x8D06, 0xffff,0xffff}, +{ 0x89B0, 0x2540, 0xffff,0xffff}, +{ 0x89B2, 0x1610, 0xffff,0xffff}, +{ 0x89B4, 0x1D31, 0xffff,0xffff}, +{ 0x89B6, 0x1042, 0xffff,0xffff}, +{ 0x89B8, 0x081B, 0xffff,0xffff}, +{ 0x89BA, 0x0051, 0xffff,0xffff}, +{ 0x89BC, 0x8700, 0xffff,0xffff}, +{ 0x89BE, 0x8008, 0xffff,0xffff}, +{ 0x89C0, 0x7840, 0xffff,0xffff}, +{ 0x89C2, 0xD900, 0xffff,0xffff}, +{ 0x89C4, 0x2941, 0xffff,0xffff}, +{ 0x89C6, 0x0200, 0xffff,0xffff}, +{ 0x89C8, 0xAD00, 0xffff,0xffff}, +{ 0x89CA, 0xAD21, 0xffff,0xffff}, +{ 0x89CC, 0xD801, 0xffff,0xffff}, +{ 0x89CE, 0x1D4D, 0xffff,0xffff}, +{ 0x89D0, 0x1002, 0xffff,0xffff}, +{ 0x89D2, 0x154D, 0xffff,0xffff}, +{ 0x89D4, 0x1080, 0xffff,0xffff}, +{ 0x89D6, 0xB861, 0xffff,0xffff}, +{ 0x89D8, 0xE085, 0xffff,0xffff}, +{ 0x89DA, 0x0218, 0xffff,0xffff}, +{ 0x89DC, 0x000D, 0xffff,0xffff}, +{ 0x89DE, 0x2740, 0xffff,0xffff}, +{ 0x89E0, 0x7381, 0xffff,0xffff}, +{ 0x89E2, 0x2132, 0xffff,0xffff}, +{ 0x89E4, 0x0000, 0xffff,0xffff}, +{ 0x89E6, 0x7914, 0xffff,0xffff}, +{ 0x89E8, 0x7900, 0xffff,0xffff}, +{ 0x89EA, 0x0323, 0xffff,0xffff}, +{ 0x89EC, 0x67BB, 0xffff,0xffff}, +{ 0x89EE, 0xD62E, 0xffff,0xffff}, +{ 0x89F0, 0x8D11, 0xffff,0xffff}, +{ 0x89F2, 0xD1B6, 0xffff,0xffff}, +{ 0x89F4, 0x8924, 0xffff,0xffff}, +{ 0x89F6, 0x2032, 0xffff,0xffff}, +{ 0x89F8, 0x2000, 0xffff,0xffff}, +{ 0x89FA, 0xDE02, 0xffff,0xffff}, +{ 0x89FC, 0x082B, 0xffff,0xffff}, +{ 0x89FE, 0x0040, 0xffff,0xffff}, +{ 0x8A00, 0x8D20, 0xffff,0xffff}, +{ 0x8A02, 0x8D41, 0xffff,0xffff}, +{ 0x8A04, 0xB908, 0xffff,0xffff}, +{ 0x8A06, 0x7945, 0xffff,0xffff}, +{ 0x8A08, 0xB983, 0xffff,0xffff}, +{ 0x8A0A, 0x2941, 0xffff,0xffff}, +{ 0x8A0C, 0x0202, 0xffff,0xffff}, +{ 0x8A0E, 0xAD40, 0xffff,0xffff}, +{ 0x8A10, 0xAD21, 0xffff,0xffff}, +{ 0x8A12, 0xD1AF, 0xffff,0xffff}, +{ 0x8A14, 0x8120, 0xffff,0xffff}, +{ 0x8A16, 0x8121, 0xffff,0xffff}, +{ 0x8A18, 0x7940, 0xffff,0xffff}, +{ 0x8A1A, 0x8D06, 0xffff,0xffff}, +{ 0x8A1C, 0xE001, 0xffff,0xffff}, +{ 0x8A1E, 0xAD06, 0xffff,0xffff}, +{ 0x8A20, 0x1D4D, 0xffff,0xffff}, +{ 0x8A22, 0x1382, 0xffff,0xffff}, +{ 0x8A24, 0xF0E9, 0xffff,0xffff}, +{ 0x8A26, 0x8D06, 0xffff,0xffff}, +{ 0x8A28, 0x1D4D, 0xffff,0xffff}, +{ 0x8A2A, 0x1382, 0xffff,0xffff}, +{ 0x8A2C, 0xE001, 0xffff,0xffff}, +{ 0x8A2E, 0xAD06, 0xffff,0xffff}, +{ 0x8A30, 0x8D00, 0xffff,0xffff}, +{ 0x8A32, 0x8D21, 0xffff,0xffff}, +{ 0x8A34, 0xB808, 0xffff,0xffff}, +{ 0x8A36, 0x7825, 0xffff,0xffff}, +{ 0x8A38, 0xB885, 0xffff,0xffff}, +{ 0x8A3A, 0x2841, 0xffff,0xffff}, +{ 0x8A3C, 0x0201, 0xffff,0xffff}, +{ 0x8A3E, 0xAD20, 0xffff,0xffff}, +{ 0x8A40, 0xAD01, 0xffff,0xffff}, +{ 0x8A42, 0x8D31, 0xffff,0xffff}, +{ 0x8A44, 0xF01A, 0xffff,0xffff}, +{ 0x8A46, 0x8D31, 0xffff,0xffff}, +{ 0x8A48, 0x8D12, 0xffff,0xffff}, +{ 0x8A4A, 0x8D46, 0xffff,0xffff}, +{ 0x8A4C, 0x7822, 0xffff,0xffff}, +{ 0x8A4E, 0x0863, 0xffff,0xffff}, +{ 0x8A50, 0x0082, 0xffff,0xffff}, +{ 0x8A52, 0x1532, 0xffff,0xffff}, +{ 0x8A54, 0x1080, 0xffff,0xffff}, +{ 0x8A56, 0x1533, 0xffff,0xffff}, +{ 0x8A58, 0x1081, 0xffff,0xffff}, +{ 0x8A5A, 0x1531, 0xffff,0xffff}, +{ 0x8A5C, 0x1082, 0xffff,0xffff}, +{ 0x8A5E, 0xB808, 0xffff,0xffff}, +{ 0x8A60, 0x7825, 0xffff,0xffff}, +{ 0x8A62, 0x1530, 0xffff,0xffff}, +{ 0x8A64, 0x1081, 0xffff,0xffff}, +{ 0x8A66, 0xB908, 0xffff,0xffff}, +{ 0x8A68, 0x7945, 0xffff,0xffff}, +{ 0x8A6A, 0xD29A, 0xffff,0xffff}, +{ 0x8A6C, 0x0992, 0xffff,0xffff}, +{ 0x8A6E, 0x0020, 0xffff,0xffff}, +{ 0x8A70, 0x8A40, 0xffff,0xffff}, +{ 0x8A72, 0x8D31, 0xffff,0xffff}, +{ 0x8A74, 0x081F, 0xffff,0xffff}, +{ 0x8A76, 0x0051, 0xffff,0xffff}, +{ 0x8A78, 0x8D06, 0xffff,0xffff}, +{ 0x8A7A, 0x6038, 0xffff,0xffff}, +{ 0x8A7C, 0xD194, 0xffff,0xffff}, +{ 0x8A7E, 0x8120, 0xffff,0xffff}, +{ 0x8A80, 0x8121, 0xffff,0xffff}, +{ 0x8A82, 0x7960, 0xffff,0xffff}, +{ 0x8A84, 0x2132, 0xffff,0xffff}, +{ 0x8A86, 0x2000, 0xffff,0xffff}, +{ 0x8A88, 0x8D06, 0xffff,0xffff}, +{ 0x8A8A, 0xE001, 0xffff,0xffff}, +{ 0x8A8C, 0xAD06, 0xffff,0xffff}, +{ 0x8A8E, 0xD806, 0xffff,0xffff}, +{ 0x8A90, 0xF0B1, 0xffff,0xffff}, +{ 0x8A92, 0xE88F, 0xffff,0xffff}, +{ 0x8A94, 0x8D66, 0xffff,0xffff}, +{ 0x8A96, 0x633B, 0xffff,0xffff}, +{ 0x8A98, 0x63BB, 0xffff,0xffff}, +{ 0x8A9A, 0xD08D, 0xffff,0xffff}, +{ 0x8A9C, 0x8000, 0xffff,0xffff}, +{ 0x8A9E, 0x8021, 0xffff,0xffff}, +{ 0x8AA0, 0x7960, 0xffff,0xffff}, +{ 0x8AA2, 0x8B17, 0xffff,0xffff}, +{ 0x8AA4, 0x8D06, 0xffff,0xffff}, +{ 0x8AA6, 0xE001, 0xffff,0xffff}, +{ 0x8AA8, 0xAD06, 0xffff,0xffff}, +{ 0x8AAA, 0xD803, 0xffff,0xffff}, +{ 0x8AAC, 0xF0A3, 0xffff,0xffff}, +{ 0x8AAE, 0x2032, 0xffff,0xffff}, +{ 0x8AB0, 0x2040, 0xffff,0xffff}, +{ 0x8AB2, 0xAD07, 0xffff,0xffff}, +{ 0x8AB4, 0xD804, 0xffff,0xffff}, +{ 0x8AB6, 0xF09F, 0xffff,0xffff}, +{ 0x8AB8, 0x1532, 0xffff,0xffff}, +{ 0x8ABA, 0x1080, 0xffff,0xffff}, +{ 0x8ABC, 0x1533, 0xffff,0xffff}, +{ 0x8ABE, 0x1081, 0xffff,0xffff}, +{ 0x8AC0, 0x1531, 0xffff,0xffff}, +{ 0x8AC2, 0x1082, 0xffff,0xffff}, +{ 0x8AC4, 0xB808, 0xffff,0xffff}, +{ 0x8AC6, 0x7825, 0xffff,0xffff}, +{ 0x8AC8, 0x1530, 0xffff,0xffff}, +{ 0x8ACA, 0x1081, 0xffff,0xffff}, +{ 0x8ACC, 0xB908, 0xffff,0xffff}, +{ 0x8ACE, 0x7945, 0xffff,0xffff}, +{ 0x8AD0, 0xD280, 0xffff,0xffff}, +{ 0x8AD2, 0x092E, 0xffff,0xffff}, +{ 0x8AD4, 0x0020, 0xffff,0xffff}, +{ 0x8AD6, 0x8A41, 0xffff,0xffff}, +{ 0x8AD8, 0x8D51, 0xffff,0xffff}, +{ 0x8ADA, 0x8D32, 0xffff,0xffff}, +{ 0x8ADC, 0x8DC6, 0xffff,0xffff}, +{ 0x8ADE, 0x7942, 0xffff,0xffff}, +{ 0x8AE0, 0x62DB, 0xffff,0xffff}, +{ 0x8AE2, 0x091F, 0xffff,0xffff}, +{ 0x8AE4, 0x03A2, 0xffff,0xffff}, +{ 0x8AE6, 0x63BB, 0xffff,0xffff}, +{ 0x8AE8, 0xE88B, 0xffff,0xffff}, +{ 0x8AEA, 0x8D00, 0xffff,0xffff}, +{ 0x8AEC, 0x8D21, 0xffff,0xffff}, +{ 0x8AEE, 0xB808, 0xffff,0xffff}, +{ 0x8AF0, 0x7825, 0xffff,0xffff}, +{ 0x8AF2, 0xB885, 0xffff,0xffff}, +{ 0x8AF4, 0x2841, 0xffff,0xffff}, +{ 0x8AF6, 0x0201, 0xffff,0xffff}, +{ 0x8AF8, 0xAD20, 0xffff,0xffff}, +{ 0x8AFA, 0xAD01, 0xffff,0xffff}, +{ 0x8AFC, 0xF1CF, 0xffff,0xffff}, +{ 0x8AFE, 0xDF04, 0xffff,0xffff}, +{ 0x8B00, 0x092B, 0xffff,0xffff}, +{ 0x8B02, 0x03A3, 0xffff,0xffff}, +{ 0x8B04, 0x1D4D, 0xffff,0xffff}, +{ 0x8B06, 0x13C2, 0xffff,0xffff}, +{ 0x8B08, 0x1530, 0xffff,0xffff}, +{ 0x8B0A, 0x108E, 0xffff,0xffff}, +{ 0x8B0C, 0x1531, 0xffff,0xffff}, +{ 0x8B0E, 0x1081, 0xffff,0xffff}, +{ 0x8B10, 0x1533, 0xffff,0xffff}, +{ 0x8B12, 0x108F, 0xffff,0xffff}, +{ 0x8B14, 0xBE08, 0xffff,0xffff}, +{ 0x8B16, 0x7E25, 0xffff,0xffff}, +{ 0x8B18, 0x1532, 0xffff,0xffff}, +{ 0x8B1A, 0x1081, 0xffff,0xffff}, +{ 0x8B1C, 0xB908, 0xffff,0xffff}, +{ 0x8B1E, 0x79E5, 0xffff,0xffff}, +{ 0x8B20, 0x0907, 0xffff,0xffff}, +{ 0x8B22, 0x0382, 0xffff,0xffff}, +{ 0x8B24, 0xE883, 0xffff,0xffff}, +{ 0x8B26, 0x8B16, 0xffff,0xffff}, +{ 0x8B28, 0xF002, 0xffff,0xffff}, +{ 0x8B2A, 0x8B15, 0xffff,0xffff}, +{ 0x8B2C, 0x8D22, 0xffff,0xffff}, +{ 0x8B2E, 0xAD07, 0xffff,0xffff}, +{ 0x8B30, 0x8D03, 0xffff,0xffff}, +{ 0x8B32, 0xD367, 0xffff,0xffff}, +{ 0x8B34, 0xB908, 0xffff,0xffff}, +{ 0x8B36, 0x8DC1, 0xffff,0xffff}, +{ 0x8B38, 0x7905, 0xffff,0xffff}, +{ 0x8B3A, 0x8D00, 0xffff,0xffff}, +{ 0x8B3C, 0xB808, 0xffff,0xffff}, +{ 0x8B3E, 0x78C5, 0xffff,0xffff}, +{ 0x8B40, 0x0921, 0xffff,0xffff}, +{ 0x8B42, 0x011E, 0xffff,0xffff}, +{ 0x8B44, 0xB883, 0xffff,0xffff}, +{ 0x8B46, 0x2841, 0xffff,0xffff}, +{ 0x8B48, 0x0201, 0xffff,0xffff}, +{ 0x8B4A, 0xAD20, 0xffff,0xffff}, +{ 0x8B4C, 0x8320, 0xffff,0xffff}, +{ 0x8B4E, 0xAD01, 0xffff,0xffff}, +{ 0x8B50, 0x8121, 0xffff,0xffff}, +{ 0x8B52, 0x7960, 0xffff,0xffff}, +{ 0x8B54, 0x2032, 0xffff,0xffff}, +{ 0x8B56, 0x2080, 0xffff,0xffff}, +{ 0x8B58, 0x8D06, 0xffff,0xffff}, +{ 0x8B5A, 0xE001, 0xffff,0xffff}, +{ 0x8B5C, 0xAD06, 0xffff,0xffff}, +{ 0x8B5E, 0xF04D, 0xffff,0xffff}, +{ 0x8B60, 0x8D00, 0xffff,0xffff}, +{ 0x8B62, 0x8D21, 0xffff,0xffff}, +{ 0x8B64, 0xB808, 0xffff,0xffff}, +{ 0x8B66, 0x7825, 0xffff,0xffff}, +{ 0x8B68, 0xB886, 0xffff,0xffff}, +{ 0x8B6A, 0x2841, 0xffff,0xffff}, +{ 0x8B6C, 0x0201, 0xffff,0xffff}, +{ 0x8B6E, 0xAD20, 0xffff,0xffff}, +{ 0x8B70, 0xAD01, 0xffff,0xffff}, +{ 0x8B72, 0xD057, 0xffff,0xffff}, +{ 0x8B74, 0x8000, 0xffff,0xffff}, +{ 0x8B76, 0x8021, 0xffff,0xffff}, +{ 0x8B78, 0x7960, 0xffff,0xffff}, +{ 0x8B7A, 0x8D07, 0xffff,0xffff}, +{ 0x8B7C, 0x1545, 0xffff,0xffff}, +{ 0x8B7E, 0x1080, 0xffff,0xffff}, +{ 0x8B80, 0x1546, 0xffff,0xffff}, +{ 0x8B82, 0x1081, 0xffff,0xffff}, +{ 0x8B84, 0xB808, 0xffff,0xffff}, +{ 0x8B86, 0x7825, 0xffff,0xffff}, +{ 0x8B88, 0x085D, 0xffff,0xffff}, +{ 0x8B8A, 0x005E, 0xffff,0xffff}, +{ 0x8B8C, 0x8D06, 0xffff,0xffff}, +{ 0x8B8E, 0xE001, 0xffff,0xffff}, +{ 0x8B90, 0xAD06, 0xffff,0xffff}, +{ 0x8B92, 0xD805, 0xffff,0xffff}, +{ 0x8B94, 0xF02F, 0xffff,0xffff}, +{ 0x8B96, 0x1530, 0xffff,0xffff}, +{ 0x8B98, 0x1082, 0xffff,0xffff}, +{ 0x8B9A, 0x1531, 0xffff,0xffff}, +{ 0x8B9C, 0x1080, 0xffff,0xffff}, +{ 0x8B9E, 0xD14D, 0xffff,0xffff}, +{ 0x8BA0, 0xBA08, 0xffff,0xffff}, +{ 0x8BA2, 0x7A05, 0xffff,0xffff}, +{ 0x8BA4, 0x8903, 0xffff,0xffff}, +{ 0x8BA6, 0x080F, 0xffff,0xffff}, +{ 0x8BA8, 0x0083, 0xffff,0xffff}, +{ 0x8BAA, 0x8902, 0xffff,0xffff}, +{ 0x8BAC, 0x8E44, 0xffff,0xffff}, +{ 0x8BAE, 0x0839, 0xffff,0xffff}, +{ 0x8BB0, 0x0082, 0xffff,0xffff}, +{ 0x8BB2, 0x1545, 0xffff,0xffff}, +{ 0x8BB4, 0x1082, 0xffff,0xffff}, +{ 0x8BB6, 0x1546, 0xffff,0xffff}, +{ 0x8BB8, 0x1080, 0xffff,0xffff}, +{ 0x8BBA, 0xBA08, 0xffff,0xffff}, +{ 0x8BBC, 0x7A05, 0xffff,0xffff}, +{ 0x8BBE, 0x0A29, 0xffff,0xffff}, +{ 0x8BC0, 0x005E, 0xffff,0xffff}, +{ 0x8BC2, 0x8D00, 0xffff,0xffff}, +{ 0x8BC4, 0x8D21, 0xffff,0xffff}, +{ 0x8BC6, 0xB808, 0xffff,0xffff}, +{ 0x8BC8, 0x7825, 0xffff,0xffff}, +{ 0x8BCA, 0xB88D, 0xffff,0xffff}, +{ 0x8BCC, 0x2841, 0xffff,0xffff}, +{ 0x8BCE, 0x0201, 0xffff,0xffff}, +{ 0x8BD0, 0xAD20, 0xffff,0xffff}, +{ 0x8BD2, 0xAD01, 0xffff,0xffff}, +{ 0x8BD4, 0x0A11, 0xffff,0xffff}, +{ 0x8BD6, 0x009E, 0xffff,0xffff}, +{ 0x8BD8, 0xD03D, 0xffff,0xffff}, +{ 0x8BDA, 0x8000, 0xffff,0xffff}, +{ 0x8BDC, 0x8021, 0xffff,0xffff}, +{ 0x8BDE, 0x7960, 0xffff,0xffff}, +{ 0x8BE0, 0x1550, 0xffff,0xffff}, +{ 0x8BE2, 0x1080, 0xffff,0xffff}, +{ 0x8BE4, 0xD800, 0xffff,0xffff}, +{ 0x8BE6, 0x09AA, 0xffff,0xffff}, +{ 0x8BE8, 0x0164, 0xffff,0xffff}, +{ 0x8BEA, 0x1D4D, 0xffff,0xffff}, +{ 0x8BEC, 0x1002, 0xffff,0xffff}, +{ 0x8BEE, 0xF005, 0xffff,0xffff}, +{ 0x8BF0, 0xD800, 0xffff,0xffff}, +{ 0x8BF2, 0x1D4D, 0xffff,0xffff}, +{ 0x8BF4, 0x1002, 0xffff,0xffff}, +{ 0x8BF6, 0x06B1, 0xffff,0xffff}, +{ 0x8BF8, 0x0684, 0xffff,0xffff}, +{ 0x8BFA, 0x78E0, 0xffff,0xffff}, +{ 0x8BFC, 0xC0F1, 0xffff,0xffff}, +{ 0x8BFE, 0x0E4E, 0xffff,0xffff}, +{ 0x8C00, 0x06A4, 0xffff,0xffff}, +{ 0x8C02, 0x7308, 0xffff,0xffff}, +{ 0x8C04, 0x0919, 0xffff,0xffff}, +{ 0x8C06, 0x0023, 0xffff,0xffff}, +{ 0x8C08, 0x721A, 0xffff,0xffff}, +{ 0x8C0A, 0xD026, 0xffff,0xffff}, +{ 0x8C0C, 0x1030, 0xffff,0xffff}, +{ 0x8C0E, 0x0082, 0xffff,0xffff}, +{ 0x8C10, 0x1031, 0xffff,0xffff}, +{ 0x8C12, 0x0081, 0xffff,0xffff}, +{ 0x8C14, 0xBA08, 0xffff,0xffff}, +{ 0x8C16, 0x7A25, 0xffff,0xffff}, +{ 0x8C18, 0xDD00, 0xffff,0xffff}, +{ 0x8C1A, 0xF005, 0xffff,0xffff}, +{ 0x8C1C, 0xDD01, 0xffff,0xffff}, +{ 0x8C1E, 0x7268, 0xffff,0xffff}, +{ 0x8C20, 0x7328, 0xffff,0xffff}, +{ 0x8C22, 0x2302, 0xffff,0xffff}, +{ 0x8C24, 0x0080, 0xffff,0xffff}, +{ 0x8C26, 0x2885, 0xffff,0xffff}, +{ 0x8C28, 0x0901, 0xffff,0xffff}, +{ 0x8C2A, 0x702F, 0xffff,0xffff}, +{ 0x8C2C, 0x0EFA, 0xffff,0xffff}, +{ 0x8C2E, 0x06A4, 0xffff,0xffff}, +{ 0x8C30, 0x7168, 0xffff,0xffff}, +{ 0x8C32, 0xD31C, 0xffff,0xffff}, +{ 0x8C34, 0x8BC6, 0xffff,0xffff}, +{ 0x8C36, 0x8B31, 0xffff,0xffff}, +{ 0x8C38, 0x780F, 0xffff,0xffff}, +{ 0x8C3A, 0xD226, 0xffff,0xffff}, +{ 0x8C3C, 0x663E, 0xffff,0xffff}, +{ 0x8C3E, 0xD123, 0xffff,0xffff}, +{ 0x8C40, 0xBE62, 0xffff,0xffff}, +{ 0x8C42, 0x7ECF, 0xffff,0xffff}, +{ 0x8C44, 0x89E4, 0xffff,0xffff}, +{ 0x8C46, 0x2214, 0xffff,0xffff}, +{ 0x8C48, 0x0381, 0xffff,0xffff}, +{ 0x8C4A, 0xED07, 0xffff,0xffff}, +{ 0x8C4C, 0x2840, 0xffff,0xffff}, +{ 0x8C4E, 0x020E, 0xffff,0xffff}, +{ 0x8C50, 0x7EE5, 0xffff,0xffff}, +{ 0x8C52, 0xB1CC, 0xffff,0xffff}, +{ 0x8C54, 0xF007, 0xffff,0xffff}, +{ 0x8C56, 0x7E12, 0xffff,0xffff}, +{ 0x8C58, 0xE601, 0xffff,0xffff}, +{ 0x8C5A, 0x7ECF, 0xffff,0xffff}, +{ 0x8C5C, 0xBE08, 0xffff,0xffff}, +{ 0x8C5E, 0x7FC5, 0xffff,0xffff}, +{ 0x8C60, 0xB1EC, 0xffff,0xffff}, +{ 0x8C62, 0x080D, 0xffff,0xffff}, +{ 0x8C64, 0x2003, 0xffff,0xffff}, +{ 0x8C66, 0xED0D, 0xffff,0xffff}, +{ 0x8C68, 0xD800, 0xffff,0xffff}, +{ 0x8C6A, 0xF01A, 0xffff,0xffff}, +{ 0x8C6C, 0x134D, 0xffff,0xffff}, +{ 0x8C6E, 0x0080, 0xffff,0xffff}, +{ 0x8C70, 0x080B, 0xffff,0xffff}, +{ 0x8C72, 0x0190, 0xffff,0xffff}, +{ 0x8C74, 0x8A0E, 0xffff,0xffff}, +{ 0x8C76, 0x080B, 0xffff,0xffff}, +{ 0x8C78, 0x0291, 0xffff,0xffff}, +{ 0x8C7A, 0xD801, 0xffff,0xffff}, +{ 0x8C7C, 0xF010, 0xffff,0xffff}, +{ 0x8C7E, 0x1330, 0xffff,0xffff}, +{ 0x8C80, 0x0081, 0xffff,0xffff}, +{ 0x8C82, 0x1331, 0xffff,0xffff}, +{ 0x8C84, 0x008D, 0xffff,0xffff}, +{ 0x8C86, 0xD802, 0xffff,0xffff}, +{ 0x8C88, 0xB908, 0xffff,0xffff}, +{ 0x8C8A, 0x79A5, 0xffff,0xffff}, +{ 0x8C8C, 0xB22A, 0xffff,0xffff}, +{ 0x8C8E, 0x1332, 0xffff,0xffff}, +{ 0x8C90, 0x0081, 0xffff,0xffff}, +{ 0x8C92, 0x1333, 0xffff,0xffff}, +{ 0x8C94, 0x008D, 0xffff,0xffff}, +{ 0x8C96, 0xB908, 0xffff,0xffff}, +{ 0x8C98, 0x79A5, 0xffff,0xffff}, +{ 0x8C9A, 0xB22B, 0xffff,0xffff}, +{ 0x8C9C, 0x0611, 0xffff,0xffff}, +{ 0x8C9E, 0x0684, 0xffff,0xffff}, +{ 0x8CA0, 0xFF80, 0xffff,0xffff}, +{ 0x8CA2, 0x0290, 0xffff,0xffff}, +{ 0x8CA4, 0x8000, 0xffff,0xffff}, +{ 0x8CA6, 0x008C, 0xffff,0xffff}, +{ 0x8CA8, 0x0000, 0xffff,0xffff}, +{ 0x8CAA, 0xF3BC, 0xffff,0xffff}, +{ 0x8CAC, 0xFF80, 0xffff,0xffff}, +{ 0x8CAE, 0x1120, 0xffff,0xffff}, +{ 0x8CB0, 0xFF80, 0xffff,0xffff}, +{ 0x8CB2, 0x08EC, 0xffff,0xffff}, +{ 0x8CB4, 0xFF80, 0xffff,0xffff}, +{ 0x8CB6, 0x0954, 0xffff,0xffff}, +{ 0x8CB8, 0xFF80, 0xffff,0xffff}, +{ 0x8CBA, 0x0970, 0xffff,0xffff}, +{ 0x8CBC, 0xFF80, 0xffff,0xffff}, +{ 0x8CBE, 0x0CD4, 0xffff,0xffff}, +{ 0x8CC0, 0xFF80, 0xffff,0xffff}, +{ 0x8CC2, 0x06C8, 0xffff,0xffff}, +{ 0x8CC4, 0xFF80, 0xffff,0xffff}, +{ 0x8CC6, 0x050C, 0xffff,0xffff}, +{ 0x8CC8, 0xFF80, 0xffff,0xffff}, +{ 0x8CCA, 0x0158, 0xffff,0xffff}, +{ 0x8CCC, 0x8000, 0xffff,0xffff}, +{ 0x8CCE, 0x0008, 0xffff,0xffff}, +{ 0x8CD0, 0xFF80, 0xffff,0xffff}, +{ 0x8CD2, 0x10C8, 0xffff,0xffff}, +{ 0x8CD4, 0xC0F1, 0xffff,0xffff}, +{ 0x8CD6, 0x0D7E, 0xffff,0xffff}, +{ 0x8CD8, 0x0684, 0xffff,0xffff}, +{ 0x8CDA, 0x17C8, 0xffff,0xffff}, +{ 0x8CDC, 0xF00D, 0xffff,0xffff}, +{ 0x8CDE, 0x1545, 0xffff,0xffff}, +{ 0x8CE0, 0x1080, 0xffff,0xffff}, +{ 0x8CE2, 0x1546, 0xffff,0xffff}, +{ 0x8CE4, 0x1081, 0xffff,0xffff}, +{ 0x8CE6, 0xB808, 0xffff,0xffff}, +{ 0x8CE8, 0x7825, 0xffff,0xffff}, +{ 0x8CEA, 0xB8E0, 0xffff,0xffff}, +{ 0x8CEC, 0xDE00, 0xffff,0xffff}, +{ 0x8CEE, 0xF208, 0xffff,0xffff}, +{ 0x8CF0, 0x8D00, 0xffff,0xffff}, +{ 0x8CF2, 0x8D21, 0xffff,0xffff}, +{ 0x8CF4, 0xB808, 0xffff,0xffff}, +{ 0x8CF6, 0x7825, 0xffff,0xffff}, +{ 0x8CF8, 0x2044, 0xffff,0xffff}, +{ 0x8CFA, 0x020E, 0xffff,0xffff}, +{ 0x8CFC, 0x8D00, 0xffff,0xffff}, +{ 0x8CFE, 0x8D21, 0xffff,0xffff}, +{ 0x8D00, 0xB808, 0xffff,0xffff}, +{ 0x8D02, 0x7825, 0xffff,0xffff}, +{ 0x8D04, 0x082F, 0xffff,0xffff}, +{ 0x8D06, 0x00DE, 0xffff,0xffff}, +{ 0x8D08, 0x7108, 0xffff,0xffff}, +{ 0x8D0A, 0x2186, 0xffff,0xffff}, +{ 0x8D0C, 0x0FFE, 0xffff,0xffff}, +{ 0x8D0E, 0x262F, 0xffff,0xffff}, +{ 0x8D10, 0xF04A, 0xffff,0xffff}, +{ 0x8D12, 0xF211, 0xffff,0xffff}, +{ 0x8D14, 0x17BC, 0xffff,0xffff}, +{ 0x8D16, 0xF002, 0xffff,0xffff}, +{ 0x8D18, 0x8A25, 0xffff,0xffff}, +{ 0x8D1A, 0xE906, 0xffff,0xffff}, +{ 0x8D1C, 0xB961, 0xffff,0xffff}, +{ 0x8D1E, 0xAA25, 0xffff,0xffff}, +{ 0x8D20, 0xD806, 0xffff,0xffff}, +{ 0x8D22, 0xF01E, 0xffff,0xffff}, +{ 0x8D24, 0x8A24, 0xffff,0xffff}, +{ 0x8D26, 0xB8A3, 0xffff,0xffff}, +{ 0x8D28, 0xAA25, 0xffff,0xffff}, +{ 0x8D2A, 0x2841, 0xffff,0xffff}, +{ 0x8D2C, 0x0201, 0xffff,0xffff}, +{ 0x8D2E, 0xAD20, 0xffff,0xffff}, +{ 0x8D30, 0xAD01, 0xffff,0xffff}, +{ 0x8D32, 0x0D56, 0xffff,0xffff}, +{ 0x8D34, 0x0144, 0xffff,0xffff}, +{ 0x8D36, 0x1545, 0xffff,0xffff}, +{ 0x8D38, 0x1081, 0xffff,0xffff}, +{ 0x8D3A, 0x1546, 0xffff,0xffff}, +{ 0x8D3C, 0x1082, 0xffff,0xffff}, +{ 0x8D3E, 0xB908, 0xffff,0xffff}, +{ 0x8D40, 0x7945, 0xffff,0xffff}, +{ 0x8D42, 0xB9E0, 0xffff,0xffff}, +{ 0x8D44, 0x26CC, 0xffff,0xffff}, +{ 0x8D46, 0x9022, 0xffff,0xffff}, +{ 0x8D48, 0xF20A, 0xffff,0xffff}, +{ 0x8D4A, 0x8D20, 0xffff,0xffff}, +{ 0x8D4C, 0x8D41, 0xffff,0xffff}, +{ 0x8D4E, 0xB908, 0xffff,0xffff}, +{ 0x8D50, 0x7945, 0xffff,0xffff}, +{ 0x8D52, 0xB983, 0xffff,0xffff}, +{ 0x8D54, 0x2941, 0xffff,0xffff}, +{ 0x8D56, 0x0202, 0xffff,0xffff}, +{ 0x8D58, 0xAD40, 0xffff,0xffff}, +{ 0x8D5A, 0xAD21, 0xffff,0xffff}, +{ 0x8D5C, 0x0561, 0xffff,0xffff}, +{ 0x8D5E, 0x0684, 0xffff,0xffff}, +{ 0x8D60, 0xC0F1, 0xffff,0xffff}, +{ 0x8D62, 0x0CEE, 0xffff,0xffff}, +{ 0x8D64, 0x06A4, 0xffff,0xffff}, +{ 0x8D66, 0x7098, 0xffff,0xffff}, +{ 0x8D68, 0xD284, 0xffff,0xffff}, +{ 0x8D6A, 0x1206, 0xffff,0xffff}, +{ 0x8D6C, 0x0086, 0xffff,0xffff}, +{ 0x8D6E, 0x2240, 0xffff,0xffff}, +{ 0x8D70, 0x0205, 0xffff,0xffff}, +{ 0x8D72, 0x264C, 0xffff,0xffff}, +{ 0x8D74, 0x8000, 0xffff,0xffff}, +{ 0x8D76, 0x20CA, 0xffff,0xffff}, +{ 0x8D78, 0x0101, 0xffff,0xffff}, +{ 0x8D7A, 0xF237, 0xffff,0xffff}, +{ 0x8D7C, 0x8AA7, 0xffff,0xffff}, +{ 0x8D7E, 0x6D69, 0xffff,0xffff}, +{ 0x8D80, 0x7B6D, 0xffff,0xffff}, +{ 0x8D82, 0x0B3F, 0xffff,0xffff}, +{ 0x8D84, 0x0012, 0xffff,0xffff}, +{ 0x8D86, 0x7068, 0xffff,0xffff}, +{ 0x8D88, 0x780D, 0xffff,0xffff}, +{ 0x8D8A, 0x2040, 0xffff,0xffff}, +{ 0x8D8C, 0x007C, 0xffff,0xffff}, +{ 0x8D8E, 0x20A8, 0xffff,0xffff}, +{ 0x8D90, 0x0640, 0xffff,0xffff}, +{ 0x8D92, 0x71CF, 0xffff,0xffff}, +{ 0x8D94, 0xFF80, 0xffff,0xffff}, +{ 0x8D96, 0x0158, 0xffff,0xffff}, +{ 0x8D98, 0x8924, 0xffff,0xffff}, +{ 0x8D9A, 0x2532, 0xffff,0xffff}, +{ 0x8D9C, 0x00C0, 0xffff,0xffff}, +{ 0x8D9E, 0xBD61, 0xffff,0xffff}, +{ 0x8DA0, 0x0819, 0xffff,0xffff}, +{ 0x8DA2, 0x0063, 0xffff,0xffff}, +{ 0x8DA4, 0x7DAF, 0xffff,0xffff}, +{ 0x8DA6, 0x76CF, 0xffff,0xffff}, +{ 0x8DA8, 0xFF80, 0xffff,0xffff}, +{ 0x8DAA, 0x0290, 0xffff,0xffff}, +{ 0x8DAC, 0x8EF1, 0xffff,0xffff}, +{ 0x8DAE, 0x2640, 0xffff,0xffff}, +{ 0x8DB0, 0x1601, 0xffff,0xffff}, +{ 0x8DB2, 0x61E9, 0xffff,0xffff}, +{ 0x8DB4, 0x090F, 0xffff,0xffff}, +{ 0x8DB6, 0x0002, 0xffff,0xffff}, +{ 0x8DB8, 0xAAA7, 0xffff,0xffff}, +{ 0x8DBA, 0xBB61, 0xffff,0xffff}, +{ 0x8DBC, 0x7B6D, 0xffff,0xffff}, +{ 0x8DBE, 0x7088, 0xffff,0xffff}, +{ 0x8DC0, 0xF005, 0xffff,0xffff}, +{ 0x8DC2, 0x8E26, 0xffff,0xffff}, +{ 0x8DC4, 0xAAA7, 0xffff,0xffff}, +{ 0x8DC6, 0xB961, 0xffff,0xffff}, +{ 0x8DC8, 0xAE26, 0xffff,0xffff}, +{ 0x8DCA, 0x0B1F, 0xffff,0xffff}, +{ 0x8DCC, 0x0013, 0xffff,0xffff}, +{ 0x8DCE, 0x1A07, 0xffff,0xffff}, +{ 0x8DD0, 0x0182, 0xffff,0xffff}, +{ 0x8DD2, 0xD26B, 0xffff,0xffff}, +{ 0x8DD4, 0x8A20, 0xffff,0xffff}, +{ 0x8DD6, 0x8A61, 0xffff,0xffff}, +{ 0x8DD8, 0xB908, 0xffff,0xffff}, +{ 0x8DDA, 0x7965, 0xffff,0xffff}, +{ 0x8DDC, 0xB9A3, 0xffff,0xffff}, +{ 0x8DDE, 0x2941, 0xffff,0xffff}, +{ 0x8DE0, 0x020C, 0xffff,0xffff}, +{ 0x8DE2, 0xAA80, 0xffff,0xffff}, +{ 0x8DE4, 0xAA21, 0xffff,0xffff}, +{ 0x8DE6, 0x04D1, 0xffff,0xffff}, +{ 0x8DE8, 0x0684, 0xffff,0xffff}, +{ 0x8DEA, 0x78E0, 0xffff,0xffff}, +{ 0x8DEC, 0xC0F1, 0xffff,0xffff}, +{ 0x8DEE, 0xC5E1, 0xffff,0xffff}, +{ 0x8DF0, 0xD363, 0xffff,0xffff}, +{ 0x8DF2, 0x8B24, 0xffff,0xffff}, +{ 0x8DF4, 0x8B45, 0xffff,0xffff}, +{ 0x8DF6, 0xB908, 0xffff,0xffff}, +{ 0x8DF8, 0x7945, 0xffff,0xffff}, +{ 0x8DFA, 0xE188, 0xffff,0xffff}, +{ 0x8DFC, 0x21CC, 0xffff,0xffff}, +{ 0x8DFE, 0x8422, 0xffff,0xffff}, +{ 0x8E00, 0xF41F, 0xffff,0xffff}, +{ 0x8E02, 0x8B26, 0xffff,0xffff}, +{ 0x8E04, 0x093B, 0xffff,0xffff}, +{ 0x8E06, 0x0051, 0xffff,0xffff}, +{ 0x8E08, 0xD15C, 0xffff,0xffff}, +{ 0x8E0A, 0xD80A, 0xffff,0xffff}, +{ 0x8E0C, 0xA90E, 0xffff,0xffff}, +{ 0x8E0E, 0xD05D, 0xffff,0xffff}, +{ 0x8E10, 0x8804, 0xffff,0xffff}, +{ 0x8E12, 0x1330, 0xffff,0xffff}, +{ 0x8E14, 0x0082, 0xffff,0xffff}, +{ 0x8E16, 0x1331, 0xffff,0xffff}, +{ 0x8E18, 0x008D, 0xffff,0xffff}, +{ 0x8E1A, 0xBA08, 0xffff,0xffff}, +{ 0x8E1C, 0x7AA5, 0xffff,0xffff}, +{ 0x8E1E, 0xB148, 0xffff,0xffff}, +{ 0x8E20, 0x8952, 0xffff,0xffff}, +{ 0x8E22, 0xA90F, 0xffff,0xffff}, +{ 0x8E24, 0x0813, 0xffff,0xffff}, +{ 0x8E26, 0x00A2, 0xffff,0xffff}, +{ 0x8E28, 0x132C, 0xffff,0xffff}, +{ 0x8E2A, 0x0083, 0xffff,0xffff}, +{ 0x8E2C, 0xDA00, 0xffff,0xffff}, +{ 0x8E2E, 0xA953, 0xffff,0xffff}, +{ 0x8E30, 0x7862, 0xffff,0xffff}, +{ 0x8E32, 0x780F, 0xffff,0xffff}, +{ 0x8E34, 0xF005, 0xffff,0xffff}, +{ 0x8E36, 0xDA01, 0xffff,0xffff}, +{ 0x8E38, 0xA953, 0xffff,0xffff}, +{ 0x8E3A, 0x6078, 0xffff,0xffff}, +{ 0x8E3C, 0x780F, 0xffff,0xffff}, +{ 0x8E3E, 0x080E, 0xffff,0xffff}, +{ 0x8E40, 0x0000, 0xffff,0xffff}, +{ 0x8E42, 0x0485, 0xffff,0xffff}, +{ 0x8E44, 0x0684, 0xffff,0xffff}, +{ 0x8E46, 0x78E0, 0xffff,0xffff}, +{ 0x8E48, 0xC0F1, 0xffff,0xffff}, +{ 0x8E4A, 0x0BFE, 0xffff,0xffff}, +{ 0x8E4C, 0x0684, 0xffff,0xffff}, +{ 0x8E4E, 0xD64D, 0xffff,0xffff}, +{ 0x8E50, 0x7508, 0xffff,0xffff}, +{ 0x8E52, 0x8E01, 0xffff,0xffff}, +{ 0x8E54, 0xD14A, 0xffff,0xffff}, +{ 0x8E56, 0x2046, 0xffff,0xffff}, +{ 0x8E58, 0x00C0, 0xffff,0xffff}, +{ 0x8E5A, 0xAE01, 0xffff,0xffff}, +{ 0x8E5C, 0x1145, 0xffff,0xffff}, +{ 0x8E5E, 0x0080, 0xffff,0xffff}, +{ 0x8E60, 0x1146, 0xffff,0xffff}, +{ 0x8E62, 0x0082, 0xffff,0xffff}, +{ 0x8E64, 0xB808, 0xffff,0xffff}, +{ 0x8E66, 0x7845, 0xffff,0xffff}, +{ 0x8E68, 0x0817, 0xffff,0xffff}, +{ 0x8E6A, 0x001E, 0xffff,0xffff}, +{ 0x8E6C, 0x8900, 0xffff,0xffff}, +{ 0x8E6E, 0x8941, 0xffff,0xffff}, +{ 0x8E70, 0xB808, 0xffff,0xffff}, +{ 0x8E72, 0x7845, 0xffff,0xffff}, +{ 0x8E74, 0x080B, 0xffff,0xffff}, +{ 0x8E76, 0x00DE, 0xffff,0xffff}, +{ 0x8E78, 0x70A9, 0xffff,0xffff}, +{ 0x8E7A, 0xFFBA, 0xffff,0xffff}, +{ 0x8E7C, 0x7508, 0xffff,0xffff}, +{ 0x8E7E, 0x1604, 0xffff,0xffff}, +{ 0x8E80, 0x1090, 0xffff,0xffff}, +{ 0x8E82, 0x0D93, 0xffff,0xffff}, +{ 0x8E84, 0x1400, 0xffff,0xffff}, +{ 0x8E86, 0x8EEA, 0xffff,0xffff}, +{ 0x8E88, 0x8E0B, 0xffff,0xffff}, +{ 0x8E8A, 0x214A, 0xffff,0xffff}, +{ 0x8E8C, 0x2040, 0xffff,0xffff}, +{ 0x8E8E, 0x8E2D, 0xffff,0xffff}, +{ 0x8E90, 0xBF08, 0xffff,0xffff}, +{ 0x8E92, 0x7F05, 0xffff,0xffff}, +{ 0x8E94, 0x8E0C, 0xffff,0xffff}, +{ 0x8E96, 0xB808, 0xffff,0xffff}, +{ 0x8E98, 0x7825, 0xffff,0xffff}, +{ 0x8E9A, 0x7710, 0xffff,0xffff}, +{ 0x8E9C, 0x21C2, 0xffff,0xffff}, +{ 0x8E9E, 0x244C, 0xffff,0xffff}, +{ 0x8EA0, 0x081D, 0xffff,0xffff}, +{ 0x8EA2, 0x03E3, 0xffff,0xffff}, +{ 0x8EA4, 0xD9FF, 0xffff,0xffff}, +{ 0x8EA6, 0x2702, 0xffff,0xffff}, +{ 0x8EA8, 0x1002, 0xffff,0xffff}, +{ 0x8EAA, 0x2A05, 0xffff,0xffff}, +{ 0x8EAC, 0x037E, 0xffff,0xffff}, +{ 0x8EAE, 0x0C7A, 0xffff,0xffff}, +{ 0x8EB0, 0x06A4, 0xffff,0xffff}, +{ 0x8EB2, 0x702F, 0xffff,0xffff}, +{ 0x8EB4, 0x7810, 0xffff,0xffff}, +{ 0x8EB6, 0x7F02, 0xffff,0xffff}, +{ 0x8EB8, 0x7FF0, 0xffff,0xffff}, +{ 0x8EBA, 0xF00B, 0xffff,0xffff}, +{ 0x8EBC, 0x78E2, 0xffff,0xffff}, +{ 0x8EBE, 0x2805, 0xffff,0xffff}, +{ 0x8EC0, 0x037E, 0xffff,0xffff}, +{ 0x8EC2, 0x0C66, 0xffff,0xffff}, +{ 0x8EC4, 0x06A4, 0xffff,0xffff}, +{ 0x8EC6, 0x702F, 0xffff,0xffff}, +{ 0x8EC8, 0x7810, 0xffff,0xffff}, +{ 0x8ECA, 0x671F, 0xffff,0xffff}, +{ 0x8ECC, 0x7FF0, 0xffff,0xffff}, +{ 0x8ECE, 0x7FEF, 0xffff,0xffff}, +{ 0x8ED0, 0x8E08, 0xffff,0xffff}, +{ 0x8ED2, 0xBF06, 0xffff,0xffff}, +{ 0x8ED4, 0xD12C, 0xffff,0xffff}, +{ 0x8ED6, 0xB8C3, 0xffff,0xffff}, +{ 0x8ED8, 0x78E5, 0xffff,0xffff}, +{ 0x8EDA, 0xB88F, 0xffff,0xffff}, +{ 0x8EDC, 0x1908, 0xffff,0xffff}, +{ 0x8EDE, 0x0024, 0xffff,0xffff}, +{ 0x8EE0, 0x2841, 0xffff,0xffff}, +{ 0x8EE2, 0x0201, 0xffff,0xffff}, +{ 0x8EE4, 0x1E26, 0xffff,0xffff}, +{ 0x8EE6, 0x1042, 0xffff,0xffff}, +{ 0x8EE8, 0x0D15, 0xffff,0xffff}, +{ 0x8EEA, 0x1423, 0xffff,0xffff}, +{ 0x8EEC, 0x1E27, 0xffff,0xffff}, +{ 0x8EEE, 0x1002, 0xffff,0xffff}, +{ 0x8EF0, 0x214C, 0xffff,0xffff}, +{ 0x8EF2, 0xA000, 0xffff,0xffff}, +{ 0x8EF4, 0x214A, 0xffff,0xffff}, +{ 0x8EF6, 0x2040, 0xffff,0xffff}, +{ 0x8EF8, 0x21C2, 0xffff,0xffff}, +{ 0x8EFA, 0x2442, 0xffff,0xffff}, +{ 0x8EFC, 0x8E21, 0xffff,0xffff}, +{ 0x8EFE, 0x214F, 0xffff,0xffff}, +{ 0x8F00, 0x0040, 0xffff,0xffff}, +{ 0x8F02, 0x090F, 0xffff,0xffff}, +{ 0x8F04, 0x2010, 0xffff,0xffff}, +{ 0x8F06, 0x2145, 0xffff,0xffff}, +{ 0x8F08, 0x0181, 0xffff,0xffff}, +{ 0x8F0A, 0xAE21, 0xffff,0xffff}, +{ 0x8F0C, 0xF003, 0xffff,0xffff}, +{ 0x8F0E, 0xB8A2, 0xffff,0xffff}, +{ 0x8F10, 0xAE01, 0xffff,0xffff}, +{ 0x8F12, 0x0FFE, 0xffff,0xffff}, +{ 0x8F14, 0xFFA3, 0xffff,0xffff}, +{ 0x8F16, 0x70A9, 0xffff,0xffff}, +{ 0x8F18, 0x038D, 0xffff,0xffff}, +{ 0x8F1A, 0x0684, 0xffff,0xffff}, +{ 0x8F1C, 0xC0F1, 0xffff,0xffff}, +{ 0x8F1E, 0xC5E1, 0xffff,0xffff}, +{ 0x8F20, 0xD518, 0xffff,0xffff}, +{ 0x8F22, 0x8D00, 0xffff,0xffff}, +{ 0x8F24, 0xB8E7, 0xffff,0xffff}, +{ 0x8F26, 0x20D1, 0xffff,0xffff}, +{ 0x8F28, 0x80E2, 0xffff,0xffff}, +{ 0x8F2A, 0xF20D, 0xffff,0xffff}, +{ 0x8F2C, 0xD117, 0xffff,0xffff}, +{ 0x8F2E, 0xB8A7, 0xffff,0xffff}, +{ 0x8F30, 0xAD00, 0xffff,0xffff}, +{ 0x8F32, 0xD017, 0xffff,0xffff}, +{ 0x8F34, 0x7228, 0xffff,0xffff}, +{ 0x8F36, 0x8123, 0xffff,0xffff}, +{ 0x8F38, 0xA040, 0xffff,0xffff}, +{ 0x8F3A, 0x7960, 0xffff,0xffff}, +{ 0x8F3C, 0xD801, 0xffff,0xffff}, +{ 0x8F3E, 0xD800, 0xffff,0xffff}, +{ 0x8F40, 0xAD05, 0xffff,0xffff}, +{ 0x8F42, 0x0F56, 0xffff,0xffff}, +{ 0x8F44, 0xFF83, 0xffff,0xffff}, +{ 0x8F46, 0x0381, 0xffff,0xffff}, +{ 0x8F48, 0x0684, 0xffff,0xffff}, +{ 0x8F4A, 0x78E0, 0xffff,0xffff}, +{ 0x8F4C, 0xD20D, 0xffff,0xffff}, +{ 0x8F4E, 0x8A21, 0xffff,0xffff}, +{ 0x8F50, 0xB9A1, 0xffff,0xffff}, +{ 0x8F52, 0x782F, 0xffff,0xffff}, +{ 0x8F54, 0x7FE0, 0xffff,0xffff}, +{ 0x8F56, 0xAA21, 0xffff,0xffff}, +{ 0x8F58, 0xD00E, 0xffff,0xffff}, +{ 0x8F5A, 0xD10C, 0xffff,0xffff}, +{ 0x8F5C, 0xA100, 0xffff,0xffff}, +{ 0x8F5E, 0xD00E, 0xffff,0xffff}, +{ 0x8F60, 0xA101, 0xffff,0xffff}, +{ 0x8F62, 0xD00E, 0xffff,0xffff}, +{ 0x8F64, 0xA102, 0xffff,0xffff}, +{ 0x8F66, 0xD00E, 0xffff,0xffff}, +{ 0x8F68, 0xA103, 0xffff,0xffff}, +{ 0x8F6A, 0xD009, 0xffff,0xffff}, +{ 0x8F6C, 0xA020, 0xffff,0xffff}, +{ 0x8F6E, 0xD005, 0xffff,0xffff}, +{ 0x8F70, 0xD988, 0xffff,0xffff}, +{ 0x8F72, 0xA820, 0xffff,0xffff}, +{ 0x8F74, 0xF1D4, 0xffff,0xffff}, +{ 0x8F76, 0x78E0, 0xffff,0xffff}, +{ 0x8F78, 0xFF80, 0xffff,0xffff}, +{ 0x8F7A, 0x10C8, 0xffff,0xffff}, +{ 0x8F7C, 0xFF80, 0xffff,0xffff}, +{ 0x8F7E, 0x0290, 0xffff,0xffff}, +{ 0x8F80, 0xFF80, 0xffff,0xffff}, +{ 0x8F82, 0x0158, 0xffff,0xffff}, +{ 0x8F84, 0xFF00, 0xffff,0xffff}, +{ 0x8F86, 0x0618, 0xffff,0xffff}, +{ 0x8F88, 0xFF80, 0xffff,0xffff}, +{ 0x8F8A, 0x1158, 0xffff,0xffff}, +{ 0x8F8C, 0x8000, 0xffff,0xffff}, +{ 0x8F8E, 0x0008, 0xffff,0xffff}, +{ 0x8F90, 0xFF80, 0xffff,0xffff}, +{ 0x8F92, 0x0F1C, 0xffff,0xffff}, +{ 0x8F94, 0xFF80, 0xffff,0xffff}, +{ 0x8F96, 0x0DEC, 0xffff,0xffff}, +{ 0x8F98, 0xFF80, 0xffff,0xffff}, +{ 0x8F9A, 0x0F4C, 0xffff,0xffff}, +{ 0x8F9C, 0x0000, 0xffff,0xffff}, +{ 0x8F9E, 0x0998, 0xffff,0xffff}, +{ 0x8FA0, 0xC0F1, 0xffff,0xffff}, +{ 0x8FA2, 0xC5E1, 0xffff,0xffff}, +{ 0x8FA4, 0xD02C, 0xffff,0xffff}, +{ 0x8FA6, 0x0982, 0xffff,0xffff}, +{ 0x8FA8, 0x0664, 0xffff,0xffff}, +{ 0x8FAA, 0x88AE, 0xffff,0xffff}, +{ 0x8FAC, 0x0D23, 0xffff,0xffff}, +{ 0x8FAE, 0x1051, 0xffff,0xffff}, +{ 0x8FB0, 0xD12A, 0xffff,0xffff}, +{ 0x8FB2, 0x1145, 0xffff,0xffff}, +{ 0x8FB4, 0x0080, 0xffff,0xffff}, +{ 0x8FB6, 0x1146, 0xffff,0xffff}, +{ 0x8FB8, 0x0082, 0xffff,0xffff}, +{ 0x8FBA, 0xB808, 0xffff,0xffff}, +{ 0x8FBC, 0x7845, 0xffff,0xffff}, +{ 0x8FBE, 0x0813, 0xffff,0xffff}, +{ 0x8FC0, 0x00DE, 0xffff,0xffff}, +{ 0x8FC2, 0xD027, 0xffff,0xffff}, +{ 0x8FC4, 0x8000, 0xffff,0xffff}, +{ 0x8FC6, 0x8041, 0xffff,0xffff}, +{ 0x8FC8, 0x7A60, 0xffff,0xffff}, +{ 0x8FCA, 0x1150, 0xffff,0xffff}, +{ 0x8FCC, 0x0080, 0xffff,0xffff}, +{ 0x8FCE, 0x02F9, 0xffff,0xffff}, +{ 0x8FD0, 0x0684, 0xffff,0xffff}, +{ 0x8FD2, 0x78E0, 0xffff,0xffff}, +{ 0x8FD4, 0xC0F1, 0xffff,0xffff}, +{ 0x8FD6, 0x0A7E, 0xffff,0xffff}, +{ 0x8FD8, 0x0684, 0xffff,0xffff}, +{ 0x8FDA, 0xD622, 0xffff,0xffff}, +{ 0x8FDC, 0x8EA9, 0xffff,0xffff}, +{ 0x8FDE, 0x8E2A, 0xffff,0xffff}, +{ 0x8FE0, 0xBD08, 0xffff,0xffff}, +{ 0x8FE2, 0x7D25, 0xffff,0xffff}, +{ 0x8FE4, 0x2550, 0xffff,0xffff}, +{ 0x8FE6, 0x10C2, 0xffff,0xffff}, +{ 0x8FE8, 0x2A41, 0xffff,0xffff}, +{ 0x8FEA, 0x0201, 0xffff,0xffff}, +{ 0x8FEC, 0xAE29, 0xffff,0xffff}, +{ 0x8FEE, 0x0F9A, 0xffff,0xffff}, +{ 0x8FF0, 0x05A4, 0xffff,0xffff}, +{ 0x8FF2, 0xAE4A, 0xffff,0xffff}, +{ 0x8FF4, 0x0D17, 0xffff,0xffff}, +{ 0x8FF6, 0x10DE, 0xffff,0xffff}, +{ 0x8FF8, 0x8E09, 0xffff,0xffff}, +{ 0x8FFA, 0x8E2A, 0xffff,0xffff}, +{ 0x8FFC, 0xB808, 0xffff,0xffff}, +{ 0x8FFE, 0x7825, 0xffff,0xffff}, +{ 0x9000, 0xB883, 0xffff,0xffff}, +{ 0x9002, 0x2841, 0xffff,0xffff}, +{ 0x9004, 0x0201, 0xffff,0xffff}, +{ 0x9006, 0xAE29, 0xffff,0xffff}, +{ 0x9008, 0xAE0A, 0xffff,0xffff}, +{ 0x900A, 0x02B5, 0xffff,0xffff}, +{ 0x900C, 0x0684, 0xffff,0xffff}, +{ 0x900E, 0x78E0, 0xffff,0xffff}, +{ 0x9010, 0xC0F1, 0xffff,0xffff}, +{ 0x9012, 0x0A42, 0xffff,0xffff}, +{ 0x9014, 0x06A4, 0xffff,0xffff}, +{ 0x9016, 0xDA34, 0xffff,0xffff}, +{ 0x9018, 0xD113, 0xffff,0xffff}, +{ 0x901A, 0xD514, 0xffff,0xffff}, +{ 0x901C, 0x76A9, 0xffff,0xffff}, +{ 0x901E, 0x0FD6, 0xffff,0xffff}, +{ 0x9020, 0x0664, 0xffff,0xffff}, +{ 0x9022, 0x70C9, 0xffff,0xffff}, +{ 0x9024, 0xD012, 0xffff,0xffff}, +{ 0x9026, 0xA504, 0xffff,0xffff}, +{ 0x9028, 0xD012, 0xffff,0xffff}, +{ 0x902A, 0x0295, 0xffff,0xffff}, +{ 0x902C, 0x06A4, 0xffff,0xffff}, +{ 0x902E, 0xA0C0, 0xffff,0xffff}, +{ 0x9030, 0xC0F1, 0xffff,0xffff}, +{ 0x9032, 0xC5E1, 0xffff,0xffff}, +{ 0x9034, 0xD50D, 0xffff,0xffff}, +{ 0x9036, 0xD110, 0xffff,0xffff}, +{ 0x9038, 0x2540, 0xffff,0xffff}, +{ 0x903A, 0x1D00, 0xffff,0xffff}, +{ 0x903C, 0x0FB6, 0xffff,0xffff}, +{ 0x903E, 0x0664, 0xffff,0xffff}, +{ 0x9040, 0xDA50, 0xffff,0xffff}, +{ 0x9042, 0xD00E, 0xffff,0xffff}, +{ 0x9044, 0x2540, 0xffff,0xffff}, +{ 0x9046, 0x1D01, 0xffff,0xffff}, +{ 0x9048, 0xA517, 0xffff,0xffff}, +{ 0x904A, 0xD00D, 0xffff,0xffff}, +{ 0x904C, 0x0279, 0xffff,0xffff}, +{ 0x904E, 0x06A4, 0xffff,0xffff}, +{ 0x9050, 0xA020, 0xffff,0xffff}, +{ 0x9052, 0x78E0, 0xffff,0xffff}, +{ 0x9054, 0xFF80, 0xffff,0xffff}, +{ 0x9056, 0x07A8, 0xffff,0xffff}, +{ 0x9058, 0xFF80, 0xffff,0xffff}, +{ 0x905A, 0x0290, 0xffff,0xffff}, +{ 0x905C, 0x8000, 0xffff,0xffff}, +{ 0x905E, 0x0008, 0xffff,0xffff}, +{ 0x9060, 0xFF80, 0xffff,0xffff}, +{ 0x9062, 0x02CC, 0xffff,0xffff}, +{ 0x9064, 0x0000, 0xffff,0xffff}, +{ 0x9066, 0xFA88, 0xffff,0xffff}, +{ 0x9068, 0xFF80, 0xffff,0xffff}, +{ 0x906A, 0x1168, 0xffff,0xffff}, +{ 0x906C, 0xFF80, 0xffff,0xffff}, +{ 0x906E, 0x0FD4, 0xffff,0xffff}, +{ 0x9070, 0x8000, 0xffff,0xffff}, +{ 0x9072, 0x0194, 0xffff,0xffff}, +{ 0x9074, 0x0000, 0xffff,0xffff}, +{ 0x9076, 0xFB08, 0xffff,0xffff}, +{ 0x9078, 0xFF80, 0xffff,0xffff}, +{ 0x907A, 0x0FA0, 0xffff,0xffff}, +{ 0x907C, 0x8000, 0xffff,0xffff}, +{ 0x907E, 0x01A0, 0xffff,0xffff}, +{ 0x9080, 0xE280, 0xffff,0xffff}, +{ 0x9082, 0x24CA, 0xffff,0xffff}, +{ 0x9084, 0x7082, 0xffff,0xffff}, +{ 0x9086, 0x78E0, 0xffff,0xffff}, +{ 0x9088, 0x20E8, 0xffff,0xffff}, +{ 0x908A, 0x01A2, 0xffff,0xffff}, +{ 0x908C, 0x1002, 0xffff,0xffff}, +{ 0x908E, 0x0D02, 0xffff,0xffff}, +{ 0x9090, 0x1902, 0xffff,0xffff}, +{ 0x9092, 0x0094, 0xffff,0xffff}, +{ 0x9094, 0x7FE0, 0xffff,0xffff}, +{ 0x9096, 0x7028, 0xffff,0xffff}, +{ 0x9098, 0x7308, 0xffff,0xffff}, +{ 0x909A, 0x1000, 0xffff,0xffff}, +{ 0x909C, 0x0900, 0xffff,0xffff}, +{ 0x909E, 0x7904, 0xffff,0xffff}, +{ 0x90A0, 0x7947, 0xffff,0xffff}, +{ 0x90A2, 0x1B00, 0xffff,0xffff}, +{ 0x90A4, 0x0064, 0xffff,0xffff}, +{ 0x90A6, 0x7EE0, 0xffff,0xffff}, +{ 0x90A8, 0xE280, 0xffff,0xffff}, +{ 0x90AA, 0x24CA, 0xffff,0xffff}, +{ 0x90AC, 0x7082, 0xffff,0xffff}, +{ 0x90AE, 0x78E0, 0xffff,0xffff}, +{ 0x90B0, 0x20E8, 0xffff,0xffff}, +{ 0x90B2, 0x01A2, 0xffff,0xffff}, +{ 0x90B4, 0x1102, 0xffff,0xffff}, +{ 0x90B6, 0x0502, 0xffff,0xffff}, +{ 0x90B8, 0x1802, 0xffff,0xffff}, +{ 0x90BA, 0x00B4, 0xffff,0xffff}, +{ 0x90BC, 0x7FE0, 0xffff,0xffff}, +{ 0x90BE, 0x7028, 0xffff,0xffff}, +{ 0x90C0, 0x0000, 0xffff,0xffff}, +{ 0x90C2, 0x0000, 0xffff,0xffff}, +{ 0x90C4, 0x0000, 0xffff,0xffff}, +{ 0x90C6, 0x0000, 0xffff,0xffff}, +{ 0x098E, 0x0000, 0xffff,0xffff}, // LOGICAL_ADDRESS_ACCESS +{ 0x8016, 0x086C, 0xffff,0xffff}, // MON_ADDRESS_LO +{ 0x8018, 0xFF80, 0xffff,0xffff}, // MON_ADDRESS_HI +{ 0x8002, 0x0001, 0xffff,0xffff}, // MON_CMD //delay = 100 -{ SEQUENCE_WAIT_MS,100, BYTE_LEN, 0}, - +SensorWaitMs(100), //[Lens Correction 90% 02/04/13 18:03:18] //BITFIELD= 0x3210, 0x0008, 0 //PGA_ENABLE -{ 0x3210, 0x0008, WORD_LEN, 0}, -{ 0x3210, 0x49B0, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL -{ 0x3640, 0x0170, WORD_LEN, 0}, // P_G1_P0Q0 -{ 0x3642, 0x0BCC, WORD_LEN, 0}, // P_G1_P0Q1 -{ 0x3644, 0x7210, WORD_LEN, 0}, // P_G1_P0Q2 -{ 0x3646, 0x4C8D, WORD_LEN, 0}, // P_G1_P0Q3 -{ 0x3648, 0xF58D, WORD_LEN, 0}, // P_G1_P0Q4 -{ 0x364A, 0x0610, WORD_LEN, 0}, // P_R_P0Q0 -{ 0x364C, 0x8D6E, WORD_LEN, 0}, // P_R_P0Q1 -{ 0x364E, 0x6E90, WORD_LEN, 0}, // P_R_P0Q2 -{ 0x3650, 0x088F, WORD_LEN, 0}, // P_R_P0Q3 -{ 0x3652, 0xA890, WORD_LEN, 0}, // P_R_P0Q4 -{ 0x3654, 0x0550, WORD_LEN, 0}, // P_B_P0Q0 -{ 0x3656, 0x764C, WORD_LEN, 0}, // P_B_P0Q1 -{ 0x3658, 0x0FB0, WORD_LEN, 0}, // P_B_P0Q2 -{ 0x365A, 0x9A0D, WORD_LEN, 0}, // P_B_P0Q3 -{ 0x365C, 0xF4AD, WORD_LEN, 0}, // P_B_P0Q4 -{ 0x365E, 0x02F0, WORD_LEN, 0}, // P_G2_P0Q0 -{ 0x3660, 0x9A0E, WORD_LEN, 0}, // P_G2_P0Q1 -{ 0x3662, 0x77B0, WORD_LEN, 0}, // P_G2_P0Q2 -{ 0x3664, 0x416D, WORD_LEN, 0}, // P_G2_P0Q3 -{ 0x3666, 0xF24D, WORD_LEN, 0}, // P_G2_P0Q4 -{ 0x3680, 0x018A, WORD_LEN, 0}, // P_G1_P1Q0 -{ 0x3682, 0xD0AD, WORD_LEN, 0}, // P_G1_P1Q1 -{ 0x3684, 0xC62E, WORD_LEN, 0}, // P_G1_P1Q2 -{ 0x3686, 0x736D, WORD_LEN, 0}, // P_G1_P1Q3 -{ 0x3688, 0x0130, WORD_LEN, 0}, // P_G1_P1Q4 -{ 0x368A, 0x52ED, WORD_LEN, 0}, // P_R_P1Q0 -{ 0x368C, 0x682D, WORD_LEN, 0}, // P_R_P1Q1 -{ 0x368E, 0xF02B, WORD_LEN, 0}, // P_R_P1Q2 -{ 0x3690, 0xB68E, WORD_LEN, 0}, // P_R_P1Q3 -{ 0x3692, 0xF4AD, WORD_LEN, 0}, // P_R_P1Q4 -{ 0x3694, 0xC68D, WORD_LEN, 0}, // P_B_P1Q0 -{ 0x3696, 0x440D, WORD_LEN, 0}, // P_B_P1Q1 -{ 0x3698, 0x416E, WORD_LEN, 0}, // P_B_P1Q2 -{ 0x369A, 0xC0CE, WORD_LEN, 0}, // P_B_P1Q3 -{ 0x369C, 0xB46D, WORD_LEN, 0}, // P_B_P1Q4 -{ 0x369E, 0xD90A, WORD_LEN, 0}, // P_G2_P1Q0 -{ 0x36A0, 0xD76D, WORD_LEN, 0}, // P_G2_P1Q1 -{ 0x36A2, 0xFE0D, WORD_LEN, 0}, // P_G2_P1Q2 -{ 0x36A4, 0x0E0D, WORD_LEN, 0}, // P_G2_P1Q3 -{ 0x36A6, 0x0890, WORD_LEN, 0}, // P_G2_P1Q4 -{ 0x36C0, 0x70D0, WORD_LEN, 0}, // P_G1_P2Q0 -{ 0x36C2, 0x10CF, WORD_LEN, 0}, // P_G1_P2Q1 -{ 0x36C4, 0x4592, WORD_LEN, 0}, // P_G1_P2Q2 -{ 0x36C6, 0xB74D, WORD_LEN, 0}, // P_G1_P2Q3 -{ 0x36C8, 0xEEB3, WORD_LEN, 0}, // P_G1_P2Q4 -{ 0x36CA, 0x1991, WORD_LEN, 0}, // P_R_P2Q0 -{ 0x36CC, 0x9B8E, WORD_LEN, 0}, // P_R_P2Q1 -{ 0x36CE, 0x5DCD, WORD_LEN, 0}, // P_R_P2Q2 -{ 0x36D0, 0x1C8D, WORD_LEN, 0}, // P_R_P2Q3 -{ 0x36D2, 0x8C71, WORD_LEN, 0}, // P_R_P2Q4 -{ 0x36D4, 0x00F1, WORD_LEN, 0}, // P_B_P2Q0 -{ 0x36D6, 0x480F, WORD_LEN, 0}, // P_B_P2Q1 -{ 0x36D8, 0x26AF, WORD_LEN, 0}, // P_B_P2Q2 -{ 0x36DA, 0xC2EF, WORD_LEN, 0}, // P_B_P2Q3 -{ 0x36DC, 0xFC8F, WORD_LEN, 0}, // P_B_P2Q4 -{ 0x36DE, 0x0071, WORD_LEN, 0}, // P_G2_P2Q0 -{ 0x36E0, 0x8230, WORD_LEN, 0}, // P_G2_P2Q1 -{ 0x36E2, 0x60B2, WORD_LEN, 0}, // P_G2_P2Q2 -{ 0x36E4, 0x3E51, WORD_LEN, 0}, // P_G2_P2Q3 -{ 0x36E6, 0x8C74, WORD_LEN, 0}, // P_G2_P2Q4 -{ 0x3700, 0x492E, WORD_LEN, 0}, // P_G1_P3Q0 -{ 0x3702, 0x7FAD, WORD_LEN, 0}, // P_G1_P3Q1 -{ 0x3704, 0x93CE, WORD_LEN, 0}, // P_G1_P3Q2 -{ 0x3706, 0xC86F, WORD_LEN, 0}, // P_G1_P3Q3 -{ 0x3708, 0xC830, WORD_LEN, 0}, // P_G1_P3Q4 -{ 0x370A, 0x610E, WORD_LEN, 0}, // P_R_P3Q0 -{ 0x370C, 0x8EC8, WORD_LEN, 0}, // P_R_P3Q1 -{ 0x370E, 0xA930, WORD_LEN, 0}, // P_R_P3Q2 -{ 0x3710, 0xE88D, WORD_LEN, 0}, // P_R_P3Q3 -{ 0x3712, 0x2B51, WORD_LEN, 0}, // P_R_P3Q4 -{ 0x3714, 0xDECD, WORD_LEN, 0}, // P_B_P3Q0 -{ 0x3716, 0xBD8E, WORD_LEN, 0}, // P_B_P3Q1 -{ 0x3718, 0x2E50, WORD_LEN, 0}, // P_B_P3Q2 -{ 0x371A, 0x60AF, WORD_LEN, 0}, // P_B_P3Q3 -{ 0x371C, 0xBB11, WORD_LEN, 0}, // P_B_P3Q4 -{ 0x371E, 0x22CB, WORD_LEN, 0}, // P_G2_P3Q0 -{ 0x3720, 0xEEEC, WORD_LEN, 0}, // P_G2_P3Q1 -{ 0x3722, 0x0251, WORD_LEN, 0}, // P_G2_P3Q2 -{ 0x3724, 0x142D, WORD_LEN, 0}, // P_G2_P3Q3 -{ 0x3726, 0xE271, WORD_LEN, 0}, // P_G2_P3Q4 -{ 0x3740, 0x1D10, WORD_LEN, 0}, // P_G1_P4Q0 -{ 0x3742, 0xE94F, WORD_LEN, 0}, // P_G1_P4Q1 -{ 0x3744, 0x8735, WORD_LEN, 0}, // P_G1_P4Q2 -{ 0x3746, 0xC2CC, WORD_LEN, 0}, // P_G1_P4Q3 -{ 0x3748, 0x23F6, WORD_LEN, 0}, // P_G1_P4Q4 -{ 0x374A, 0xE90F, WORD_LEN, 0}, // P_R_P4Q0 -{ 0x374C, 0x1A30, WORD_LEN, 0}, // P_R_P4Q1 -{ 0x374E, 0xAEF3, WORD_LEN, 0}, // P_R_P4Q2 -{ 0x3750, 0xB2F2, WORD_LEN, 0}, // P_R_P4Q3 -{ 0x3752, 0x2195, WORD_LEN, 0}, // P_R_P4Q4 -{ 0x3754, 0xFFEE, WORD_LEN, 0}, // P_B_P4Q0 -{ 0x3756, 0xD8D0, WORD_LEN, 0}, // P_B_P4Q1 -{ 0x3758, 0xCC92, WORD_LEN, 0}, // P_B_P4Q2 -{ 0x375A, 0x0451, WORD_LEN, 0}, // P_B_P4Q3 -{ 0x375C, 0x5814, WORD_LEN, 0}, // P_B_P4Q4 -{ 0x375E, 0x2470, WORD_LEN, 0}, // P_G2_P4Q0 -{ 0x3760, 0x6151, WORD_LEN, 0}, // P_G2_P4Q1 -{ 0x3762, 0x9555, WORD_LEN, 0}, // P_G2_P4Q2 -{ 0x3764, 0xD5D3, WORD_LEN, 0}, // P_G2_P4Q3 -{ 0x3766, 0x3B56, WORD_LEN, 0}, // P_G2_P4Q4 -{ 0x3782, 0x03DC, WORD_LEN, 0}, // CENTER_ROW -{ 0x3784, 0x04E0, WORD_LEN, 0}, // CENTER_COLUMN -{ 0x3210, 0x49B8, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL +{ 0x3210, 0x0008, 0xffff,0xffff}, +{ 0x3210, 0x49B0, 0xffff,0xffff}, // COLOR_PIPELINE_CONTROL +{ 0x3640, 0x0170, 0xffff,0xffff}, // P_G1_P0Q0 +{ 0x3642, 0x0BCC, 0xffff,0xffff}, // P_G1_P0Q1 +{ 0x3644, 0x7210, 0xffff,0xffff}, // P_G1_P0Q2 +{ 0x3646, 0x4C8D, 0xffff,0xffff}, // P_G1_P0Q3 +{ 0x3648, 0xF58D, 0xffff,0xffff}, // P_G1_P0Q4 +{ 0x364A, 0x0610, 0xffff,0xffff}, // P_R_P0Q0 +{ 0x364C, 0x8D6E, 0xffff,0xffff}, // P_R_P0Q1 +{ 0x364E, 0x6E90, 0xffff,0xffff}, // P_R_P0Q2 +{ 0x3650, 0x088F, 0xffff,0xffff}, // P_R_P0Q3 +{ 0x3652, 0xA890, 0xffff,0xffff}, // P_R_P0Q4 +{ 0x3654, 0x0550, 0xffff,0xffff}, // P_B_P0Q0 +{ 0x3656, 0x764C, 0xffff,0xffff}, // P_B_P0Q1 +{ 0x3658, 0x0FB0, 0xffff,0xffff}, // P_B_P0Q2 +{ 0x365A, 0x9A0D, 0xffff,0xffff}, // P_B_P0Q3 +{ 0x365C, 0xF4AD, 0xffff,0xffff}, // P_B_P0Q4 +{ 0x365E, 0x02F0, 0xffff,0xffff}, // P_G2_P0Q0 +{ 0x3660, 0x9A0E, 0xffff,0xffff}, // P_G2_P0Q1 +{ 0x3662, 0x77B0, 0xffff,0xffff}, // P_G2_P0Q2 +{ 0x3664, 0x416D, 0xffff,0xffff}, // P_G2_P0Q3 +{ 0x3666, 0xF24D, 0xffff,0xffff}, // P_G2_P0Q4 +{ 0x3680, 0x018A, 0xffff,0xffff}, // P_G1_P1Q0 +{ 0x3682, 0xD0AD, 0xffff,0xffff}, // P_G1_P1Q1 +{ 0x3684, 0xC62E, 0xffff,0xffff}, // P_G1_P1Q2 +{ 0x3686, 0x736D, 0xffff,0xffff}, // P_G1_P1Q3 +{ 0x3688, 0x0130, 0xffff,0xffff}, // P_G1_P1Q4 +{ 0x368A, 0x52ED, 0xffff,0xffff}, // P_R_P1Q0 +{ 0x368C, 0x682D, 0xffff,0xffff}, // P_R_P1Q1 +{ 0x368E, 0xF02B, 0xffff,0xffff}, // P_R_P1Q2 +{ 0x3690, 0xB68E, 0xffff,0xffff}, // P_R_P1Q3 +{ 0x3692, 0xF4AD, 0xffff,0xffff}, // P_R_P1Q4 +{ 0x3694, 0xC68D, 0xffff,0xffff}, // P_B_P1Q0 +{ 0x3696, 0x440D, 0xffff,0xffff}, // P_B_P1Q1 +{ 0x3698, 0x416E, 0xffff,0xffff}, // P_B_P1Q2 +{ 0x369A, 0xC0CE, 0xffff,0xffff}, // P_B_P1Q3 +{ 0x369C, 0xB46D, 0xffff,0xffff}, // P_B_P1Q4 +{ 0x369E, 0xD90A, 0xffff,0xffff}, // P_G2_P1Q0 +{ 0x36A0, 0xD76D, 0xffff,0xffff}, // P_G2_P1Q1 +{ 0x36A2, 0xFE0D, 0xffff,0xffff}, // P_G2_P1Q2 +{ 0x36A4, 0x0E0D, 0xffff,0xffff}, // P_G2_P1Q3 +{ 0x36A6, 0x0890, 0xffff,0xffff}, // P_G2_P1Q4 +{ 0x36C0, 0x70D0, 0xffff,0xffff}, // P_G1_P2Q0 +{ 0x36C2, 0x10CF, 0xffff,0xffff}, // P_G1_P2Q1 +{ 0x36C4, 0x4592, 0xffff,0xffff}, // P_G1_P2Q2 +{ 0x36C6, 0xB74D, 0xffff,0xffff}, // P_G1_P2Q3 +{ 0x36C8, 0xEEB3, 0xffff,0xffff}, // P_G1_P2Q4 +{ 0x36CA, 0x1991, 0xffff,0xffff}, // P_R_P2Q0 +{ 0x36CC, 0x9B8E, 0xffff,0xffff}, // P_R_P2Q1 +{ 0x36CE, 0x5DCD, 0xffff,0xffff}, // P_R_P2Q2 +{ 0x36D0, 0x1C8D, 0xffff,0xffff}, // P_R_P2Q3 +{ 0x36D2, 0x8C71, 0xffff,0xffff}, // P_R_P2Q4 +{ 0x36D4, 0x00F1, 0xffff,0xffff}, // P_B_P2Q0 +{ 0x36D6, 0x480F, 0xffff,0xffff}, // P_B_P2Q1 +{ 0x36D8, 0x26AF, 0xffff,0xffff}, // P_B_P2Q2 +{ 0x36DA, 0xC2EF, 0xffff,0xffff}, // P_B_P2Q3 +{ 0x36DC, 0xFC8F, 0xffff,0xffff}, // P_B_P2Q4 +{ 0x36DE, 0x0071, 0xffff,0xffff}, // P_G2_P2Q0 +{ 0x36E0, 0x8230, 0xffff,0xffff}, // P_G2_P2Q1 +{ 0x36E2, 0x60B2, 0xffff,0xffff}, // P_G2_P2Q2 +{ 0x36E4, 0x3E51, 0xffff,0xffff}, // P_G2_P2Q3 +{ 0x36E6, 0x8C74, 0xffff,0xffff}, // P_G2_P2Q4 +{ 0x3700, 0x492E, 0xffff,0xffff}, // P_G1_P3Q0 +{ 0x3702, 0x7FAD, 0xffff,0xffff}, // P_G1_P3Q1 +{ 0x3704, 0x93CE, 0xffff,0xffff}, // P_G1_P3Q2 +{ 0x3706, 0xC86F, 0xffff,0xffff}, // P_G1_P3Q3 +{ 0x3708, 0xC830, 0xffff,0xffff}, // P_G1_P3Q4 +{ 0x370A, 0x610E, 0xffff,0xffff}, // P_R_P3Q0 +{ 0x370C, 0x8EC8, 0xffff,0xffff}, // P_R_P3Q1 +{ 0x370E, 0xA930, 0xffff,0xffff}, // P_R_P3Q2 +{ 0x3710, 0xE88D, 0xffff,0xffff}, // P_R_P3Q3 +{ 0x3712, 0x2B51, 0xffff,0xffff}, // P_R_P3Q4 +{ 0x3714, 0xDECD, 0xffff,0xffff}, // P_B_P3Q0 +{ 0x3716, 0xBD8E, 0xffff,0xffff}, // P_B_P3Q1 +{ 0x3718, 0x2E50, 0xffff,0xffff}, // P_B_P3Q2 +{ 0x371A, 0x60AF, 0xffff,0xffff}, // P_B_P3Q3 +{ 0x371C, 0xBB11, 0xffff,0xffff}, // P_B_P3Q4 +{ 0x371E, 0x22CB, 0xffff,0xffff}, // P_G2_P3Q0 +{ 0x3720, 0xEEEC, 0xffff,0xffff}, // P_G2_P3Q1 +{ 0x3722, 0x0251, 0xffff,0xffff}, // P_G2_P3Q2 +{ 0x3724, 0x142D, 0xffff,0xffff}, // P_G2_P3Q3 +{ 0x3726, 0xE271, 0xffff,0xffff}, // P_G2_P3Q4 +{ 0x3740, 0x1D10, 0xffff,0xffff}, // P_G1_P4Q0 +{ 0x3742, 0xE94F, 0xffff,0xffff}, // P_G1_P4Q1 +{ 0x3744, 0x8735, 0xffff,0xffff}, // P_G1_P4Q2 +{ 0x3746, 0xC2CC, 0xffff,0xffff}, // P_G1_P4Q3 +{ 0x3748, 0x23F6, 0xffff,0xffff}, // P_G1_P4Q4 +{ 0x374A, 0xE90F, 0xffff,0xffff}, // P_R_P4Q0 +{ 0x374C, 0x1A30, 0xffff,0xffff}, // P_R_P4Q1 +{ 0x374E, 0xAEF3, 0xffff,0xffff}, // P_R_P4Q2 +{ 0x3750, 0xB2F2, 0xffff,0xffff}, // P_R_P4Q3 +{ 0x3752, 0x2195, 0xffff,0xffff}, // P_R_P4Q4 +{ 0x3754, 0xFFEE, 0xffff,0xffff}, // P_B_P4Q0 +{ 0x3756, 0xD8D0, 0xffff,0xffff}, // P_B_P4Q1 +{ 0x3758, 0xCC92, 0xffff,0xffff}, // P_B_P4Q2 +{ 0x375A, 0x0451, 0xffff,0xffff}, // P_B_P4Q3 +{ 0x375C, 0x5814, 0xffff,0xffff}, // P_B_P4Q4 +{ 0x375E, 0x2470, 0xffff,0xffff}, // P_G2_P4Q0 +{ 0x3760, 0x6151, 0xffff,0xffff}, // P_G2_P4Q1 +{ 0x3762, 0x9555, 0xffff,0xffff}, // P_G2_P4Q2 +{ 0x3764, 0xD5D3, 0xffff,0xffff}, // P_G2_P4Q3 +{ 0x3766, 0x3B56, 0xffff,0xffff}, // P_G2_P4Q4 +{ 0x3782, 0x03DC, 0xffff,0xffff}, // CENTER_ROW +{ 0x3784, 0x04E0, 0xffff,0xffff}, // CENTER_COLUMN +{ 0x3210, 0x49B8, 0xffff,0xffff}, // COLOR_PIPELINE_CONTROL //BITFIELD= 0x3210, 0x0008, 1 //PGA_ENABLE -//{ 0x3210, 0x0008, WORD_LEN, 0}, +//{ 0x3210, 0x0008, 0xffff,0xffff}, @@ -1447,4141 +1386,973 @@ static struct reginfo sensor_init_data[] = //[Step6-AWB_CCM] //[AWB_setup] -{ 0xAC01, 0xBB, BYTE_LEN, 0}, // AWB_MODE +{ 0xAC01, 0xBB, 0xffff,0xff}, // AWB_MODE //[CCM] -{ 0xAC46, 0x0221, WORD_LEN, 0}, // AWB_LEFT_CCM_0 -{ 0xAC48, 0xFEAE, WORD_LEN, 0}, // AWB_LEFT_CCM_1 -{ 0xAC4A, 0x0032, WORD_LEN, 0}, // AWB_LEFT_CCM_2 -{ 0xAC4C, 0xFFC5, WORD_LEN, 0}, // AWB_LEFT_CCM_3 -{ 0xAC4E, 0x0154, WORD_LEN, 0}, // AWB_LEFT_CCM_4 -{ 0xAC50, 0xFFE7, WORD_LEN, 0}, // AWB_LEFT_CCM_5 -{ 0xAC52, 0xFFB1, WORD_LEN, 0}, // AWB_LEFT_CCM_6 -{ 0xAC54, 0xFEC5, WORD_LEN, 0}, // AWB_LEFT_CCM_7 -{ 0xAC56, 0x028A, WORD_LEN, 0}, // AWB_LEFT_CCM_8 -{ 0xAC58, 0x00C6, WORD_LEN, 0}, // AWB_LEFT_CCM_R2BRATIO -{ 0xAC5C, 0x01CD, WORD_LEN, 0}, // AWB_RIGHT_CCM_0 -{ 0xAC5E, 0xFF63, WORD_LEN, 0}, // AWB_RIGHT_CCM_1 -{ 0xAC60, 0xFFD0, WORD_LEN, 0}, // AWB_RIGHT_CCM_2 -{ 0xAC62, 0xFFCD, WORD_LEN, 0}, // AWB_RIGHT_CCM_3 -{ 0xAC64, 0x013B, WORD_LEN, 0}, // AWB_RIGHT_CCM_4 -{ 0xAC66, 0xFFF8, WORD_LEN, 0}, // AWB_RIGHT_CCM_5 -{ 0xAC68, 0xFFFB, WORD_LEN, 0}, // AWB_RIGHT_CCM_6 -{ 0xAC6A, 0xFF78, WORD_LEN, 0}, // AWB_RIGHT_CCM_7 -{ 0xAC6C, 0x018D, WORD_LEN, 0}, // AWB_RIGHT_CCM_8 -{ 0xAC6E, 0x0055, WORD_LEN, 0}, // AWB_RIGHT_CCM_R2BRATIO +{ 0xAC46, 0x0221, 0xffff,0xffff}, // AWB_LEFT_CCM_0 +{ 0xAC48, 0xFEAE, 0xffff,0xffff}, // AWB_LEFT_CCM_1 +{ 0xAC4A, 0x0032, 0xffff,0xffff}, // AWB_LEFT_CCM_2 +{ 0xAC4C, 0xFFC5, 0xffff,0xffff}, // AWB_LEFT_CCM_3 +{ 0xAC4E, 0x0154, 0xffff,0xffff}, // AWB_LEFT_CCM_4 +{ 0xAC50, 0xFFE7, 0xffff,0xffff}, // AWB_LEFT_CCM_5 +{ 0xAC52, 0xFFB1, 0xffff,0xffff}, // AWB_LEFT_CCM_6 +{ 0xAC54, 0xFEC5, 0xffff,0xffff}, // AWB_LEFT_CCM_7 +{ 0xAC56, 0x028A, 0xffff,0xffff}, // AWB_LEFT_CCM_8 +{ 0xAC58, 0x00C6, 0xffff,0xffff}, // AWB_LEFT_CCM_R2BRATIO +{ 0xAC5C, 0x01CD, 0xffff,0xffff}, // AWB_RIGHT_CCM_0 +{ 0xAC5E, 0xFF63, 0xffff,0xffff}, // AWB_RIGHT_CCM_1 +{ 0xAC60, 0xFFD0, 0xffff,0xffff}, // AWB_RIGHT_CCM_2 +{ 0xAC62, 0xFFCD, 0xffff,0xffff}, // AWB_RIGHT_CCM_3 +{ 0xAC64, 0x013B, 0xffff,0xffff}, // AWB_RIGHT_CCM_4 +{ 0xAC66, 0xFFF8, 0xffff,0xffff}, // AWB_RIGHT_CCM_5 +{ 0xAC68, 0xFFFB, 0xffff,0xffff}, // AWB_RIGHT_CCM_6 +{ 0xAC6A, 0xFF78, 0xffff,0xffff}, // AWB_RIGHT_CCM_7 +{ 0xAC6C, 0x018D, 0xffff,0xffff}, // AWB_RIGHT_CCM_8 +{ 0xAC6E, 0x0055, 0xffff,0xffff}, // AWB_RIGHT_CCM_R2BRATIO //[AWB] -{ 0xB842, 0x0037, WORD_LEN, 0}, // STAT_AWB_GRAY_CHECKER_OFFSET_X -{ 0xB844, 0x0044, WORD_LEN, 0}, // STAT_AWB_GRAY_CHECKER_OFFSET_Y -{ 0x3240, 0x0024, WORD_LEN, 0}, // AWB_XY_SCALE -{ 0x3240, 0x0024, WORD_LEN, 0}, // AWB_XY_SCALE -{ 0x3242, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R0 -{ 0x3244, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R1 -{ 0x3246, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R2 -{ 0x3248, 0x7F00, WORD_LEN, 0}, // AWB_WEIGHT_R3 -{ 0x324A, 0xA500, WORD_LEN, 0}, // AWB_WEIGHT_R4 -{ 0x324C, 0x1540, WORD_LEN, 0}, // AWB_WEIGHT_R5 -{ 0x324E, 0x01AC, WORD_LEN, 0}, // AWB_WEIGHT_R6 -{ 0x3250, 0x003E, WORD_LEN, 0}, // AWB_WEIGHT_R7 +{ 0xB842, 0x0037, 0xffff,0xffff}, // STAT_AWB_GRAY_CHECKER_OFFSET_X +{ 0xB844, 0x0044, 0xffff,0xffff}, // STAT_AWB_GRAY_CHECKER_OFFSET_Y +{ 0x3240, 0x0024, 0xffff,0xffff}, // AWB_XY_SCALE +{ 0x3240, 0x0024, 0xffff,0xffff}, // AWB_XY_SCALE +{ 0x3242, 0x0000, 0xffff,0xffff}, // AWB_WEIGHT_R0 +{ 0x3244, 0x0000, 0xffff,0xffff}, // AWB_WEIGHT_R1 +{ 0x3246, 0x0000, 0xffff,0xffff}, // AWB_WEIGHT_R2 +{ 0x3248, 0x7F00, 0xffff,0xffff}, // AWB_WEIGHT_R3 +{ 0x324A, 0xA500, 0xffff,0xffff}, // AWB_WEIGHT_R4 +{ 0x324C, 0x1540, 0xffff,0xffff}, // AWB_WEIGHT_R5 +{ 0x324E, 0x01AC, 0xffff,0xffff}, // AWB_WEIGHT_R6 +{ 0x3250, 0x003E, 0xffff,0xffff}, // AWB_WEIGHT_R7 //[Preawb_params] -{ 0xACB0, 0x32, BYTE_LEN, 0}, // AWB_RG_MIN -{ 0xACB1, 0x5A, BYTE_LEN, 0}, // AWB_RG_MAX -{ 0xACB2, 0x32, BYTE_LEN, 0}, // AWB_RG_MIN_BRIGHT -{ 0xACB3, 0x5A, BYTE_LEN, 0}, // AWB_RG_MAX_BRIGHT -{ 0xACB4, 0x23, BYTE_LEN, 0}, // AWB_BG_MIN -{ 0xACB5, 0x55, BYTE_LEN, 0}, // AWB_BG_MAX -{ 0xACB6, 0x49, BYTE_LEN, 0}, // AWB_BG_MIN_BRIGHT -{ 0xACB7, 0x55, BYTE_LEN, 0}, // AWB_BG_MAX_BRIGHT +{ 0xACB0, 0x32, 0xffff,0xff}, // AWB_RG_MIN +{ 0xACB1, 0x5A, 0xffff,0xff}, // AWB_RG_MAX +{ 0xACB2, 0x32, 0xffff,0xff}, // AWB_RG_MIN_BRIGHT +{ 0xACB3, 0x5A, 0xffff,0xff}, // AWB_RG_MAX_BRIGHT +{ 0xACB4, 0x23, 0xffff,0xff}, // AWB_BG_MIN +{ 0xACB5, 0x55, 0xffff,0xff}, // AWB_BG_MAX +{ 0xACB6, 0x49, 0xffff,0xff}, // AWB_BG_MIN_BRIGHT +{ 0xACB7, 0x55, 0xffff,0xff}, // AWB_BG_MAX_BRIGHT //[**********Step7*************] //[Step7-CPIPE_Calibration] //[jpeg_setup] -{ 0xD80F, 0x04, BYTE_LEN, 0}, // JPEG_QSCALE_0 -{ 0xD810, 0x08, BYTE_LEN, 0}, // JPEG_QSCALE_1 -{ 0xC8D2, 0x04, BYTE_LEN, 0}, // CAM_OUTPUT_1_JPEG_QSCALE_0 -{ 0xC8D3, 0x08, BYTE_LEN, 0}, // CAM_OUTPUT_1_JPEG_QSCALE_1 -{ 0xC8BC, 0x04, BYTE_LEN, 0}, // CAM_OUTPUT_0_JPEG_QSCALE_0 -{ 0xC8BD, 0x08, BYTE_LEN, 0}, // CAM_OUTPUT_0_JPEG_QSCALE_1 +{ 0xD80F, 0x04, 0xffff,0xff}, // JPEG_QSCALE_0 +{ 0xD810, 0x08, 0xffff,0xff}, // JPEG_QSCALE_1 +{ 0xC8D2, 0x04, 0xffff,0xff}, // CAM_OUTPUT_1_JPEG_QSCALE_0 +{ 0xC8D3, 0x08, 0xffff,0xff}, // CAM_OUTPUT_1_JPEG_QSCALE_1 +{ 0xC8BC, 0x04, 0xffff,0xff}, // CAM_OUTPUT_0_JPEG_QSCALE_0 +{ 0xC8BD, 0x08, 0xffff,0xff}, // CAM_OUTPUT_0_JPEG_QSCALE_1 //[Sys_Settings] -{ 0xDC35, 0x04, BYTE_LEN, 0}, // SYS_UV_COLOR_BOOST -{ 0x326E, 0x0006, WORD_LEN, 0}, // RESERVED_SOC1_326E -{ 0xDC37, 0x62, BYTE_LEN, 0}, // SYS_BRIGHT_COLORKILL -{ 0x35A4, 0x0596, WORD_LEN, 0}, // BRIGHT_COLOR_KILL_CONTROLS -{ 0x35A2, 0x0094, WORD_LEN, 0}, // DARK_COLOR_KILL_CONTROLS -{ 0xDC36, 0x23, BYTE_LEN, 0}, // SYS_DARK_COLOR_KILL +{ 0xDC35, 0x04, 0xffff,0xff}, // SYS_UV_COLOR_BOOST +{ 0x326E, 0x0006, 0xffff,0xffff}, // RESERVED_SOC1_326E +{ 0xDC37, 0x62, 0xffff,0xff}, // SYS_BRIGHT_COLORKILL +{ 0x35A4, 0x0596, 0xffff,0xffff}, // BRIGHT_COLOR_KILL_CONTROLS +{ 0x35A2, 0x0094, 0xffff,0xffff}, // DARK_COLOR_KILL_CONTROLS +{ 0xDC36, 0x23, 0xffff,0xff}, // SYS_DARK_COLOR_KILL //[Gamma_Curves_REV3] -{ 0xBC18, 0x00, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_0 -{ 0xBC19, 0x11, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_1 -{ 0xBC1A, 0x23, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_2 -{ 0xBC1B, 0x3F, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_3 -{ 0xBC1C, 0x67, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_4 -{ 0xBC1D, 0x85, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_5 -{ 0xBC1E, 0x9B, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_6 -{ 0xBC1F, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_7 -{ 0xBC20, 0xBB, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_8 -{ 0xBC21, 0xC7, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_9 -{ 0xBC22, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_10 -{ 0xBC23, 0xDA, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_11 -{ 0xBC24, 0xE1, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_12 -{ 0xBC25, 0xE8, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_13 -{ 0xBC26, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_14 -{ 0xBC27, 0xF3, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_15 -{ 0xBC28, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_16 -{ 0xBC29, 0xFB, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_17 -{ 0xBC2A, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_18 -{ 0xBC2B, 0x00, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_0 -{ 0xBC2C, 0x11, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_1 -{ 0xBC2D, 0x23, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_2 -{ 0xBC2E, 0x3F, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_3 -{ 0xBC2F, 0x67, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_4 -{ 0xBC30, 0x85, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_5 -{ 0xBC31, 0x9B, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_6 -{ 0xBC32, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_7 -{ 0xBC33, 0xBB, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_8 -{ 0xBC34, 0xC7, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_9 -{ 0xBC35, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_10 -{ 0xBC36, 0xDA, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_11 -{ 0xBC37, 0xE1, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_12 -{ 0xBC38, 0xE8, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_13 -{ 0xBC39, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_14 -{ 0xBC3A, 0xF3, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_15 -{ 0xBC3B, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_16 -{ 0xBC3C, 0xFB, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_17 -{ 0xBC3D, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_18 -{ 0xBC3E, 0x00, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_0 -{ 0xBC3F, 0x05, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_1 -{ 0xBC40, 0x0F, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_2 -{ 0xBC41, 0x21, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_3 -{ 0xBC42, 0x3C, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_4 -{ 0xBC43, 0x52, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_5 -{ 0xBC44, 0x67, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_6 -{ 0xBC45, 0x7B, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_7 -{ 0xBC46, 0x8D, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_8 -{ 0xBC47, 0x9E, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_9 -{ 0xBC48, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_10 -{ 0xBC49, 0xBA, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_11 -{ 0xBC4A, 0xC6, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_12 -{ 0xBC4B, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_13 -{ 0xBC4C, 0xDC, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_14 -{ 0xBC4D, 0xE5, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_15 -{ 0xBC4E, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_16 -{ 0xBC4F, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_17 -{ 0xBC50, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_18 +{ 0xBC18, 0x00, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_0 +{ 0xBC19, 0x11, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_1 +{ 0xBC1A, 0x23, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_2 +{ 0xBC1B, 0x3F, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_3 +{ 0xBC1C, 0x67, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_4 +{ 0xBC1D, 0x85, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_5 +{ 0xBC1E, 0x9B, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_6 +{ 0xBC1F, 0xAD, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_7 +{ 0xBC20, 0xBB, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_8 +{ 0xBC21, 0xC7, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_9 +{ 0xBC22, 0xD1, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_10 +{ 0xBC23, 0xDA, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_11 +{ 0xBC24, 0xE1, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_12 +{ 0xBC25, 0xE8, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_13 +{ 0xBC26, 0xEE, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_14 +{ 0xBC27, 0xF3, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_15 +{ 0xBC28, 0xF7, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_16 +{ 0xBC29, 0xFB, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_17 +{ 0xBC2A, 0xFF, 0xffff,0xff}, // LL_GAMMA_CONTRAST_CURVE_18 +{ 0xBC2B, 0x00, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_0 +{ 0xBC2C, 0x11, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_1 +{ 0xBC2D, 0x23, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_2 +{ 0xBC2E, 0x3F, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_3 +{ 0xBC2F, 0x67, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_4 +{ 0xBC30, 0x85, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_5 +{ 0xBC31, 0x9B, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_6 +{ 0xBC32, 0xAD, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_7 +{ 0xBC33, 0xBB, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_8 +{ 0xBC34, 0xC7, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_9 +{ 0xBC35, 0xD1, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_10 +{ 0xBC36, 0xDA, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_11 +{ 0xBC37, 0xE1, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_12 +{ 0xBC38, 0xE8, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_13 +{ 0xBC39, 0xEE, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_14 +{ 0xBC3A, 0xF3, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_15 +{ 0xBC3B, 0xF7, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_16 +{ 0xBC3C, 0xFB, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_17 +{ 0xBC3D, 0xFF, 0xffff,0xff}, // LL_GAMMA_NEUTRAL_CURVE_18 +{ 0xBC3E, 0x00, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_0 +{ 0xBC3F, 0x05, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_1 +{ 0xBC40, 0x0F, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_2 +{ 0xBC41, 0x21, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_3 +{ 0xBC42, 0x3C, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_4 +{ 0xBC43, 0x52, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_5 +{ 0xBC44, 0x67, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_6 +{ 0xBC45, 0x7B, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_7 +{ 0xBC46, 0x8D, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_8 +{ 0xBC47, 0x9E, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_9 +{ 0xBC48, 0xAD, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_10 +{ 0xBC49, 0xBA, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_11 +{ 0xBC4A, 0xC6, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_12 +{ 0xBC4B, 0xD1, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_13 +{ 0xBC4C, 0xDC, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_14 +{ 0xBC4D, 0xE5, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_15 +{ 0xBC4E, 0xEE, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_16 +{ 0xBC4F, 0xF7, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_17 +{ 0xBC50, 0xFF, 0xffff,0xff}, // LL_GAMMA_NR_CURVE_18 //[BM_Dampening] -{ 0xB801, 0xE0, BYTE_LEN, 0}, // STAT_MODE -{ 0xB862, 0x04, BYTE_LEN, 0}, // STAT_BMTRACKING_SPEED +{ 0xB801, 0xE0, 0xffff,0xff}, // STAT_MODE +{ 0xB862, 0x04, 0xffff,0xff}, // STAT_BMTRACKING_SPEED //[AE] -{ 0xB829, 0x02, BYTE_LEN, 0}, // STAT_LL_BRIGHTNESS_METRIC_DIVISOR -{ 0xB863, 0x02, BYTE_LEN, 0}, // STAT_BM_MUL -{ 0xB827, 0x0F, BYTE_LEN, 0}, // STAT_AE_EV_SHIFT -{ 0xA409, 0x42, BYTE_LEN, 0}, // AE_RULE_BASE_TARGET +{ 0xB829, 0x02, 0xffff,0xff}, // STAT_LL_BRIGHTNESS_METRIC_DIVISOR +{ 0xB863, 0x02, 0xffff,0xff}, // STAT_BM_MUL +{ 0xB827, 0x0F, 0xffff,0xff}, // STAT_AE_EV_SHIFT +{ 0xA409, 0x42, 0xffff,0xff}, // AE_RULE_BASE_TARGET //[BM_GM_Start_Stop] -{ 0xBC52, 0x00C8, WORD_LEN, 0}, // LL_START_BRIGHTNESS_METRIC -{ 0xBC54, 0x0A28, WORD_LEN, 0}, // LL_END_BRIGHTNESS_METRIC -{ 0xBC58, 0x00C8, WORD_LEN, 0}, // LL_START_GAIN_METRIC -{ 0xBC5A, 0x12C0, WORD_LEN, 0}, // LL_END_GAIN_METRIC -{ 0xBC5E, 0x00FA, WORD_LEN, 0}, // LL_START_APERTURE_GAIN_BM -{ 0xBC60, 0x0258, WORD_LEN, 0}, // LL_END_APERTURE_GAIN_BM -{ 0xBC66, 0x00FA, WORD_LEN, 0}, // LL_START_APERTURE_GM -{ 0xBC68, 0x0258, WORD_LEN, 0}, // LL_END_APERTURE_GM -{ 0xBC86, 0x00C8, WORD_LEN, 0}, // LL_START_FFNR_GM -{ 0xBC88, 0x0640, WORD_LEN, 0}, // LL_END_FFNR_GM -{ 0xBCBC, 0x0040, WORD_LEN, 0}, // LL_SFFB_START_GAIN -{ 0xBCBE, 0x01FC, WORD_LEN, 0}, // LL_SFFB_END_GAIN -{ 0xBCCC, 0x00C8, WORD_LEN, 0}, // LL_SFFB_START_MAX_GM -{ 0xBCCE, 0x0640, WORD_LEN, 0}, // LL_SFFB_END_MAX_GM -{ 0xBC90, 0x00C8, WORD_LEN, 0}, // LL_START_GRB_GM -{ 0xBC92, 0x0640, WORD_LEN, 0}, // LL_END_GRB_GM -{ 0xBC0E, 0x0001, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_START_POS -{ 0xBC10, 0x0002, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_MID_POS -{ 0xBC12, 0x02BC, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_END_POS -{ 0xBCAA, 0x044C, WORD_LEN, 0}, // LL_CDC_THR_ADJ_START_POS -{ 0xBCAC, 0x00AF, WORD_LEN, 0}, // LL_CDC_THR_ADJ_MID_POS -{ 0xBCAE, 0x0009, WORD_LEN, 0}, // LL_CDC_THR_ADJ_END_POS -{ 0xBCD8, 0x00C8, WORD_LEN, 0}, // LL_PCR_START_BM -{ 0xBCDA, 0x0A28, WORD_LEN, 0}, // LL_PCR_END_BM +{ 0xBC52, 0x00C8, 0xffff,0xffff}, // LL_START_BRIGHTNESS_METRIC +{ 0xBC54, 0x0A28, 0xffff,0xffff}, // LL_END_BRIGHTNESS_METRIC +{ 0xBC58, 0x00C8, 0xffff,0xffff}, // LL_START_GAIN_METRIC +{ 0xBC5A, 0x12C0, 0xffff,0xffff}, // LL_END_GAIN_METRIC +{ 0xBC5E, 0x00FA, 0xffff,0xffff}, // LL_START_APERTURE_GAIN_BM +{ 0xBC60, 0x0258, 0xffff,0xffff}, // LL_END_APERTURE_GAIN_BM +{ 0xBC66, 0x00FA, 0xffff,0xffff}, // LL_START_APERTURE_GM +{ 0xBC68, 0x0258, 0xffff,0xffff}, // LL_END_APERTURE_GM +{ 0xBC86, 0x00C8, 0xffff,0xffff}, // LL_START_FFNR_GM +{ 0xBC88, 0x0640, 0xffff,0xffff}, // LL_END_FFNR_GM +{ 0xBCBC, 0x0040, 0xffff,0xffff}, // LL_SFFB_START_GAIN +{ 0xBCBE, 0x01FC, 0xffff,0xffff}, // LL_SFFB_END_GAIN +{ 0xBCCC, 0x00C8, 0xffff,0xffff}, // LL_SFFB_START_MAX_GM +{ 0xBCCE, 0x0640, 0xffff,0xffff}, // LL_SFFB_END_MAX_GM +{ 0xBC90, 0x00C8, 0xffff,0xffff}, // LL_START_GRB_GM +{ 0xBC92, 0x0640, 0xffff,0xffff}, // LL_END_GRB_GM +{ 0xBC0E, 0x0001, 0xffff,0xffff}, // LL_GAMMA_CURVE_ADJ_START_POS +{ 0xBC10, 0x0002, 0xffff,0xffff}, // LL_GAMMA_CURVE_ADJ_MID_POS +{ 0xBC12, 0x02BC, 0xffff,0xffff}, // LL_GAMMA_CURVE_ADJ_END_POS +{ 0xBCAA, 0x044C, 0xffff,0xffff}, // LL_CDC_THR_ADJ_START_POS +{ 0xBCAC, 0x00AF, 0xffff,0xffff}, // LL_CDC_THR_ADJ_MID_POS +{ 0xBCAE, 0x0009, 0xffff,0xffff}, // LL_CDC_THR_ADJ_END_POS +{ 0xBCD8, 0x00C8, 0xffff,0xffff}, // LL_PCR_START_BM +{ 0xBCDA, 0x0A28, 0xffff,0xffff}, // LL_PCR_END_BM //[Kernel] -{ 0x3380, 0x0504, WORD_LEN, 0}, // KERNEL_CONFIG +{ 0x3380, 0x0504, 0xffff,0xffff}, // KERNEL_CONFIG //[GRB] -{ 0xBC94, 0x0C, BYTE_LEN, 0}, // LL_GB_START_THRESHOLD_0 -{ 0xBC95, 0x08, BYTE_LEN, 0}, // LL_GB_START_THRESHOLD_1 -{ 0xBC9C, 0x3C, BYTE_LEN, 0}, // RESERVED_LL_9C -{ 0xBC9D, 0x28, BYTE_LEN, 0}, // RESERVED_LL_9D +{ 0xBC94, 0x0C, 0xffff,0xff}, // LL_GB_START_THRESHOLD_0 +{ 0xBC95, 0x08, 0xffff,0xff}, // LL_GB_START_THRESHOLD_1 +{ 0xBC9C, 0x3C, 0xffff,0xff}, // RESERVED_LL_9C +{ 0xBC9D, 0x28, 0xffff,0xff}, // RESERVED_LL_9D //[Demosaic_REV3] -{ 0x33B0, 0x2A16, WORD_LEN, 0}, // FFNR_ALPHA_BETA -{ 0xBC8A, 0x02, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_Y -{ 0xBC8B, 0x0F, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_Y -{ 0xBC8C, 0xFF, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_YGAIN -{ 0xBC8D, 0xFF, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_YGAIN -{ 0xBC8E, 0xFF, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_GAIN -{ 0xBC8F, 0x00, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_GAIN +{ 0x33B0, 0x2A16, 0xffff,0xffff}, // FFNR_ALPHA_BETA +{ 0xBC8A, 0x02, 0xffff,0xff}, // LL_START_FF_MIX_THRESH_Y +{ 0xBC8B, 0x0F, 0xffff,0xff}, // LL_END_FF_MIX_THRESH_Y +{ 0xBC8C, 0xFF, 0xffff,0xff}, // LL_START_FF_MIX_THRESH_YGAIN +{ 0xBC8D, 0xFF, 0xffff,0xff}, // LL_END_FF_MIX_THRESH_YGAIN +{ 0xBC8E, 0xFF, 0xffff,0xff}, // LL_START_FF_MIX_THRESH_GAIN +{ 0xBC8F, 0x00, 0xffff,0xff}, // LL_END_FF_MIX_THRESH_GAIN //[CDC] -{ 0xBCB2, 0x20, BYTE_LEN, 0}, // LL_CDC_DARK_CLUS_SLOPE -{ 0xBCB3, 0x3A, BYTE_LEN, 0}, // LL_CDC_DARK_CLUS_SATUR -{ 0xBCB4, 0x39, BYTE_LEN, 0}, // RESERVED_LL_B4 -{ 0xBCB7, 0x39, BYTE_LEN, 0}, // RESERVED_LL_B7 -{ 0xBCB5, 0x20, BYTE_LEN, 0}, // RESERVED_LL_B5 -{ 0xBCB8, 0x3A, BYTE_LEN, 0}, // RESERVED_LL_B8 -{ 0xBCB6, 0x80, BYTE_LEN, 0}, // RESERVED_LL_B6 -{ 0xBCB9, 0x24, BYTE_LEN, 0}, // RESERVED_LL_B9 -{ 0xBCAA, 0x03E8, WORD_LEN, 0}, // LL_CDC_THR_ADJ_START_POS -{ 0xBCAC, 0x012C, WORD_LEN, 0}, // LL_CDC_THR_ADJ_MID_POS -{ 0xBCAE, 0x0009, WORD_LEN, 0}, // LL_CDC_THR_ADJ_END_POS +{ 0xBCB2, 0x20, 0xffff,0xff}, // LL_CDC_DARK_CLUS_SLOPE +{ 0xBCB3, 0x3A, 0xffff,0xff}, // LL_CDC_DARK_CLUS_SATUR +{ 0xBCB4, 0x39, 0xffff,0xff}, // RESERVED_LL_B4 +{ 0xBCB7, 0x39, 0xffff,0xff}, // RESERVED_LL_B7 +{ 0xBCB5, 0x20, 0xffff,0xff}, // RESERVED_LL_B5 +{ 0xBCB8, 0x3A, 0xffff,0xff}, // RESERVED_LL_B8 +{ 0xBCB6, 0x80, 0xffff,0xff}, // RESERVED_LL_B6 +{ 0xBCB9, 0x24, 0xffff,0xff}, // RESERVED_LL_B9 +{ 0xBCAA, 0x03E8, 0xffff,0xffff}, // LL_CDC_THR_ADJ_START_POS +{ 0xBCAC, 0x012C, 0xffff,0xffff}, // LL_CDC_THR_ADJ_MID_POS +{ 0xBCAE, 0x0009, 0xffff,0xffff}, // LL_CDC_THR_ADJ_END_POS //[Aperture_calib] -{ 0x33BA, 0x0084, WORD_LEN, 0}, // APEDGE_CONTROL -{ 0x33BE, 0x0000, WORD_LEN, 0}, // UA_KNEE_L -{ 0x33C2, 0x8800, WORD_LEN, 0}, // UA_WEIGHTS -{ 0xBC5E, 0x0154, WORD_LEN, 0}, // LL_START_APERTURE_GAIN_BM -{ 0xBC60, 0x0640, WORD_LEN, 0}, // LL_END_APERTURE_GAIN_BM -{ 0xBC62, 0x0E, BYTE_LEN, 0}, // LL_START_APERTURE_KPGAIN -{ 0xBC63, 0x14, BYTE_LEN, 0}, // LL_END_APERTURE_KPGAIN -{ 0xBC64, 0x0E, BYTE_LEN, 0}, // LL_START_APERTURE_KNGAIN -{ 0xBC65, 0x14, BYTE_LEN, 0}, // LL_END_APERTURE_KNGAIN -{ 0xBCE2, 0x0A, BYTE_LEN, 0}, // LL_START_POS_KNEE -{ 0xBCE3, 0x2B, BYTE_LEN, 0}, // LL_END_POS_KNEE -{ 0xBCE4, 0x0A, BYTE_LEN, 0}, // LL_START_NEG_KNEE -{ 0xBCE5, 0x2B, BYTE_LEN, 0}, // LL_END_NEG_KNEE -{ 0x3210, 0x49B8, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL +{ 0x33BA, 0x0084, 0xffff,0xffff}, // APEDGE_CONTROL +{ 0x33BE, 0x0000, 0xffff,0xffff}, // UA_KNEE_L +{ 0x33C2, 0x8800, 0xffff,0xffff}, // UA_WEIGHTS +{ 0xBC5E, 0x0154, 0xffff,0xffff}, // LL_START_APERTURE_GAIN_BM +{ 0xBC60, 0x0640, 0xffff,0xffff}, // LL_END_APERTURE_GAIN_BM +{ 0xBC62, 0x0E, 0xffff,0xff}, // LL_START_APERTURE_KPGAIN +{ 0xBC63, 0x14, 0xffff,0xff}, // LL_END_APERTURE_KPGAIN +{ 0xBC64, 0x0E, 0xffff,0xff}, // LL_START_APERTURE_KNGAIN +{ 0xBC65, 0x14, 0xffff,0xff}, // LL_END_APERTURE_KNGAIN +{ 0xBCE2, 0x0A, 0xffff,0xff}, // LL_START_POS_KNEE +{ 0xBCE3, 0x2B, 0xffff,0xff}, // LL_END_POS_KNEE +{ 0xBCE4, 0x0A, 0xffff,0xff}, // LL_START_NEG_KNEE +{ 0xBCE5, 0x2B, 0xffff,0xff}, // LL_END_NEG_KNEE +{ 0x3210, 0x49B8, 0xffff,0xffff}, // COLOR_PIPELINE_CONTROL //[SFFB_REV3_noisemodel] -{ 0xBCC0, 0x1F, BYTE_LEN, 0}, // LL_SFFB_RAMP_START -{ 0xBCC1, 0x03, BYTE_LEN, 0}, // LL_SFFB_RAMP_STOP -{ 0xBCC2, 0x2C, BYTE_LEN, 0}, // LL_SFFB_SLOPE_START -{ 0xBCC3, 0x10, BYTE_LEN, 0}, // LL_SFFB_SLOPE_STOP -{ 0xBCC4, 0x07, BYTE_LEN, 0}, // LL_SFFB_THSTART -{ 0xBCC5, 0x0B, BYTE_LEN, 0}, // LL_SFFB_THSTOP -{ 0xBCBA, 0x0009, WORD_LEN, 0}, // LL_SFFB_CONFIG +{ 0xBCC0, 0x1F, 0xffff,0xff}, // LL_SFFB_RAMP_START +{ 0xBCC1, 0x03, 0xffff,0xff}, // LL_SFFB_RAMP_STOP +{ 0xBCC2, 0x2C, 0xffff,0xff}, // LL_SFFB_SLOPE_START +{ 0xBCC3, 0x10, 0xffff,0xff}, // LL_SFFB_SLOPE_STOP +{ 0xBCC4, 0x07, 0xffff,0xff}, // LL_SFFB_THSTART +{ 0xBCC5, 0x0B, 0xffff,0xff}, // LL_SFFB_THSTOP +{ 0xBCBA, 0x0009, 0xffff,0xffff}, // LL_SFFB_CONFIG //[**********Step8*************] //[FTB_Off] -{ 0xBC14, 0xFFFE, WORD_LEN, 0}, // LL_GAMMA_FADE_TO_BLACK_START_POS -{ 0xBC16, 0xFFFE, WORD_LEN, 0}, // LL_GAMMA_FADE_TO_BLACK_END_POS +{ 0xBC14, 0xFFFE, 0xffff,0xffff}, // LL_GAMMA_FADE_TO_BLACK_START_POS +{ 0xBC16, 0xFFFE, 0xffff,0xffff}, // LL_GAMMA_FADE_TO_BLACK_END_POS //[Aperture_preference] -{ 0xBC66, 0x0154, WORD_LEN, 0}, // LL_START_APERTURE_GM -{ 0xBC68, 0x07D0, WORD_LEN, 0}, // LL_END_APERTURE_GM -{ 0xBC6A, 0x04, BYTE_LEN, 0}, // LL_START_APERTURE_INTEGER_GAIN -{ 0xBC6B, 0x00, BYTE_LEN, 0}, // LL_END_APERTURE_INTEGER_GAIN -{ 0xBC6C, 0x00, BYTE_LEN, 0}, // LL_START_APERTURE_EXP_GAIN -{ 0xBC6D, 0x00, BYTE_LEN, 0}, // LL_END_APERTURE_EXP_GAIN +{ 0xBC66, 0x0154, 0xffff,0xffff}, // LL_START_APERTURE_GM +{ 0xBC68, 0x07D0, 0xffff,0xffff}, // LL_END_APERTURE_GM +{ 0xBC6A, 0x04, 0xffff,0xff}, // LL_START_APERTURE_INTEGER_GAIN +{ 0xBC6B, 0x00, 0xffff,0xff}, // LL_END_APERTURE_INTEGER_GAIN +{ 0xBC6C, 0x00, 0xffff,0xff}, // LL_START_APERTURE_EXP_GAIN +{ 0xBC6D, 0x00, 0xffff,0xff}, // LL_END_APERTURE_EXP_GAIN //[Gain_max] -{ 0xA81C, 0x0040, WORD_LEN, 0}, // AE_TRACK_MIN_AGAIN -{ 0xA820, 0x012C, WORD_LEN, 0}, // AE_TRACK_MAX_AGAIN -{ 0xA822, 0x0060, WORD_LEN, 0}, // AE_TRACK_MIN_DGAIN -{ 0xA824, 0x00E5, WORD_LEN, 0}, // AE_TRACK_MAX_DGAIN +{ 0xA81C, 0x0040, 0xffff,0xffff}, // AE_TRACK_MIN_AGAIN +{ 0xA820, 0x012C, 0xffff,0xffff}, // AE_TRACK_MAX_AGAIN +{ 0xA822, 0x0060, 0xffff,0xffff}, // AE_TRACK_MIN_DGAIN +{ 0xA824, 0x00E5, 0xffff,0xffff}, // AE_TRACK_MAX_DGAIN //[Saturation_REV3] -{ 0xBC56, 0x64, BYTE_LEN, 0}, // LL_START_CCM_SATURATION -{ 0xBC57, 0x1E, BYTE_LEN, 0}, // LL_END_CCM_SATURATION +{ 0xBC56, 0x64, 0xffff,0xff}, // LL_START_CCM_SATURATION +{ 0xBC57, 0x1E, 0xffff,0xff}, // LL_END_CCM_SATURATION //[DCCM_REV3] -{ 0xBCDE, 0x03, BYTE_LEN, 0}, // LL_START_SYS_THRESHOLD -{ 0xBCDF, 0x50, BYTE_LEN, 0}, // LL_STOP_SYS_THRESHOLD -{ 0xBCE0, 0x08, BYTE_LEN, 0}, // LL_START_SYS_GAIN -{ 0xBCE1, 0x03, BYTE_LEN, 0}, // LL_STOP_SYS_GAIN +{ 0xBCDE, 0x03, 0xffff,0xff}, // LL_START_SYS_THRESHOLD +{ 0xBCDF, 0x50, 0xffff,0xff}, // LL_STOP_SYS_THRESHOLD +{ 0xBCE0, 0x08, 0xffff,0xff}, // LL_START_SYS_GAIN +{ 0xBCE1, 0x03, 0xffff,0xff}, // LL_STOP_SYS_GAIN //[Sobel_REV3] -{ 0xBCD0, 0x000A, WORD_LEN, 0}, // LL_SFFB_SOBEL_FLAT_START -{ 0xBCD2, 0x00FE, WORD_LEN, 0}, // LL_SFFB_SOBEL_FLAT_STOP -{ 0xBCD4, 0x001E, WORD_LEN, 0}, // LL_SFFB_SOBEL_SHARP_START -{ 0xBCD6, 0x00FF, WORD_LEN, 0}, // LL_SFFB_SOBEL_SHARP_STOP -{ 0xBCC6, 0x00, BYTE_LEN, 0}, // LL_SFFB_SHARPENING_START -{ 0xBCC7, 0x00, BYTE_LEN, 0}, // LL_SFFB_SHARPENING_STOP -{ 0xBCC8, 0x20, BYTE_LEN, 0}, // LL_SFFB_FLATNESS_START -{ 0xBCC9, 0x40, BYTE_LEN, 0}, // LL_SFFB_FLATNESS_STOP -{ 0xBCCA, 0x04, BYTE_LEN, 0}, // LL_SFFB_TRANSITION_START -{ 0xBCCB, 0x00, BYTE_LEN, 0}, // LL_SFFB_TRANSITION_STOP +{ 0xBCD0, 0x000A, 0xffff,0xffff}, // LL_SFFB_SOBEL_FLAT_START +{ 0xBCD2, 0x00FE, 0xffff,0xffff}, // LL_SFFB_SOBEL_FLAT_STOP +{ 0xBCD4, 0x001E, 0xffff,0xffff}, // LL_SFFB_SOBEL_SHARP_START +{ 0xBCD6, 0x00FF, 0xffff,0xffff}, // LL_SFFB_SOBEL_SHARP_STOP +{ 0xBCC6, 0x00, 0xffff,0xff}, // LL_SFFB_SHARPENING_START +{ 0xBCC7, 0x00, 0xffff,0xff}, // LL_SFFB_SHARPENING_STOP +{ 0xBCC8, 0x20, 0xffff,0xff}, // LL_SFFB_FLATNESS_START +{ 0xBCC9, 0x40, 0xffff,0xff}, // LL_SFFB_FLATNESS_STOP +{ 0xBCCA, 0x04, 0xffff,0xff}, // LL_SFFB_TRANSITION_START +{ 0xBCCB, 0x00, 0xffff,0xff}, // LL_SFFB_TRANSITION_STOP //[SFFB_slope_zero_enable] -{ 0xBCE6, 0x03, BYTE_LEN, 0}, // LL_SFFB_ZERO_ENABLE -{ 0xBCE6, 0x03, BYTE_LEN, 0}, // LL_SFFB_ZERO_ENABLE +{ 0xBCE6, 0x03, 0xffff,0xff}, // LL_SFFB_ZERO_ENABLE +{ 0xBCE6, 0x03, 0xffff,0xff}, // LL_SFFB_ZERO_ENABLE //[AE_preference] -{ 0xA410, 0x04, BYTE_LEN, 0}, // AE_RULE_TARGET_AE_6 -{ 0xA411, 0x06, BYTE_LEN, 0}, // AE_RULE_TARGET_AE_7 +{ 0xA410, 0x04, 0xffff,0xff}, // AE_RULE_TARGET_AE_6 +{ 0xA411, 0x06, 0xffff,0xff}, // AE_RULE_TARGET_AE_7 //[**********Step9*************] //[JPEG Quantization] //[Sepia effect] -{ 0xDC3A, 0x23, BYTE_LEN, 0}, // SYS_SEPIA_CR -{ 0xDC3B, 0xB2, BYTE_LEN, 0}, // SYS_SEPIA_CB +{ 0xDC3A, 0x23, 0xffff,0xff}, // SYS_SEPIA_CR +{ 0xDC3B, 0xB2, 0xffff,0xff}, // SYS_SEPIA_CB //[Touch Focus + Fast Focus AF_AFM_INIT] -{ 0x8411, 0x00, BYTE_LEN, 0}, // SEQ_STATE_CFG_0_AF -{ 0x8419, 0x04, BYTE_LEN, 0}, // SEQ_STATE_CFG_1_AF +{ 0x8411, 0x00, 0xffff,0xff}, // SEQ_STATE_CFG_0_AF +{ 0x8419, 0x04, 0xffff,0xff}, // SEQ_STATE_CFG_1_AF -{ 0xB002, 0x0002, WORD_LEN, 0}, // AF_MODE -{ 0xC40A, 0x0030, WORD_LEN, 0}, // AFM_POS_MIN -{ 0xC40C, 0x00A0, WORD_LEN, 0}, // AFM_POS_MAX -{ 0xB045, 0x000C, WORD_LEN, 0}, // AF_MODE_EX +{ 0xB002, 0x0002, 0xffff,0xffff}, // AF_MODE +{ 0xC40A, 0x0030, 0xffff,0xffff}, // AFM_POS_MIN +{ 0xC40C, 0x00A0, 0xffff,0xffff}, // AFM_POS_MAX +{ 0xB045, 0x000C, 0xffff,0xffff}, // AF_MODE_EX //AF Window size -{ 0xB854, 0x60, BYTE_LEN, 0}, // STAT_SM_WINDOW_POS_X -{ 0xB855, 0x60, BYTE_LEN, 0}, // STAT_SM_WINDOW_POS_Y -{ 0xB856, 0x40, BYTE_LEN, 0}, // STAT_SM_WINDOW_SIZE_X -{ 0xB857, 0x40, BYTE_LEN, 0}, // STAT_SM_WINDOW_SIZE_Y -{ 0xB012, 0x0A, BYTE_LEN, 0}, // AF_FS_NUM_STEPS -{ 0xB018, 0x00, BYTE_LEN, 0}, // AF_FS_POS_0 -{ 0xB019, 0x30, BYTE_LEN, 0}, // AF_FS_POS_1 -{ 0xB01A, 0x48, BYTE_LEN, 0}, // AF_FS_POS_2 -{ 0xB01B, 0x60, BYTE_LEN, 0}, // AF_FS_POS_3 -{ 0xB01C, 0x78, BYTE_LEN, 0}, // AF_FS_POS_4 -{ 0xB01D, 0x90, BYTE_LEN, 0}, // AF_FS_POS_5 -{ 0xB01E, 0xA8, BYTE_LEN, 0}, // AF_FS_POS_6 -{ 0xB01F, 0xC0, BYTE_LEN, 0}, // AF_FS_POS_7 -{ 0xB020, 0xE0, BYTE_LEN, 0}, // AF_FS_POS_8 -{ 0xB021, 0xFF, BYTE_LEN, 0}, // AF_FS_POS_9 -{ 0xB022, 0x00, BYTE_LEN, 0}, // AF_FS_POS_10 -{ 0xB011, 0x00, BYTE_LEN, 0}, // AF_FS_INIT_POS +{ 0xB854, 0x60, 0xffff,0xff}, // STAT_SM_WINDOW_POS_X +{ 0xB855, 0x60, 0xffff,0xff}, // STAT_SM_WINDOW_POS_Y +{ 0xB856, 0x40, 0xffff,0xff}, // STAT_SM_WINDOW_SIZE_X +{ 0xB857, 0x40, 0xffff,0xff}, // STAT_SM_WINDOW_SIZE_Y +{ 0xB012, 0x0A, 0xffff,0xff}, // AF_FS_NUM_STEPS +{ 0xB018, 0x00, 0xffff,0xff}, // AF_FS_POS_0 +{ 0xB019, 0x30, 0xffff,0xff}, // AF_FS_POS_1 +{ 0xB01A, 0x48, 0xffff,0xff}, // AF_FS_POS_2 +{ 0xB01B, 0x60, 0xffff,0xff}, // AF_FS_POS_3 +{ 0xB01C, 0x78, 0xffff,0xff}, // AF_FS_POS_4 +{ 0xB01D, 0x90, 0xffff,0xff}, // AF_FS_POS_5 +{ 0xB01E, 0xA8, 0xffff,0xff}, // AF_FS_POS_6 +{ 0xB01F, 0xC0, 0xffff,0xff}, // AF_FS_POS_7 +{ 0xB020, 0xE0, 0xffff,0xff}, // AF_FS_POS_8 +{ 0xB021, 0xFF, 0xffff,0xff}, // AF_FS_POS_9 +{ 0xB022, 0x00, 0xffff,0xff}, // AF_FS_POS_10 +{ 0xB011, 0x00, 0xffff,0xff}, // AF_FS_INIT_POS //INIT PATCH PAGE used in FF -{ 0x098E, 0xD40E, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS -{ 0xD40E, 0x0000, WORD_LEN, 0}, -{ 0xD40F, 0x0000, WORD_LEN, 0}, -{ 0xD410, 0x0000, WORD_LEN, 0}, -{ 0xD411, 0x0000, WORD_LEN, 0}, -{ 0xD412, 0x0000, WORD_LEN, 0}, -{ 0xD413, 0x0000, WORD_LEN, 0}, -{ 0xD414, 0x0000, WORD_LEN, 0}, -{ 0xD415, 0x0000, WORD_LEN, 0}, -{ 0xD416, 0x0000, WORD_LEN, 0}, -{ 0xD417, 0x0000, WORD_LEN, 0}, -{ 0xD418, 0x0000, WORD_LEN, 0}, -{ 0xD418, 0x0000, WORD_LEN, 0}, -{ 0xD419, 0x0000, WORD_LEN, 0}, -{ 0xD41A, 0x0000, WORD_LEN, 0}, -{ 0xD41B, 0x0000, WORD_LEN, 0}, -{ 0xD41C, 0x0000, WORD_LEN, 0}, -{ 0xD41D, 0x0000, WORD_LEN, 0}, -{ 0xD41E, 0x0000, WORD_LEN, 0}, -{ 0xD420, 0x0000, WORD_LEN, 0}, -{ 0xD406, 0x0000, WORD_LEN, 0}, -{ 0xD407, 0x0000, WORD_LEN, 0}, -{ 0xD422, 0x0000, WORD_LEN, 0}, -{ 0xD423, 0x0000, WORD_LEN, 0}, -{ 0xD424, 0x0000, WORD_LEN, 0}, -{ 0xD425, 0x0000, WORD_LEN, 0}, -{ 0xD426, 0x0000, WORD_LEN, 0}, -{ 0xD427, 0x0000, WORD_LEN, 0}, -{ 0xD428, 0x0000, WORD_LEN, 0}, -{ 0xD429, 0x0000, WORD_LEN, 0}, -{ 0xD42A, 0x0000, WORD_LEN, 0}, -{ 0xD42B, 0x0000, WORD_LEN, 0}, -{ 0xD400, 0x0001, WORD_LEN, 0}, -{ 0xD401, 0x0000, WORD_LEN, 0}, -{ 0xD402, 0x0028, WORD_LEN, 0}, -{ 0xD403, 0x0080, WORD_LEN, 0}, -{ 0xD404, 0x0000, WORD_LEN, 0}, -{ 0xD405, 0x0000, WORD_LEN, 0}, -{ 0xD406, 0x0000, WORD_LEN, 0}, -{ 0xD407, 0x0000, WORD_LEN, 0}, -{ 0xD408, 0x0030, WORD_LEN, 0}, -{ 0xD409, 0x0040, WORD_LEN, 0}, -{ 0xD40A, 0x0050, WORD_LEN, 0}, -{ 0xD40B, 0x0070, WORD_LEN, 0}, -{ 0xD40C, 0x0080, WORD_LEN, 0}, -{ 0xD40D, 0x0090, WORD_LEN, 0}, - -{ 0x0018, 0x2008, WORD_LEN, 0}, // STANDBY_CONTROL_AND_STATUS - -{SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, - - { SEQUENCE_END, 0x00, 0, 0} +{ 0x098E, 0xD40E, 0xffff,0xffff}, // LOGICAL_ADDRESS_ACCESS +{ 0xD40E, 0x0000, 0xffff,0xffff}, +{ 0xD40F, 0x0000, 0xffff,0xffff}, +{ 0xD410, 0x0000, 0xffff,0xffff}, +{ 0xD411, 0x0000, 0xffff,0xffff}, +{ 0xD412, 0x0000, 0xffff,0xffff}, +{ 0xD413, 0x0000, 0xffff,0xffff}, +{ 0xD414, 0x0000, 0xffff,0xffff}, +{ 0xD415, 0x0000, 0xffff,0xffff}, +{ 0xD416, 0x0000, 0xffff,0xffff}, +{ 0xD417, 0x0000, 0xffff,0xffff}, +{ 0xD418, 0x0000, 0xffff,0xffff}, +{ 0xD418, 0x0000, 0xffff,0xffff}, +{ 0xD419, 0x0000, 0xffff,0xffff}, +{ 0xD41A, 0x0000, 0xffff,0xffff}, +{ 0xD41B, 0x0000, 0xffff,0xffff}, +{ 0xD41C, 0x0000, 0xffff,0xffff}, +{ 0xD41D, 0x0000, 0xffff,0xffff}, +{ 0xD41E, 0x0000, 0xffff,0xffff}, +{ 0xD420, 0x0000, 0xffff,0xffff}, +{ 0xD406, 0x0000, 0xffff,0xffff}, +{ 0xD407, 0x0000, 0xffff,0xffff}, +{ 0xD422, 0x0000, 0xffff,0xffff}, +{ 0xD423, 0x0000, 0xffff,0xffff}, +{ 0xD424, 0x0000, 0xffff,0xffff}, +{ 0xD425, 0x0000, 0xffff,0xffff}, +{ 0xD426, 0x0000, 0xffff,0xffff}, +{ 0xD427, 0x0000, 0xffff,0xffff}, +{ 0xD428, 0x0000, 0xffff,0xffff}, +{ 0xD429, 0x0000, 0xffff,0xffff}, +{ 0xD42A, 0x0000, 0xffff,0xffff}, +{ 0xD42B, 0x0000, 0xffff,0xffff}, +{ 0xD400, 0x0001, 0xffff,0xffff}, +{ 0xD401, 0x0000, 0xffff,0xffff}, +{ 0xD402, 0x0028, 0xffff,0xffff}, +{ 0xD403, 0x0080, 0xffff,0xffff}, +{ 0xD404, 0x0000, 0xffff,0xffff}, +{ 0xD405, 0x0000, 0xffff,0xffff}, +{ 0xD406, 0x0000, 0xffff,0xffff}, +{ 0xD407, 0x0000, 0xffff,0xffff}, +{ 0xD408, 0x0030, 0xffff,0xffff}, +{ 0xD409, 0x0040, 0xffff,0xffff}, +{ 0xD40A, 0x0050, 0xffff,0xffff}, +{ 0xD40B, 0x0070, 0xffff,0xffff}, +{ 0xD40C, 0x0080, 0xffff,0xffff}, +{ 0xD40D, 0x0090, 0xffff,0xffff}, + +{ 0x0018, 0x2008, 0xffff,0xffff}, // STANDBY_CONTROL_AND_STATUS + +SensorWaitMs(100), +SensorEnd }; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + //capture2preview + {0x098E, 0x843C, 0xffff, 0xffff}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] + {0x843C, 0xFF, 0xffff, 0xff}, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x02, 0xffff, 0xff}, // SEQ_CMD + SensorWaitMs(200), + 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[] = +{ + // Set resolution vga + {0xC83A, 0x000C, 0xffff,0xffff}, // CAM_CORE_A_Y_ADDR_START + {0xC83C, 0x0018, 0xffff,0xffff}, // CAM_CORE_A_X_ADDR_START + {0xC83E, 0x07B1, 0xffff,0xffff }, // CAM_CORE_A_Y_ADDR_END + {0xC840, 0x0A45, 0xffff,0xffff}, // CAM_CORE_A_X_ADDR_END + {0xC868, 0x0423, 0xffff,0xffff}, // CAM_CORE_A_FRAME_LENGTH_LINES + {0xC86A, 0x1194, 0xffff,0xffff}, // CAM_CORE_A_LINE_LENGTH_PCK + {0xC86C, 0x0518, 0xffff,0xffff}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH + {0xC86E, 0x03D4, 0xffff,0xffff}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT + {0xC870, 0x0014, 0xffff,0xffff}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK + {0xC858, 0x0003, 0xffff,0xffff}, // CAM_CORE_A_COARSE_ITMIN + {0xC8A4, 0x0A28, 0xffff,0xffff}, // CAM_CORE_B_OUTPUT_SIZE_WIDTH + {0xC8A6, 0x07A0, 0xffff,0xffff }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT + {0xC8AA, 0x0280, 0xffff,0xffff }, // CAM_OUTPUT_0_IMAGE_WIDTH + {0xC8AC, 0x01E0, 0xffff,0xffff }, // CAM_OUTPUT_0_IMAGE_HEIGHT + {0xC8AE, 0x0001, 0xffff,0xffff }, // CAM_OUTPUT_0_OUTPUT_FORMAT + {0x8404, 0x06, 0xffff,0xff }, // SEQ_CMD + SensorWaitMs(100), -/* 720p 15fps @ 1280x720 */ -static struct reginfo sensor_720p[]= -{ - //{SEQUENCE_END, 0x00}, - {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [CAM_CORE_A_Y_ADDR_START] - {0x843C, 0x01, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT - {0x8404, 0x01, BYTE_LEN, 0 }, // SEQ_CMD - {0x0016, 0x0447, WORD_LEN, 0}, // CLOCKS_CONTROL - {0xC83A, 0x0106, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_START - {0xC83C, 0x0018, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_START - {0xC83E, 0x06B7, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_END - {0xC840, 0x0A45, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_END - {0xC86C, 0x0518, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH - {0xC86E, 0x02D8, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT - {0xC870, 0x0014, WORD_LEN, 0}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK - {0xC858, 0x0003, WORD_LEN, 0}, // CAM_CORE_A_COARSE_ITMIN - {0xC8B8, 0x0004, WORD_LEN, 0}, // CAM_OUTPUT_0_JPEG_CONTROL -/****bug:part pixsels data not to be aquired *****/ -#if ADJUST_FOR_720P_FALG - {0xC8AA, 0x0500, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_WIDTH - {0xC8AC, 0x02D1, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_HEIGHT -#else - {0xC8AA, 0x0500, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_WIDTH - {0xC8AC, 0x02D0, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_HEIGHT -#endif - {0xC8AE, 0x0001, WORD_LEN, 0}, // CAM_OUTPUT_0_OUTPUT_FORMAT - {0x8404, 0x06, BYTE_LEN, 0 }, // SEQ_CMD - - {SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, - - { SEQUENCE_END, 0x00, 0, 0} -}; - -/* 1080p, 0x15fps, 0xyuv @1920x1080 */ -static struct reginfo sensor_1080p[]= -{ -{ SEQUENCE_END, 0x00, 0, 0} + //snap2preview + {0x098E, 0x843C,0xffff, 0xffff}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] + {0x843C, 0x01, 0xffff, 0xff}, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x01, 0xffff, 0xff}, // SEQ_CMD + {0x0016, 0x0447,0xffff, 0xffff}, // CLOCKS_CONTRO + SensorEnd }; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ -/* 2592X1944 QSXGA */ -#if ADJUST_FOR_CAPTURE_FALG -static struct reginfo sensor_qsxga[] = -{ - - {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] - {0xC8C0, 0x0A20,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH - {0xC8C2, 0x0798,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT - {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD - {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, - - {SEQUENCE_END, 0x00, 0, 0} -}; -#else -static struct reginfo sensor_qsxga[] = -{ - {SEQUENCE_PROPERTY,SEQUENCE_CAPTURE}, - { SEQUENCE_END, 0x00, 0, 0} -}; -#endif + {0x098E, 0x843C, 0xffff,0xffff}, // LOGICAL_ADDRESS_ACCESS [CAM_CORE_A_Y_ADDR_START] + {0x843C, 0x01, 0xffff,0xff }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x01, 0xffff,0xff }, // SEQ_CMD + {0x0016, 0x0447, 0xffff,0xffff}, // CLOCKS_CONTROL + {0xC83A, 0x0106, 0xffff,0xffff}, // CAM_CORE_A_Y_ADDR_START + {0xC83C, 0x0018, 0xffff,0xffff}, // CAM_CORE_A_X_ADDR_START + {0xC83E, 0x06B7, 0xffff,0xffff}, // CAM_CORE_A_Y_ADDR_END + {0xC840, 0x0A45, 0xffff,0xffff}, // CAM_CORE_A_X_ADDR_END + {0xC86C, 0x0518, 0xffff,0xffff}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH + {0xC86E, 0x02D8, 0xffff,0xffff}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT + {0xC870, 0x0014, 0xffff,0xffff}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK + {0xC858, 0x0003, 0xffff,0xffff}, // CAM_CORE_A_COARSE_ITMIN + {0xC8B8, 0x0004, 0xffff,0xffff}, // CAM_OUTPUT_0_JPEG_CONTROL + {0xC8AA, 0x0500, 0xffff,0xffff}, // CAM_OUTPUT_0_IMAGE_WIDTH + {0xC8AC, 0x02D1, 0xffff,0xffff}, // CAM_OUTPUT_0_IMAGE_HEIGHT + {0xC8AE, 0x0001, 0xffff,0xffff}, // CAM_OUTPUT_0_OUTPUT_FORMAT + {0x8404, 0x06, 0xffff,0xff }, // SEQ_CMD + SensorWaitMs(100), -/* 2048*1536 QXGA */ -#if ADJUST_FOR_CAPTURE_FALG -// send extra two lines to forbid to be captured error -static struct reginfo sensor_qxga[] = -{ - {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] - {0xC8C0, 0x0800,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH - {0xC8C2, 0x0602,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT - {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD - {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, - - {SEQUENCE_END, 0x00, 0, 0} -}; -#else -static struct reginfo sensor_qxga[] = -{ -{ SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -#endif -/* 1600X1200 UXGA */ -#if ADJUST_FOR_CAPTURE_FALG -static struct reginfo sensor_uxga[] = -{ - {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] - {0xC8C0, 0x0640,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH - {0xC8C2, 0x04b2,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT - {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD - {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, - - {SEQUENCE_END, 0x00, 0, 0} -}; -#else -static struct reginfo sensor_uxga[] = -{ - { SEQUENCE_END, 0x00, 0, 0} +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd }; -#endif -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {SEQUENCE_END, 0x00} -}; -/* 1024X768 XGA */ -#if ADJUST_FOR_CAPTURE_FALG -static struct reginfo sensor_xga[] = -{ - {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] - {0xC8C0, 0x0403,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH - {0xC8C2, 0x0302,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT - {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD - {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, - - {SEQUENCE_END, 0x00, 0, 0} -}; -#else -static struct reginfo sensor_xga[] = -{ - {SEQUENCE_END, 0x00, 0, 0} +static struct rk_sensor_reg sensor_softreset_data[]={ + {0x0010,0x0115,0xffff,0xffff}, + SensorEnd }; -#endif - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - { SEQUENCE_END, 0x00, 0, 0} +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorEnd }; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[]= { - //720p2vga - {0xC83A, 0x000C, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_START - {0xC83C, 0x0018, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_START - {0xC83E, 0x07B1, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_END - {0xC840, 0x0A45, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_END - {0xC868, 0x0423, WORD_LEN, 0}, // CAM_CORE_A_FRAME_LENGTH_LINES - {0xC86A, 0x1194, WORD_LEN, 0}, // CAM_CORE_A_LINE_LENGTH_PCK - {0xC86C, 0x0518, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH - {0xC86E, 0x03D4, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT - {0xC870, 0x0014, WORD_LEN, 0}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK - {0xC858, 0x0003, WORD_LEN, 0}, // CAM_CORE_A_COARSE_ITMIN - {0xC8A4, 0x0A28, WORD_LEN, 0}, // CAM_CORE_B_OUTPUT_SIZE_WIDTH - {0xC8A6, 0x07A0, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT - {0xC8AA, 0x0280, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_WIDTH - {0xC8AC, 0x01E0, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_HEIGHT - {0xC8AE, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_0_OUTPUT_FORMAT - {0x8404, 0x06, BYTE_LEN, 0 }, // SEQ_CMD - {SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, - {SEQUENCE_END, 0x00, 0, 0} - + SensorEnd }; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= { - {SEQUENCE_END, 0x00} -}; -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {SEQUENCE_END, 0x00} + SensorEnd }; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -#endif -static struct reginfo sensor_Preview2Capture[]= +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= { - //capture2preview - {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] - {0x843C, 0xFF, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT - {0x8404, 0x02, BYTE_LEN, 0 }, // SEQ_CMD - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; - -static struct reginfo sensor_Capture2Preview[]= +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= { - //snap2preview - {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] - {0x843C, 0x01, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT - {0x8404, 0x01, BYTE_LEN, 0 }, // SEQ_CMD - {0x0016, 0x0447, WORD_LEN, 0}, // CLOCKS_CONTRO - {SEQUENCE_END, 0x00, 0, 0} - + SensorEnd }; -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {SEQUENCE_END, 0x00} +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 reginfo sensor_ClrFmt_UYVY[]= +static struct rk_sensor_reg sensor_Brightness0[]= { - {SEQUENCE_END, 0x00} + // Brightness -2 + SensorEnd }; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= +static struct rk_sensor_reg sensor_Brightness1[]= { - //Auto - {0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] - {0xACB0, 0x31, BYTE_LEN, 0 }, // AWB_RG_MIN - {0xACB1, 0x5B, BYTE_LEN, 0 }, // AWB_RG_MAX - {0xACB4, 0x2A, BYTE_LEN, 0 }, // AWB_BG_MIN - {0xACB5, 0x5B, BYTE_LEN, 0 }, // AWB_BG_MAX - {0xACB2, 0x40, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT - {0xACB3, 0x48, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT - {0xACB6, 0x3f, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT - {0xACB7, 0x48, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT - {0xAC44, 0x00, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT - {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT - {SEQUENCE_END, 0x00, 0, 0} + // Brightness -1 + SensorEnd }; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - //[V. DL 7500] - { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] - {0xACB0, 0x38, BYTE_LEN, 0 }, // AWB_RG_MIN - {0xACB1, 0x42, BYTE_LEN, 0 }, // AWB_RG_MAX - {0xACB4, 0x44, BYTE_LEN, 0 }, // AWB_BG_MIN - {0xACB5, 0x4C, BYTE_LEN, 0 }, // AWB_BG_MAX - {0xACB2, 0x38, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT - {0xACB3, 0x42, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT - {0xACB6, 0x44, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT - {0xACB7, 0x4C, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT - {0xAC44, 0x7C, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT - {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT - {0xAC04, 0x3E, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO - {0xAC05, 0x48, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO - {0xAC08, 0x7F, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS - {SEQUENCE_END, 0x00, 0, 0} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= +static struct rk_sensor_reg sensor_Brightness2[]= { - //[IV Day Light] - { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] - {0xACB0, 0x3A, BYTE_LEN, 0 }, // AWB_RG_MIN - {0xACB1, 0x44, BYTE_LEN, 0 }, // AWB_RG_MAX - {0xACB4, 0x40, BYTE_LEN, 0 }, // AWB_BG_MIN - {0xACB5, 0x4A, BYTE_LEN, 0 }, // AWB_BG_MAX - {0xACB2, 0x3A, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT - {0xACB3, 0x44, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT - {0xACB6, 0x40, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT - {0xACB7, 0x4A, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT - {0xAC44, 0x7C, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT - {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT - {0xAC04, 0x40, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO - {0xAC05, 0x48, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO - {0xAC08, 0x7F, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS - {SEQUENCE_END, 0x00, 0, 0} + // Brightness 0 + SensorEnd }; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //[III Fluorescent] - { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] - {0xACB0, 0x44, BYTE_LEN, 0 }, // AWB_RG_MIN - {0xACB1, 0x4B, BYTE_LEN, 0 }, // AWB_RG_MAX - {0xACB4, 0x2C, BYTE_LEN, 0 }, // AWB_BG_MIN - {0xACB5, 0x34, BYTE_LEN, 0 }, // AWB_BG_MAX - {0xACB2, 0x44, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT - {0xACB3, 0x4B, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT - {0xACB6, 0x2C, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT - {0xACB7, 0x34, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT - {0xAC44, 0x40, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT - {0xAC45, 0x4A, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT - {0xAC04, 0x47, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO - {0xAC05, 0x30, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO - {0xAC08, 0x45, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS - {SEQUENCE_END, 0x00, 0, 0} -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //[II. Incandescent] - { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] - {0xACB0, 0x57, BYTE_LEN, 0 }, // AWB_RG_MIN - {0xACB1, 0x5F, BYTE_LEN, 0 }, // AWB_RG_MAX - {0xACB4, 0x26, BYTE_LEN, 0 }, // AWB_BG_MIN - {0xACB5, 0x2E, BYTE_LEN, 0 }, // AWB_BG_MAX - {0xACB2, 0x57, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT - {0xACB3, 0x5F, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT - {0xACB6, 0x26, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT - {0xACB7, 0x2E, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT - {0xAC44, 0x00, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT - {0xAC45, 0x08, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT - {0xAC04, 0x5B, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO - {0xAC05, 0x2A, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO - {0xAC08, 0x00, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS - {SEQUENCE_END, 0x00, 0, 0} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= +static struct rk_sensor_reg sensor_Brightness3[]= { - {SEQUENCE_END, 0x00} -}; + // Brightness +1 -static struct reginfo sensor_Brightness1[]= -{ - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Brightness2[]= +static struct rk_sensor_reg sensor_Brightness4[]= { - {SEQUENCE_END, 0x00} -}; + // Brightness +2 -static struct reginfo sensor_Brightness3[]= -{ - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Brightness4[]= +static struct rk_sensor_reg sensor_Brightness5[]= { - {SEQUENCE_END, 0x00} -}; + // Brightness +3 -static struct reginfo sensor_Brightness5[]= -{ - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, }; -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = +static struct rk_sensor_reg sensor_Effect_Normal[] = { - {0x098e,0xdc38, WORD_LEN, 0}, - {0xdc38,0x00, BYTE_LEN, 0 }, - {0x8404,0x06, BYTE_LEN, 0 }, - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -#if 0 -static struct reginfo sensor_Effect_WandB[] = + +static struct rk_sensor_reg sensor_Effect_WandB[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -#endif -static struct reginfo sensor_Effect_Sepia[] = + +static struct rk_sensor_reg sensor_Effect_Sepia[] = { - {0x098e,0xdc38, WORD_LEN, 0}, - {0xdc38,0x02, BYTE_LEN, 0 }, - {0xdc3a,0x10, BYTE_LEN, 0 }, - {0xdc3b,0xe0, BYTE_LEN, 0 }, - {0x8404,0x06, BYTE_LEN, 0 }, - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_Effect_Negative[] = +static struct rk_sensor_reg sensor_Effect_Negative[] = { - {0x098e,0xdc38, WORD_LEN, 0}, - {0xdc38,0x03, BYTE_LEN, 0 }, - {0x8404,0x06, BYTE_LEN, 0 }, - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -#if 0 -static struct reginfo sensor_Effect_Bluish[] = +static struct rk_sensor_reg sensor_Effect_Bluish[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_Effect_Green[] = -{ - {SEQUENCE_END, 0x00, 0, 0} -}; -#endif -static struct reginfo sensor_Effect_Solarize[] = +static struct rk_sensor_reg sensor_Effect_Green[] = { - {0x098e,0xdc38, WORD_LEN, 0}, - {0xdc38,0x05, BYTE_LEN, 0 }, - {0xdc39,0x20, BYTE_LEN, 0 }, - {0x8404,0x06, BYTE_LEN, 0 }, - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Solarize,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {SEQUENCE_END, 0x00} +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 reginfo sensor_Exposure1[]= +static struct rk_sensor_reg sensor_Exposure0[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure2[]= +static struct rk_sensor_reg sensor_Exposure1[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure3[]= +static struct rk_sensor_reg sensor_Exposure2[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure4[]= +static struct rk_sensor_reg sensor_Exposure3[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure5[]= +static struct rk_sensor_reg sensor_Exposure4[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Exposure6[]= +static struct rk_sensor_reg sensor_Exposure5[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= +static struct rk_sensor_reg sensor_Exposure6[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Saturation1[]= -{ - {SEQUENCE_END, 0x00} +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, }; -static struct reginfo sensor_Saturation2[]= +static struct rk_sensor_reg sensor_Saturation0[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= +static struct rk_sensor_reg sensor_Saturation1[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast1[]= +static struct rk_sensor_reg sensor_Saturation2[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; -static struct reginfo sensor_Contrast2[]= +static struct rk_sensor_reg sensor_Contrast0[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast3[]= +static struct rk_sensor_reg sensor_Contrast1[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast4[]= +static struct rk_sensor_reg sensor_Contrast2[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; - -static struct reginfo sensor_Contrast5[]= +static struct rk_sensor_reg sensor_Contrast3[]= { - {SEQUENCE_END, 0x00} + SensorEnd }; -static struct reginfo sensor_Contrast6[]= +static struct rk_sensor_reg sensor_Contrast4[]= { - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, + SensorEnd }; -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {SEQUENCE_END, 0x00, 0, 0} -}; -static struct reginfo sensor_MirrorOff[]= +static struct rk_sensor_reg sensor_Contrast5[]= { - {SEQUENCE_END, 0x00, 0, 0} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_FlipOff[]= +static struct rk_sensor_reg sensor_Contrast6[]= { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif - -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = +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[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_SceneNight[] = +static struct rk_sensor_reg sensor_SceneNight[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif +static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = +static struct rk_sensor_reg sensor_Zoom0[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_Zoom1[] = +static struct rk_sensor_reg sensor_Zoom1[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_Zoom2[] = +static struct rk_sensor_reg sensor_Zoom2[] = { - {SEQUENCE_END, 0x00, 0, 0} + SensorEnd }; -static struct reginfo sensor_Zoom3[] = -{ - {SEQUENCE_END, 0x00, 0, 0} -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL}; -#endif -static const struct v4l2_querymenu sensor_menus[] = +static struct rk_sensor_reg sensor_Zoom3[] = { - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "negative", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "sepia", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "solarize", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif + SensorEnd }; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -static struct v4l2_queryctrl sensor_controls[] = +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = { - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - { - .id = V4L2_CID_FOCUSZONE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "FocusZone Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - },{ - .id = V4L2_CID_FOCUS_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Focus Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - },/*{ - .id = V4L2_CID_FOCUS_CONTINUOUS, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Focus Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - },*/ - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 2, - //.maximum = 3 - .step = 1, - .default_value = 0, - }, - #endif }; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = { - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), }; -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; +//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}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; +static struct soc_camera_ops sensor_ops; -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - return NULL; -} +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; -enum sensor_wq_cmd -{ - WqCmd_af_init, - WqCmd_af_single, - WqCmd_af_special_pos, - WqCmd_af_far_pos, - WqCmd_af_near_pos, - WqCmd_af_continues, - WqCmd_af_return_idle, -}; -enum sensor_wq_result -{ - WqRet_success = 0, - WqRet_fail = -1, - WqRet_inval = -2 -}; -struct sensor_work +/* +********************************************************** +* 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) { - struct i2c_client *client; - struct delayed_work dwork; - enum sensor_wq_cmd cmd; - wait_queue_head_t done; - enum sensor_wq_result result; - bool wait; - int var; - int zone_center_pos[2]; -}; -typedef struct sensor_info_priv_s + SENSOR_DG("%s",__FUNCTION__); + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) { - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int auto_focus; - int affm_reinit; - int flash; - int exposure; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - bool snap2preview; - bool video2preview; - int capture_w; - int capture_h; - int preview_w; - int preview_h; - struct reginfo *winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int enable; - unsigned int funmodule_state; -} sensor_info_priv_t; - - - -struct sensor_parameter + SENSOR_DG("%s",__FUNCTION__); + 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) { - unsigned short int preview_maxlines; - unsigned short int preview_exposure; - unsigned short int preview_line_width; - unsigned short int preview_gain; - - unsigned short int capture_framerate; - unsigned short int preview_framerate; -}; -struct sensor + return 0; +} +/* +* 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) { - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - struct sensor_parameter parameter; - struct workqueue_struct *sensor_wq; - struct sensor_work sensor_wk; - struct mutex wq_lock; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; + int i,cnt,time,ret=0; + char seq_state; + if ((mf->width == 2592) && (mf->height == 1944)) { + + /*check state of register 0x8405 to make sure set is successful*/ + /*set sensor_Preview2Capture more times to make sure set go into effect */ + cnt = 0; + time =0; + do{ + ret = 0; + msleep(50); + ret = sensor_read_reg2val1(client,0x8405, &seq_state); + if (ret<0) { + SENSOR_TR("read register(0x8405) failed"); + goto sensor_s_fmt_cb_bh_end; + } + + if(cnt++ > 9) { + time++; + cnt = 0; + ret = sensor_write_array(client, sensor_fullres_lowfps_data); + if (ret != 0||time >2) { + SENSOR_TR("switch preview to capture failed 0x%x %d",ret,time); + goto sensor_s_fmt_cb_bh_end; + } + } + } while((seq_state != 0x07) && (time < 4)); + } else if ((mf->width == 1280) && (mf->height == 720)) { + for (i=0;i<3;i++) + generic_sensor_write_array(client, sensor_720p); + } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); - -static struct sensor* to_sensor(const struct i2c_client *client) +sensor_s_fmt_cb_bh_end: + return ret; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) { - return container_of(i2c_get_clientdata(client), struct sensor, subdev); + return 0; } - -static int sensor_task_lock(struct i2c_client *client, int lock) +static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) { -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } + return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif } -/*sensor register write */ -static int sensor_write(struct i2c_client *client, struct reginfo *reg_info) +static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) { - int err=0,cnt; - u8 buf[4]; - struct i2c_msg msg[1]; - - switch (reg_info->reg) - { - case SEQUENCE_WAIT_MS: - { - if (in_atomic()) - mdelay(reg_info->val); - else - msleep(reg_info->val); - break; - } - - case SEQUENCE_WAIT_US: - { - udelay(reg_info->val); - break; - } - case SEQUENCE_PROPERTY: - { - break; - } - default: - { - buf[0] = reg_info->reg >> 8; - buf[1] = reg_info->reg & 0xFF; - if (reg_info->reg_len == WORD_LEN) { - buf[2] = reg_info->val >> 8; - buf[3] = reg_info->val & 0xFF; - msg->len = 4; - } else if (reg_info->reg_len == BYTE_LEN) { - buf[2] = reg_info->val; - msg->len = 3; - } - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); - udelay(10); - } - } - } - } - return err; + return 0; } -/** - *sensor_write_Multiple_data - sensor register write with Multiple data - * @i2c_client: - * @reg_info: the first register address - * @count: data number - * - * Returns negative errno, else the number of messages executed. - * - * Note that it - */ -static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo *reg_info, int count) +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) { - int err=0,cnt; - int i=0; - int sum =0; - struct reginfo *tmpval = NULL; - u8 *buf; - struct i2c_msg msg[1]; - tmpval = reg_info; - - if(count < 1 || tmpval==NULL||tmpval->reg==0x0000) - return -EINVAL; - - memset((char*)&msg[0],0,sizeof(struct i2c_msg)); - buf = kmalloc((count*2+10)*sizeof(u8),GFP_KERNEL); - if (buf == NULL) { - SENSOR_TR("%s %s fail,because kmalloc failed",SENSOR_NAME_STRING(),__FUNCTION__); - err = -1; - goto sensor_write_Multiple_data_end; - } - memset(buf,0,sizeof(buf)); - - switch (reg_info->reg) - { - case SEQUENCE_WAIT_MS: - { - if (in_atomic()) - mdelay(reg_info->val); - else - msleep(reg_info->val); - break; - } - - case SEQUENCE_WAIT_US: - { - udelay(reg_info->val); - break; - } - - case SEQUENCE_PROPERTY: - { - break; - } - default: - { - - buf[0] = tmpval->reg >> 8; - buf[1] = tmpval->reg & 0xFF; - i= 2; - if (tmpval->reg_len == WORD_LEN) - { - sum = (count+1)*2; - while(ival >> 8; - buf[i+1] = tmpval->val & 0xFF; - i=i+2; - tmpval++; - } - msg->len = sum; - } else if (tmpval->reg_len == BYTE_LEN) { - sum = count+2; - while(ival; - i++; - tmpval++; - } - msg->len = sum; - } - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); - udelay(10); - } - } - } + //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; } -sensor_write_Multiple_data_end: - if (buf) { - kfree(buf); - buf = NULL; - } - return err; + return 0; } -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u16 reg, u16 *val) +static int sensor_resume(struct soc_camera_device *icd) { - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[2]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 2; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - return err; -} + SENSOR_DG("Resume"); -static int sensor_read1(struct i2c_client *client, struct reginfo *reg_info) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[2]; - - buf[0] = reg_info->reg >> 8; - buf[1] = reg_info->reg & 0xFF; - - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - if (reg_info->reg_len == WORD_LEN) { - msg[1].len = 2; - } else if (reg_info->reg_len == BYTE_LEN) { - msg[1].len = 1; - } - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - if (reg_info->reg_len == WORD_LEN) { - reg_info->val = buf[0]; - reg_info->val <<= 8; - reg_info->val |= buf[1]; - } else if (reg_info->reg_len == BYTE_LEN) { - reg_info->val = buf[0]; - } - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); - udelay(10); - } - } + return 0; - return err; } - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +static int sensor_mirror_cb (struct i2c_client *client, int mirror) { - int err = 0, cnt; - int i = 0,j=0; - int num = 0; - u16 temp = 0; - -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - cnt = 0; - - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - // SENSOR_TR("%s ..%s..\n",SENSOR_NAME_STRING(),__FUNCTION__); - - while (regarray[i].reg != SEQUENCE_END) { - num =1; - j= i+1; - #if 0 - while((regarray[j].reg_len ==regarray[i].reg_len)&®array[j].reg != SEQUENCE_END) - { - temp = regarray[j].reg - regarray[j-1].reg; - if((regarray[j].reg_len==WORD_LEN && temp!=0x0002)||(regarray[j].reg_len==BYTE_LEN && temp!=0x0001)) - break; - num++; - j++; - } - #endif - err = sensor_write_Multiple_data(client, ®array[i], num) ; - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - - i=i+num; - } -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} + int err =0; + SENSOR_DG("mirror: %d",mirror); -/* write sensor initial data */ -static int sensor_write_init_data(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; - int num = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - int ti=0; - int table[167] = { /*written data numbers every time*/ - 3,1,1,3,1,1,1,1,11,2,2,13,1,1,1,2,11,2,2,13, - 1,2,1,1,2,1,1,1,1,1,8,1,1,1,1,1,1,714,1,1, - 1,1,1,1,1,42,1,3,9,1,1,2,2,1,1,1,1,3,1,1, - 1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,8,2,2,2, - 2,2,1,1,1,1,10,10,9,6,4,2,9,2,2,2,1,1,1,1, - 1,1,1,1,1,1,1,1,58,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,3,3,2,1,1,1,1,1, 2,2,1, - 6,3,1,1,1,1,1,6,1,2,4,4,1,1,1,4,5,2,2,4, - 4,6,1,1,1,1,1 - }; - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != SEQUENCE_END) { - #if 0 - if(ti < 167){ - num = table[ti]; - ti++; - } - #else - num = 1; - #endif - err = sensor_write_Multiple_data(client, ®array[i], num) ; - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i=i+num; - } -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if 0 -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != SEQUENCE_END) { - - err = sensor_write(client, ®array[i]); - - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } -sensor_write_array_end: - sensor_task_lock(client,0); - return err; + return err; } -#endif -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +/* +* 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) { - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != SEQUENCE_END) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; } -#endif -#if CONFIG_SENSOR_Focus +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + int err =0; + SENSOR_DG("flip: %d",flip); -static struct reginfo sensor_af_trigger[] = -{ - { 0xB854, 0x4040, WORD_LEN, 0}, // STAT_SM_WINDOW_POS_X; POS_Y - { 0xB856, 0x4040, WORD_LEN, 0}, // STAT_SM_WINDOW_SIZE_X; SIZE_Y - { 0xB006, 0x01, BYTE_LEN, 0}, //run AF - af.progress - {SEQUENCE_END, 0x00, 0, 0} -}; -static int sensor_af_touch_zone(struct i2c_client *client, int *zone_center_pos) + return err; +} +/* +* 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) { - int ret = 0; - - zone_center_pos[0] = zone_center_pos[0]*0x100/2000; - zone_center_pos[1] = zone_center_pos[1]*0x100/2000; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - zone_center_pos[0] = zone_center_pos[0]/0x40*0x40; - zone_center_pos[1] = zone_center_pos[1]/0x40*0x40; + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* the functions are focus callbacks +*/ - sensor_af_trigger[0].val = (zone_center_pos[0]<<8)|zone_center_pos[1]; - -sensor_af_zone_end: - return ret; +static int sensor_focus_init_usr_cb(struct i2c_client *client) +{ + return 0; } -static int sensor_af_single(struct i2c_client *client) +static struct rk_sensor_reg sensor_af_trigger[] = { + { 0xB854, 0x4040, 0xffff, 0xffff}, // STAT_SM_WINDOW_POS_X; POS_Y + { 0xB856, 0x4040, 0xffff, 0xffff}, // STAT_SM_WINDOW_SIZE_X; SIZE_Y + { 0xB006, 0x01, 0xffff, 0xff}, //run AF - af.progress + SensorEnd +}; +static int sensor_focus_af_single_usr_cb(struct i2c_client *client){ int ret = 0; char cnt=0; - struct reginfo reg; + struct rk_sensor_reg reg; ret = sensor_write_array(client, sensor_af_trigger); if (ret<0) { SENSOR_TR("%s sensor auto focus trigger fail!!\n",SENSOR_NAME_STRING()); } else { - - reg.reg_len = BYTE_LEN; reg.reg = 0xb006; reg.val = 0x01; - + reg.reg_mask = 0xffff; + reg.val_mask = 0xff; do { msleep(30); - sensor_read1(client,®); - + generic_sensor_read(client,®); } while ((reg.val != 0) && (cnt++ < 50)); SENSOR_DG("%s sensor auto focus trigger(0x%x) success! state: %d, cnt: %d\n",SENSOR_NAME_STRING(), sensor_af_trigger[0].val,reg.val,cnt); } - - sensor_af_single_end: return ret; } -static int sensor_af_const(struct i2c_client *client) -{ - int ret = 0; +static int sensor_focus_af_near_usr_cb(struct i2c_client *client){ + return 0; +} -sensor_af_const_end: - return ret; +static int sensor_focus_af_far_usr_cb(struct i2c_client *client){ + return 0; } -static int sensor_af_init(struct i2c_client *client) -{ - int ret = 0; - return 0; +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos) { + return 0; } -static int sensor_af_downfirmware(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - int ret=0; - struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_mbus_framefmt mf; - - SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__); - - if (sensor_af_init(client)) { - sensor->info_priv.funmodule_state &= (~SENSOR_AF_IS_OK); - ret = -1; - } else { - sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; - - mf.width = icd->user_width; - mf.height = icd->user_height; - mf.code = sensor->info_priv.fmt.code; - mf.colorspace = sensor->info_priv.fmt.colorspace; - mf.field = V4L2_FIELD_NONE; - if (sensor_fmt_videochk(NULL, &mf) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ - ret = sensor_af_const(client); - } else { - switch (sensor->info_priv.auto_focus) - { - case SENSOR_AF_MODE_AUTO: - { - ret = sensor_af_single(client); - break; - } - case SENSOR_AF_MODE_CLOSE: - { - ret = 0; - break; - } - case SENSOR_AF_MODE_CONTINUOUS: - { - ret = sensor_af_const(client); - break; - } - default: - { - SENSOR_DG("%s focus mode(0x%x) is unkonwn\n",SENSOR_NAME_STRING(),sensor->info_priv.auto_focus); - goto sensor_af_downfirmware_end; - } - } - } - SENSOR_DG("%s sensor_af_downfirmware set focus mode(0x%x) ret:0x%x\n",SENSOR_NAME_STRING(), sensor->info_priv.auto_focus,ret); - } -sensor_af_downfirmware_end: - - return ret; +static int sensor_focus_af_const_usr_cb(struct i2c_client *client){ + return 0; } -static void sensor_af_workqueue(struct work_struct *work) -{ - struct sensor_work *sensor_work = container_of(work, struct sensor_work, dwork.work); - struct i2c_client *client = sensor_work->client; - struct sensor *sensor = to_sensor(client); - //struct af_cmdinfo cmdinfo; - - SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd); - - mutex_lock(&sensor->wq_lock); - - switch (sensor_work->cmd) - { - case WqCmd_af_init: - { - if (sensor_af_downfirmware(client) < 0) { - SENSOR_TR("%s Sensor_af_init is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); - } - break; - } - case WqCmd_af_single: - { - if ((sensor_work->zone_center_pos[0] >=0) && (sensor_work->zone_center_pos[1]>=0)) - sensor_af_touch_zone(client,sensor_work->zone_center_pos); - - if (sensor_af_single(client) < 0) { - SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); - sensor_work->result = WqRet_fail; - } else { - sensor_work->result = WqRet_success; - } - break; - } - #if 0 - case WqCmd_af_special_pos: - { - sensor_af_idlechk(client); - - cmdinfo.cmd_tag = StepFocus_Spec_Tag; - cmdinfo.cmd_para[0] = sensor_work->var; - cmdinfo.validate_bit = 0x81; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_near_pos: - { - sensor_af_idlechk(client); - cmdinfo.cmd_tag = StepFocus_Near_Tag; - cmdinfo.validate_bit = 0x80; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_far_pos: - { - sensor_af_idlechk(client); - cmdinfo.cmd_tag = StepFocus_Far_Tag; - cmdinfo.validate_bit = 0x80; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - #endif - case WqCmd_af_continues: - { - if (sensor_af_const(client) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - #if 0 - case WqCmd_af_return_idle: - { - if (sensor_af_idlechk(client) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - #endif - default: - SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING()); - break; - } -set_end: - if (sensor_work->wait == false) { - kfree((void*)sensor_work); - } else { - wake_up(&sensor_work->done); - } - mutex_unlock(&sensor->wq_lock); - return; +static int sensor_focus_af_close_usr_cb(struct i2c_client *client){ + return 0; } -static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait, int *zone_pos) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - struct sensor_work *wk; - int ret=0; - - if (sensor->sensor_wq == NULL) { - ret = -EINVAL; - goto sensor_af_workqueue_set_end; - } +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client,int *zone_tm_pos){ + int ret = 0; + int zone_center_pos[2]; - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) != SENSOR_AF_IS_OK) { - if (cmd != WqCmd_af_init) { - SENSOR_TR("%s %s cmd(%d) ingore,because af module isn't ready!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - ret = -1; - goto sensor_af_workqueue_set_end; - } - } + zone_tm_pos[0] += 1000; + zone_tm_pos[1] += 1000; + zone_tm_pos[2] += 1000; + zone_tm_pos[3] += 1000; + zone_center_pos[0] = ((zone_tm_pos[0] + zone_tm_pos[2])>>1); + zone_center_pos[1] = ((zone_tm_pos[1] + zone_tm_pos[3])>>1); - wk = kzalloc(sizeof(struct sensor_work), GFP_KERNEL); - if (wk) { - wk->client = client; - INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue); - wk->cmd = cmd; - wk->result = WqRet_inval; - wk->wait = wait; - wk->var = var; - - if (zone_pos) { - *zone_pos += 1000; - *(zone_pos+1) += 1000; - *(zone_pos+2) += 1000; - *(zone_pos+3) += 1000; - wk->zone_center_pos[0] = ((*zone_pos + *(zone_pos+2))>>1); - wk->zone_center_pos[1] = ((*(zone_pos+1) + *(zone_pos+3))>>1); - } - - init_waitqueue_head(&wk->done); - - /* ddl@rock-chips.com: - * video_lock is been locked in v4l2_ioctl function, but auto focus may slow, - * As a result any other ioctl calls will proceed very, very slowly since each call - * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF - * and VIDIOC_DQBUF is sched. so unlock video_lock here. - */ - if (wait == true) { - queue_delayed_work(sensor->sensor_wq,&(wk->dwork),0); - mutex_unlock(&icd->video_lock); - if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) { //hhb - SENSOR_TR("%s %s cmd(%d) is timeout!\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - } - ret = wk->result; - kfree((void*)wk); - mutex_lock(&icd->video_lock); - } else { - queue_delayed_work(sensor->sensor_wq,&(wk->dwork),msecs_to_jiffies(10)); - } - - } else { - SENSOR_TR("%s %s cmd(%d) ingore,because struct sensor_work malloc failed!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - ret = -1; - } -sensor_af_workqueue_set_end: - return ret; -} -#endif - -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - printk( "Sensor_Flash on = %d\n", on ); -#if 0 - if(on){ - //flash off after 2 secs - if ( flash_off_timer.status ){ - hrtimer_cancel(&(flash_off_timer.timer)); - } - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - flash_off_timer.status = 1; - }else{ - flash_off_timer.status = 0; - } -#endif - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } - -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *hrtimer){ - struct flash_timer *fps_timer = container_of(hrtimer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - printk("%s %s = 0x%x !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__, fps_timer ); - return 0; -} - -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); -#if (ADJUST_OPTIMIZE_TIME_FALG == 0) - const struct v4l2_queryctrl *qctrl; -#endif - const struct sensor_datafmt *fmt; - int ret,pid = 0; - int index =0 ; -#if (SENSOR_RESET_REG != SEQUENCE_END) - struct reginfo reg_info; -#endif - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - SENSOR_DG("\n soft reset..%s.\n",SENSOR_NAME_STRING()); - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - -#if (SENSOR_RESET_REG != SEQUENCE_END) - reg_info.reg = SENSOR_RESET_REG; - reg_info.val = SENSOR_RESET_VAL; - reg_info.reg_len = SENSOR_RESET_REG_LEN; - ret = sensor_write(client, ®_info); - if (ret != 0) { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - mdelay(5); //delay 5 microseconds -#endif - - /* check if it is an sensor sensor */ -#if (SENSOR_ID_REG != SEQUENCE_END) - ret = sensor_read(client, SENSOR_ID_REG, &pid); - if (ret != 0) { - SENSOR_TR("read chip id failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); -#else - pid = SENSOR_ID; -#endif - - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING()); - - ret =sensor_write_init_data(client, sensor_init_data); - if (ret != 0) { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - sensor->info_priv.preview_w = SENSOR_INIT_WIDTH; - sensor->info_priv.preview_h = SENSOR_INIT_HEIGHT; - sensor->info_priv.capture_w = SENSOR_MAX_WIDTH; - sensor->info_priv.capture_h = SENSOR_MAX_HEIGHT; - sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ -#if ADJUST_OPTIMIZE_TIME_FALG - SENSOR_DG("\n optimize code..%s.\n",SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_WhiteBalance - sensor->info_priv.whiteBalance = 0; - #endif - #if CONFIG_SENSOR_Brightness - sensor->info_priv.brightness = 0; - #endif - #if CONFIG_SENSOR_Effect - sensor->info_priv.effect = 0; - #endif - #if CONFIG_SENSOR_Exposure - sensor->info_priv.exposure = 0; - #endif - #if CONFIG_SENSOR_Saturation - sensor->info_priv.saturation = 0; - #endif - #if CONFIG_SENSOR_Contrast - sensor->info_priv.contrast = 0; - #endif - #if CONFIG_SENSOR_Mirror - sensor->info_priv.mirror = 1; - #endif - #if CONFIG_SENSOR_Flip - sensor->info_priv.flip = 1; - index++; - #endif - #if CONFIG_SENSOR_Scene - sensor->info_priv.scene = 0; - index++; - #endif - #if CONFIG_SENSOR_DigitalZoom - sensor->info_priv.digitalzoom = 0; - #endif - #if CONFIG_SENSOR_Focus - sensor->info_priv.focus = 125 ; - if (sensor_af_init(client) < 0) { - sensor->info_priv.funmodule_state &= ~SENSOR_AF_IS_OK; - SENSOR_TR("%s auto focus module init is fail!\n",SENSOR_NAME_STRING()); - } else { - sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; - SENSOR_DG("%s auto focus module init is success!\n",SENSOR_NAME_STRING()); - } - #endif - #if CONFIG_SENSOR_Flash - sensor->info_priv.flash = 0 ; - #endif - -#else - SENSOR_DG("\n origin code..%s.\n",SENSOR_NAME_STRING()); - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - - #if CONFIG_SENSOR_Focus - if (sensor_af_init(client) < 0) { - sensor->info_priv.funmodule_state &= ~SENSOR_AF_IS_OK; - SENSOR_TR("%s auto focus module init is fail!\n",SENSOR_NAME_STRING()); - } else { - sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; - SENSOR_DG("%s auto focus module init is success!\n",SENSOR_NAME_STRING()); - } - #endif - #ifdef CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - printk( "flash_off_timer.timer.function\n" ); - - #endif -#endif - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - - - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend..pm_msg.event=%d \n", SENSOR_NAME_STRING(),pm_msg.event); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - return 0; -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h) -{ - struct reginfo *winseqe_set_addr = NULL; - - if (set_w*240 == set_h*320) { - if (((set_w >= 320) && (set_h >= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qvga; - *ret_w = 320; - *ret_h = 240; - } - -#if ADJUST_FOR_VGA_FALG - // to forbid preview err - if (((set_w >= 576) && (set_h >= 432)) && (sensor_vga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_vga; - *ret_w = 576; - *ret_h = 432; - } -#else - if (((set_w >= 640) && (set_h >= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_vga; - *ret_w = 640; - *ret_h = 480; - } - -#endif - - if (((set_w >= 800) && (set_h >= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_svga; - *ret_w = 800; - *ret_h = 600; - } - - if (((set_w >= 1024) && (set_h >= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_xga; - *ret_w = 1024; - *ret_h = 768; - } - - if (((set_w >= 1280) && (set_h >= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_sxga; - *ret_w = 1280; - *ret_h = 1024; - } - - if (((set_w >= 1600) && (set_h >= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_uxga; - *ret_w = 1600; - *ret_h = 1200; - } - - if (((set_w >= 2048) && (set_h >= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qxga; - *ret_w = 2048; - *ret_h = 1536; - } - - if (((set_w >= 2592) && (set_h >= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qsxga; - *ret_w = 2592; - *ret_h = 1944; - } - - if (winseqe_set_addr == NULL) { - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qcif; - *ret_w = 176; - *ret_h = 144; - } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_cif; - *ret_w = 352; - *ret_h = 288; - } - - if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_720p; - *ret_w = 1280; - *ret_h = 720; - } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_1080p; - *ret_w = 1920; - *ret_h = 1080; - } - } - - } else if (set_w*288 == set_h*352) { - if (((set_w >= 176) && (set_h >= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qcif; - *ret_w = 176; - *ret_h = 144; - } else if (((set_w >= 352) && (set_h >= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_cif; - *ret_w = 352; - *ret_h = 288; - } - - if (winseqe_set_addr == NULL) { - if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qvga; - *ret_w = 320; - *ret_h = 240; - } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_vga; - *ret_w = 640; - *ret_h = 480; - } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_svga; - *ret_w = 800; - *ret_h = 600; - } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_xga; - *ret_w = 1024; - *ret_h = 768; - } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_sxga; - *ret_w = 1280; - *ret_h = 1024; - } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_uxga; - *ret_w = 1600; - *ret_h = 1200; - } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qxga; - *ret_w = 2048; - *ret_h = 1536; - } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qsxga; - *ret_w = 2592; - *ret_h = 1944; - } - - - if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_720p; - *ret_w = 1280; - *ret_h = 720; - } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_1080p; - *ret_w = 1920; - *ret_h = 1080; - } - } - } else if (set_w*720 == set_h*1280) { - if (((set_w >= 1280) && (set_h >= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_720p; - *ret_w = 1280; - *ret_h = 720; - } else if (((set_w >= 1920) && (set_h >= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_1080p; - *ret_w = 1920; - *ret_h = 1080; - } - - if (winseqe_set_addr == NULL) { - - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qcif; - *ret_w = 176; - *ret_h = 144; - } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_cif; - *ret_w = 352; - *ret_h = 288; - } - - if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qvga; - *ret_w = 320; - *ret_h = 240; - } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_vga; - *ret_w = 640; - *ret_h = 480; - } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_svga; - *ret_w = 800; - *ret_h = 600; - } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_xga; - *ret_w = 1024; - *ret_h = 768; - } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_sxga; - *ret_w = 1280; - *ret_h = 1024; - } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_uxga; - *ret_w = 1600; - *ret_h = 1200; - } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qxga; - *ret_w = 2048; - *ret_h = 1536; - } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qsxga; - *ret_w = 2592; - *ret_h = 1944; - } - } - } else { - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qcif; - *ret_w = 176; - *ret_h = 144; - } else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qvga; - *ret_w = 320; - *ret_h = 240; - } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_cif; - *ret_w = 352; - *ret_h = 288; - } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_vga; - *ret_w = 640; - *ret_h = 480; - } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_svga; - *ret_w = 800; - *ret_h = 600; - } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_xga; - *ret_w = 1024; - *ret_h = 768; - } else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_720p; - *ret_w = 1280; - *ret_h = 720; - } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_sxga; - *ret_w = 1280; - *ret_h = 1024; - } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_uxga; - *ret_w = 1600; - *ret_h = 1200; - } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_1080p; - *ret_w = 1920; - *ret_h = 1080; - } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qxga; - *ret_w = 2048; - *ret_h = 1536; - } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { - winseqe_set_addr = sensor_qsxga; - *ret_w = 2592; - *ret_h = 1944; - } - } - - return winseqe_set_addr; -} - -/*modify image with resolution 2592*1944;solve bug that the first 32 pixel data*/ -/*in the first line have misplace with the last 32 pixel data in the last line*/ -static int sensor_cb(void *arg) -{ - void __iomem *vbpmem; - struct videobuf_buffer *buffer; - char *imagey_addr =NULL; - char *imageuv_addr = NULL; - char *tempaddr = NULL; - int tempsize = 0; - - buffer = (struct videobuf_buffer*)arg; - if(buffer->width!=SENSOR_MAX_WIDTH||buffer->height!=SENSOR_MAX_HEIGHT||buffer==NULL) - return -EINVAL; - - if (buffer->bsize< YUV420_BUFFER_MAX_SIZE) //yuv420 format size - return -EINVAL; - - - vbpmem = ioremap(buffer->boff,buffer->bsize); - if(vbpmem == NULL) { - SENSOR_DG("\n%s..%s..ioremap fail\n",__FUNCTION__,SENSOR_NAME_STRING()); - return -ENXIO; - } - - imagey_addr = (char*)vbpmem; // y data to be dealed with - imageuv_addr = imagey_addr+buffer->width*buffer->height; - - tempaddr = imageuv_addr - 32; - memcpy(tempaddr,imagey_addr,32); - - tempaddr = imagey_addr+32; - memcpy(imagey_addr,tempaddr,32); - - //uv data to be dealed with - tempsize = YUV420_BUFFER_MAX_SIZE-32; - tempaddr = imagey_addr+tempsize; - memcpy(tempaddr,imageuv_addr,32); - - tempaddr = imageuv_addr+32; - memcpy(imageuv_addr,tempaddr,32); - return 0; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - struct reginfo *winseqe_set_addr=NULL; - int ret = 0, set_w,set_h,cnt; - u16 seq_state=0; - int time = 0; - u16 targetbrightness,realbrightness; - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h); - - if ((winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) && winseqe_set_addr) - { - /*solve bug that video set is ineffective */ - /*set five times to make sure sensor_720p set go into effect*/ - if(winseqe_set_addr==sensor_720p) - { - time = 5; - }else{ - time = 1; - } - - while(time > 0) - { - time--; - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - goto sensor_s_fmt_end; - } - udelay(10); - } - sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; - if (winseqe_set_addr==sensor_qxga ||winseqe_set_addr==sensor_qsxga||winseqe_set_addr==sensor_uxga ||winseqe_set_addr==sensor_xga) - { - SENSOR_DG("\n%s..%s..Capture icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } else { - SENSOR_DG("\n%s..%s..Video icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - sensor->info_priv.preview_w = mf->width; - sensor->info_priv.preview_h = mf->height; - } - } - - if (winseqe_set_addr && (winseqe_set_addr==sensor_qxga ||winseqe_set_addr==sensor_qsxga||winseqe_set_addr==sensor_uxga ||winseqe_set_addr==sensor_xga)) - { - ret |= sensor_write_array(client, sensor_Preview2Capture); - if (ret != 0) { - SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING()); - goto sensor_s_fmt_end; - } - - /*check state of register 0x8405 to make sure set is successful*/ - /*set sensor_Preview2Capture more times to make sure set go into effect */ - cnt = 0; - time =0; - do{ - ret = 0; - msleep(50); - ret =sensor_read(client,0x8405, &seq_state); - if (ret < 0) - goto sensor_s_fmt_end; - cnt++; - if(cnt > 9) - { - time++; - cnt = 0; - ret |= sensor_write_array(client, sensor_Preview2Capture); - if (ret != 0||time >2) { - SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING()); - goto sensor_s_fmt_end; - } - SENSOR_DG("mt9p111 Preview 2 Capture again\n"); - } - SENSOR_DG("mt9p111 Preview 2 Capture count = %d;seq_state = 0x%x\n",cnt,seq_state); - } while((seq_state != 0x07) && (time < 4)); - - SENSOR_TR("%s Preview 2 Capture successs\n", SENSOR_NAME_STRING()); - - #if CONFIG_SENSOR_Flash - /*The 0xA409 is AE target register address.*/ - /*The 0xB804 is currently total brightness Y value of sensor.*/ - targetbrightness = 0; - realbrightness =0; - if((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) - { - if(sensor->info_priv.flash == 1) - { - ret =sensor_read(client,0xA409, &targetbrightness); - if (ret < 0) - SENSOR_DG("%s ..%s..get targetbrightness fail\n", SENSOR_NAME_STRING(),__FUNCTION__); - - ret =sensor_read(client, 0xB804, &realbrightness); - if (ret < 0) - SENSOR_DG("%s ..%s..get realbrightness fail\n", SENSOR_NAME_STRING(),__FUNCTION__); - } - - if((realbrightness < targetbrightness)|| (sensor->info_priv.flash == 2)) - { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on,realbrightness=%d,targetbrightness=%d\n", SENSOR_NAME_STRING(),realbrightness,targetbrightness); - }else{ - SENSOR_DG("%s not need to flash in capture!\n", SENSOR_NAME_STRING()); - } - } - #endif - sensor->info_priv.capture_w = set_w; - sensor->info_priv.capture_h = set_h; - sensor->info_priv.snap2preview = true; - } else if (sensor->info_priv.snap2preview == true) { - if (winseqe_set_addr || ((sensor->info_priv.preview_w == mf->width) && (sensor->info_priv.preview_h == mf->height))) { - ret |= sensor_write_array(client, sensor_Capture2Preview); - if (ret != 0) { - SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING()); - goto sensor_s_fmt_end; - } - - cnt = 0; - do{ //check state of register 0x8405 to make sure set is successful - ret = 0; - msleep(50); - ret =sensor_read(client,0x8405, &seq_state); - if (ret < 0) - goto sensor_s_fmt_end; - SENSOR_DG("mt9p111 Capture 2 Preview seq_state = 0x%x\n",seq_state); - } while((seq_state != 0x03) && (cnt < 20)); - - SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING()); - - #if CONFIG_SENSOR_Flash - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - #endif - sensor->info_priv.preview_w = mf->width; - sensor->info_priv.preview_h = mf->height; - sensor->info_priv.snap2preview = false; - } else { - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - } - - mf->width = set_w; - mf->height = set_h; -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - if (sensor_fmt_catch(mf->width, mf->height, &mf->width, &mf->height) == NULL) { - mf->width = 0; - mf->height = 0; - } - mf->colorspace = fmt->colorspace; - - return ret; -} - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - int time =5; - int ret =0 ; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - /*set five times to make sure the set go into effect*/ - /*solve bug for setting invalidate during changing from preview to video*/ - while(time >0) - { - time--; - ret |=sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]); - if(ret != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - msleep(50); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - printk("=====sensor_set_flash====== Flash On\n"); - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - printk("=====sensor_set_flash====== Flash off\n"); - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Focus -static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int ret = 0; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (!qctrl_info) - return -EINVAL; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { - - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EINVAL; - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - } - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } - -sensor_set_focus_absolute_end: - return ret; -} -static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int ret = 0; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE); - if (!qctrl_info) - return -EINVAL; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { - - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EINVAL; - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - } - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } -sensor_set_focus_relative_end: - return ret; -} - -static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int *zone_pos) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int ret = 0; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - switch (value) - { - case SENSOR_AF_MODE_AUTO: - { - ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true, zone_pos); - break; - } - - /*case SENSOR_AF_MODE_MACRO: - { - ret = sensor_set_focus_absolute(icd, qctrl, 0xff); - break; - } - - case SENSOR_AF_MODE_INFINITY: - { - ret = sensor_set_focus_absolute(icd, qctrl, 0x00); - break; - } - */ - case SENSOR_AF_MODE_CONTINUOUS: - { - ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true,NULL); - break; - } - default: - SENSOR_TR("\n %s..%s AF value(0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,value); - break; - - } - - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } - - return ret; - -} -#endif -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - #if 0 - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (sensor_set_focus_absolute(icd, qctrl,ext_ctrl->value) == 0) { - if (ext_ctrl->value == qctrl->minimum) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_INFINITY; - } else if (ext_ctrl->value == qctrl->maximum) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_MACRO; - } else { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_FIXED; - } - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - sensor_set_focus_relative(icd, qctrl,ext_ctrl->value); - break; - } - #endif - case V4L2_CID_FOCUS_AUTO: - { - if (ext_ctrl->value) { - if ((ext_ctrl->value==1) || (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus)) { - if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO,ext_ctrl->rect) != 0) { - if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; - } - return -EINVAL; - } - } - if (ext_ctrl->value == 1) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; - } else if (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus){ - if (ext_ctrl->value == 0) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; - } - break; - } - case V4L2_CID_FOCUS_CONTINUOUS: - { - if (SENSOR_AF_MODE_CONTINUOUS != sensor->info_priv.auto_focus) { - if (ext_ctrl->value == 1) { - if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_CONTINUOUS,NULL) != 0) { - if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; - } - return -EINVAL; - } - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; - } - } else { - if (ext_ctrl->value == 0) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - #if CONFIG_SENSOR_Focus - struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_mbus_framefmt mf; - #endif - - if (enable == 1) { - sensor->info_priv.enable = 1; - #if CONFIG_SENSOR_Focus - mf.width = icd->user_width; - mf.height = icd->user_height; - mf.code = sensor->info_priv.fmt.code; - mf.colorspace = sensor->info_priv.fmt.colorspace; - mf.field = V4L2_FIELD_NONE; - /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ - if (sensor_fmt_capturechk(sd, &mf) == false) { - if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { - sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false,NULL); - sensor->info_priv.affm_reinit = 0; - } - } - #endif - } else if (enable == 0) { - sensor->info_priv.enable = 0; - #if CONFIG_SENSOR_Focus - flush_workqueue(sensor->sensor_wq); - #endif - } - return 0; -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); -#if (SENSOR_RESET_REG != SEQUENCE_END) - struct reginfo reg_info; -#endif - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ -#if (SENSOR_RESET_REG != SEQUENCE_END) - reg_info.reg = SENSOR_RESET_REG; - reg_info.val = SENSOR_RESET_VAL; - reg_info.reg_len = SENSOR_RESET_REG_LEN; - ret = sensor_write(client, ®_info); - if (ret != 0) { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - mdelay(5); //delay 5 microseconds -#endif - - /* check if it is an sensor sensor */ -#if (SENSOR_ID_REG != SEQUENCE_END) - ret = sensor_read(client, SENSOR_ID_REG, &pid); - if (ret != 0) { - SENSOR_TR("read chip id failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); -#else - pid = SENSOR_ID; -#endif - - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; + zone_center_pos[0] = zone_center_pos[0]*0x100/2000; + zone_center_pos[1] = zone_center_pos[1]*0x100/2000; -sensor_video_probe_err: + zone_center_pos[0] = zone_center_pos[0]/0x40*0x40; + zone_center_pos[1] = zone_center_pos[1]/0x40*0x40; + sensor_af_trigger[0].val = (zone_center_pos[0]<<8)|zone_center_pos[1]; + +sensor_af_zone_end: return ret; } -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); -//#if CONFIG_SENSOR_Flash - int i; -//#endif - int ret = 0; - - rk29_camera_sensor_cb_s *icd_cb =NULL; - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - case RK29_CAM_SUBDEV_CB_REGISTER: - { - icd_cb = (rk29_camera_sensor_cb_s*)(arg); - icd_cb->sensor_cb = sensor_cb; - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - *code = sensor_colour_fmts[index].code; +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){ return 0; } -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, - .s_stream = sensor_s_stream, -}; -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - sensor->info_priv.fmt = sensor_colour_fmts[0]; - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } else { - #if CONFIG_SENSOR_Focus - sensor->sensor_wq = create_singlethread_workqueue(SENSOR_NAME_STRING(_af_workqueue)); - if (sensor->sensor_wq == NULL) - SENSOR_TR("%s create fail!", SENSOR_NAME_STRING(_af_workqueue)); - mutex_init(&sensor->wq_lock); - #endif - } - flash_off_timer.status = 0; - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) +/* +* 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) { - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - #if CONFIG_SENSOR_Focus - if (sensor->sensor_wq) { - destroy_workqueue(sensor->sensor_wq); - sensor->sensor_wq = NULL; - } - #endif - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; + return; } -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} +sensor_init_parameters_default_code(); -static void __exit sensor_mod_exit(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - i2c_del_driver(&sensor_i2c_driver); -} +sensor_v4l2_struct_initialization(); -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); +sensor_probe_default_code(); -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); +sensor_remove_default_code(); +sensor_driver_default_module_code(); diff --git a/drivers/media/video/mt9p111_old.c b/drivers/media/video/mt9p111_old.c new file mode 100755 index 000000000000..5d8ef04b7897 --- /dev/null +++ b/drivers/media/video/mt9p111_old.c @@ -0,0 +1,5587 @@ +/* + * Driver for OV5642 CMOS Image Sensor from OmniVision + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "mt9p111.h" + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_MT9P111 +#define SENSOR_V4L2_IDENT V4L2_IDENT_MT9P111 +#define SENSOR_ID SEQUENCE_END +#define SENSOR_ID_REG SEQUENCE_END +#define SENSOR_RESET_REG 0x0010 +#define SENSOR_RESET_VAL 0x0115 +#define SENSOR_RESET_REG_LEN WORD_LEN +#define SENSOR_MIN_WIDTH 176 +#define SENSOR_MIN_HEIGHT 144 +#define SENSOR_MAX_WIDTH 2592 +#define SENSOR_MAX_HEIGHT 1944 +#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 480 +#define SENSOR_INIT_WINSEQADR sensor_vga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define YUV420_BUFFER_MAX_SIZE 7558272 /* 2592*1944*1.5*/ + +#define CONFIG_SENSOR_WhiteBalance 0 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 0 +#define CONFIG_SENSOR_Scene 0 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 0 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 +#define CONFIG_SENSOR_Focus 1 + + +#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ +//#define CONFIG_SENSOR_I2C_SPEED 350000 /* Hz */ + +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + + + +#if CONFIG_SENSOR_Focus +/*#define SENSOR_AF_MODE_INFINITY 0 +#define SENSOR_AF_MODE_MACRO 1 +#define SENSOR_AF_MODE_FIXED 2 +#define SENSOR_AF_MODE_AUTO 3 +#define SENSOR_AF_MODE_CONTINUOUS 4 +#define SENSOR_AF_MODE_CLOSE 5*/ +#define SENSOR_AF_MODE_AUTO 0 +#define SENSOR_AF_MODE_CLOSE 1 +#define SENSOR_AF_MODE_CONTINUOUS 2 +#endif + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + int status; + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_MT9P111_USER_DEFINED_SERIES +#include "mt9p111_user_series.c" +#else + +/* init 640X480 VGA */ +static struct reginfo sensor_init_data[] = +{ +{ 0x0010, 0x0340, WORD_LEN, 0 }, + + +{ 0x0010, 0x0340, WORD_LEN, 0 }, // PLL_DIVIDERS +{ 0x0012, 0x0080, WORD_LEN, 0 }, // PLL_P_DIVIDERS +{ 0x0014, 0x2025, WORD_LEN, 0 }, // PLL_CONTROL +{ 0x001E, 0x0565, WORD_LEN, 0 }, // PAD_SLEW_PAD_CONFIG +{ 0x0022, 0x0030, WORD_LEN, 0 }, // VDD_DIS_COUNTER +{ 0x002A, 0x7FFF, WORD_LEN, 0 }, // PLL_P4_P5_P6_DIVIDERS +{ 0x002C, 0x0000, WORD_LEN, 0 }, // PLL_P7_DIVIDER +{ 0x002E, 0x0000, WORD_LEN, 0 }, // SENSOR_CLOCK_DIVIDER +{ 0x0018, 0x400c, WORD_LEN, 0 }, // STANDBY_CONTROL_AND_STATUS +//delay = 100 +{SEQUENCE_WAIT_MS,300,WORD_LEN,0}, +{ 0x098E, 0x483A, WORD_LEN, 0 }, // LOGICAL_ADDRESS_ACCESS +{ 0xC83A, 0x000C, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_START +{ 0xC83C, 0x0018, WORD_LEN, 0 }, // CAM_CORE_A_X_ADDR_START +{ 0xC83E, 0x07B1, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_END +{ 0xC840, 0x0A45, WORD_LEN, 0 }, // CAM_CORE_A_X_ADDR_END +{ 0xC842, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_ROW_SPEED +{ 0xC844, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_X_CORE +{ 0xC846, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_Y_CORE +{ 0xC848, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_X_PIPE +{ 0xC84A, 0x0103, WORD_LEN, 0 }, // CAM_CORE_A_SKIP_Y_PIPE +{ 0xC84C, 0x00F6, WORD_LEN, 0 }, // CAM_CORE_A_POWER_MODE +{ 0xC84E, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_BIN_MODE +{ 0xC850, 0x00, BYTE_LEN, 0}, // CAM_CORE_A_ORIENTATION +{ 0xC851, 0x00, BYTE_LEN, 0}, // CAM_CORE_A_PIXEL_ORDER +{ 0xC852, 0x019C, WORD_LEN, 0 }, // CAM_CORE_A_FINE_CORRECTION +{ 0xC854, 0x0732, WORD_LEN, 0 }, // CAM_CORE_A_FINE_ITMIN +{ 0xC858, 0x0000, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMIN +{ 0xC85A, 0x0001, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMAX_MARGIN +{ 0xC85C, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_MIN_FRAME_LENGTH_LINES +{ 0xC85E, 0xFFFF, WORD_LEN, 0 }, // CAM_CORE_A_MAX_FRAME_LENGTH_LINES +{ 0xC860, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_BASE_FRAME_LENGTH_LINES +{ 0xC862, 0x1194, WORD_LEN, 0 }, // CAM_CORE_A_MIN_LINE_LENGTH_PCLK +{ 0xC864, 0xFFFE, WORD_LEN, 0 }, // CAM_CORE_A_MAX_LINE_LENGTH_PCLK +{ 0xC866, 0x7F7F, WORD_LEN, 0 }, // CAM_CORE_A_P4_5_6_DIVIDER +{ 0xC868, 0x0423, WORD_LEN, 0 }, // CAM_CORE_A_FRAME_LENGTH_LINES +{ 0xC86A, 0x1194, WORD_LEN, 0 }, // CAM_CORE_A_LINE_LENGTH_PCK +{ 0xC86C, 0x0518, WORD_LEN, 0 }, // CAM_CORE_A_OUTPUT_SIZE_WIDTH +{ 0xC86E, 0x03D4, WORD_LEN, 0 }, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT +{ 0xC870, 0x0014, WORD_LEN, 0 }, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK +{ 0xC858, 0x0003, WORD_LEN, 0 }, // CAM_CORE_A_COARSE_ITMIN +{ 0xC8B8, 0x0004, WORD_LEN, 0 }, // CAM_OUTPUT_0_JPEG_CONTROL +{ 0xC8AE, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_0_OUTPUT_FORMAT +{ 0xC8AA, 0x0280, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_WIDTH +{ 0xC8AC, 0x01E0, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_HEIGHT +{ 0xC872, 0x0010, WORD_LEN, 0 }, // CAM_CORE_B_Y_ADDR_START +{ 0xC874, 0x001C, WORD_LEN, 0 }, // CAM_CORE_B_X_ADDR_START +{ 0xC876, 0x07AF, WORD_LEN, 0 }, // CAM_CORE_B_Y_ADDR_END +{ 0xC878, 0x0A43, WORD_LEN, 0 }, // CAM_CORE_B_X_ADDR_END +{ 0xC87A, 0x0001, WORD_LEN, 0 }, // CAM_CORE_B_ROW_SPEED +{ 0xC87C, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_X_CORE +{ 0xC87E, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_Y_CORE +{ 0xC880, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_X_PIPE +{ 0xC882, 0x0101, WORD_LEN, 0 }, // CAM_CORE_B_SKIP_Y_PIPE +{ 0xC884, 0x00F2, WORD_LEN, 0 }, // CAM_CORE_B_POWER_MODE +{ 0xC886, 0x0000, WORD_LEN, 0 }, // CAM_CORE_B_BIN_MODE +{ 0xC888, 0x00, BYTE_LEN, 0}, // CAM_CORE_B_ORIENTATION +{ 0xC889, 0x00, BYTE_LEN, 0}, // CAM_CORE_B_PIXEL_ORDER +{ 0xC88A, 0x009C, WORD_LEN, 0 }, // CAM_CORE_B_FINE_CORRECTION +{ 0xC88C, 0x034A, WORD_LEN, 0 }, // CAM_CORE_B_FINE_ITMIN +{ 0xC890, 0x0000, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMIN +{ 0xC892, 0x0001, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMAX_MARGIN +{ 0xC894, 0x07EF, WORD_LEN, 0 }, // CAM_CORE_B_MIN_FRAME_LENGTH_LINES +{ 0xC896, 0xFFFF, WORD_LEN, 0 }, // CAM_CORE_B_MAX_FRAME_LENGTH_LINES +{ 0xC898, 0x082F, WORD_LEN, 0 }, // CAM_CORE_B_BASE_FRAME_LENGTH_LINES +{ 0xC89A, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK +{ 0xC89C, 0xFFFE, WORD_LEN, 0 }, // CAM_CORE_B_MAX_LINE_LENGTH_PCLK +{ 0xC89E, 0x7F7F, WORD_LEN, 0 }, // CAM_CORE_B_P4_5_6_DIVIDER +{ 0xC8A0, 0x07EF, WORD_LEN, 0 }, // CAM_CORE_B_FRAME_LENGTH_LINES +{ 0xC8A2, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_LINE_LENGTH_PCK +{ 0xC8A4, 0x0A28, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_WIDTH +{ 0xC8A6, 0x07A0, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT +{ 0xC8A8, 0x0124, WORD_LEN, 0 }, // CAM_CORE_B_RX_FIFO_TRIGGER_MARK +{ 0xC890, 0x0003, WORD_LEN, 0 }, // CAM_CORE_B_COARSE_ITMIN +{ 0xC8C0, 0x0A20, WORD_LEN, 0 }, // CAM_OUTPUT_1_IMAGE_WIDTH +{ 0xC8C2, 0x0798, WORD_LEN, 0 }, // CAM_OUTPUT_1_IMAGE_HEIGHT +{ 0xC89A, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_MIN_LINE_LENGTH_PCLK +{ 0xC8A2, 0x1964, WORD_LEN, 0 }, // CAM_CORE_B_LINE_LENGTH_PCK +{ 0xC8C4, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_1_OUTPUT_FORMAT +{ 0xC8C6, 0x0000, WORD_LEN, 0 }, // CAM_OUTPUT_1_OUTPUT_FORMAT_ORDER +{ 0xC8CE, 0x0014, WORD_LEN, 0 }, // CAM_OUTPUT_1_JPEG_CONTROL +{ 0xD822, 0x4610, WORD_LEN, 0 }, // JPEG_JPSS_CTRL_VAR +{ 0x3330, 0x0000, WORD_LEN, 0 }, // OUTPUT_FORMAT_TEST +{ 0x098E, 0xA00E, WORD_LEN, 0 }, // LOGICAL_ADDRESS_ACCESS +{ 0xA00E, 0x32, BYTE_LEN, 0}, // FD_MAX_NUM_AUTOCOR_FUNC_VALUES_TO_CHECK +{ 0xA010, 0x00CC, WORD_LEN, 0 }, // FD_MIN_EXPECTED50HZ_FLICKER_PERIOD +{ 0xA012, 0x00E0, WORD_LEN, 0 }, // FD_MAX_EXPECTED50HZ_FLICKER_PERIOD +{ 0xA014, 0x00A8, WORD_LEN, 0 }, // FD_MIN_EXPECTED60HZ_FLICKER_PERIOD +{ 0xA016, 0x00BC, WORD_LEN, 0 }, // FD_MAX_EXPECTED60HZ_FLICKER_PERIOD +{ 0xA018, 0x00D6, WORD_LEN, 0 }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_A +{ 0xA01A, 0x0075, WORD_LEN, 0 }, // FD_EXPECTED50HZ_FLICKER_PERIOD_IN_CONTEXT_B +{ 0xA01C, 0x00B2, WORD_LEN, 0 }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_A +{ 0xA01E, 0x0062, WORD_LEN, 0 }, // FD_EXPECTED60HZ_FLICKER_PERIOD_IN_CONTEXT_B +{ 0xA000, 0x10, BYTE_LEN, 0}, // FD_STATUS +{ 0x8417, 0x02, BYTE_LEN, 0}, // SEQ_STATE_CFG_1_FD +//delay = 100 +{ SEQUENCE_WAIT_MS,100, BYTE_LEN, 0}, + + +//[Step2-Fixups] +// Default variable access mode is always logical. + + +{ 0x098E, 0x0000, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS +{ 0x301A, 0x0030, WORD_LEN, 0}, // RESET_REGISTER +{ 0x316C, 0xB430, WORD_LEN, 0}, // DAC_TXLO +{ 0x31E0, 0x0003, WORD_LEN, 0}, // PIX_DEF_ID +{ 0x3E2E, 0xF319, WORD_LEN, 0}, // SAMP_SPARE +{ 0x3EE6, 0xA7C1, WORD_LEN, 0}, // DAC_LD_26_27 +{ 0x301E, 0x00A8, WORD_LEN, 0}, // DATA_PEDESTAL +{ 0xDC33, 0x2A, BYTE_LEN, 0}, // SYS_FIRST_BLACK_LEVEL +{ 0x3812, 0x212C, WORD_LEN, 0}, // OTPM_CFG +{ 0x0982, 0x0000, WORD_LEN, 0}, // ACCESS_CTL_STAT +{ 0x098A, 0x0000, WORD_LEN, 0}, // PHYSICAL_ADDRESS_ACCESS +{ 0x886C, 0xC0F1, WORD_LEN, 0}, +{ 0x886E, 0xC5E1, WORD_LEN, 0}, +{ 0x8870, 0x246A, WORD_LEN, 0}, +{ 0x8872, 0x1280, WORD_LEN, 0}, +{ 0x8874, 0xC4E1, WORD_LEN, 0}, +{ 0x8876, 0xD20F, WORD_LEN, 0}, +{ 0x8878, 0x2069, WORD_LEN, 0}, +{ 0x887A, 0x0000, WORD_LEN, 0}, +{ 0x887C, 0x6A62, WORD_LEN, 0}, +{ 0x887E, 0x1303, WORD_LEN, 0}, +{ 0x8880, 0x0084, WORD_LEN, 0}, +{ 0x8882, 0x1734, WORD_LEN, 0}, +{ 0x8884, 0x7005, WORD_LEN, 0}, +{ 0x8886, 0xD801, WORD_LEN, 0}, +{ 0x8888, 0x8A41, WORD_LEN, 0}, +{ 0x888A, 0xD900, WORD_LEN, 0}, +{ 0x888C, 0x0D5A, WORD_LEN, 0}, +{ 0x888E, 0x0664, WORD_LEN, 0}, +{ 0x8890, 0x8B61, WORD_LEN, 0}, +{ 0x8892, 0xE80B, WORD_LEN, 0}, +{ 0x8894, 0x000D, WORD_LEN, 0}, +{ 0x8896, 0x0020, WORD_LEN, 0}, +{ 0x8898, 0xD508, WORD_LEN, 0}, +{ 0x889A, 0x1504, WORD_LEN, 0}, +{ 0x889C, 0x1400, WORD_LEN, 0}, +{ 0x889E, 0x7840, WORD_LEN, 0}, +{ 0x88A0, 0xD007, WORD_LEN, 0}, +{ 0x88A2, 0x0DFB, WORD_LEN, 0}, +{ 0x88A4, 0x9004, WORD_LEN, 0}, +{ 0x88A6, 0xC4C1, WORD_LEN, 0}, +{ 0x88A8, 0x2029, WORD_LEN, 0}, +{ 0x88AA, 0x0300, WORD_LEN, 0}, +{ 0x88AC, 0x0219, WORD_LEN, 0}, +{ 0x88AE, 0x06C4, WORD_LEN, 0}, +{ 0x88B0, 0xFF80, WORD_LEN, 0}, +{ 0x88B2, 0x08D4, WORD_LEN, 0}, +{ 0x88B4, 0xFF80, WORD_LEN, 0}, +{ 0x88B6, 0x086C, WORD_LEN, 0}, +{ 0x88B8, 0xFF80, WORD_LEN, 0}, +{ 0x88BA, 0x08C0, WORD_LEN, 0}, +{ 0x88BC, 0xFF80, WORD_LEN, 0}, +{ 0x88BE, 0x08D4, WORD_LEN, 0}, +{ 0x88C0, 0xFF80, WORD_LEN, 0}, +{ 0x88C2, 0x08DC, WORD_LEN, 0}, +{ 0x88C4, 0xFF80, WORD_LEN, 0}, +{ 0x88C6, 0x0F58, WORD_LEN, 0}, +{ 0x88C8, 0xFF80, WORD_LEN, 0}, +{ 0x88CA, 0x0920, WORD_LEN, 0}, +{ 0x88CC, 0xFF80, WORD_LEN, 0}, +{ 0x88CE, 0x1010, WORD_LEN, 0}, +{ 0x88D0, 0xFF80, WORD_LEN, 0}, +{ 0x88D2, 0x1030, WORD_LEN, 0}, +{ 0x88D4, 0x0010, WORD_LEN, 0}, +{ 0x88D6, 0x0008, WORD_LEN, 0}, +{ 0x88D8, 0x0000, WORD_LEN, 0}, +{ 0x88DA, 0x0000, WORD_LEN, 0}, +{ 0x88DC, 0xD102, WORD_LEN, 0}, +{ 0x88DE, 0xD003, WORD_LEN, 0}, +{ 0x88E0, 0x7FE0, WORD_LEN, 0}, +{ 0x88E2, 0xB035, WORD_LEN, 0}, +{ 0x88E4, 0xFF80, WORD_LEN, 0}, +{ 0x88E6, 0x10C8, WORD_LEN, 0}, +{ 0x88E8, 0xFF80, WORD_LEN, 0}, +{ 0x88EA, 0x0118, WORD_LEN, 0}, +{ 0x88EC, 0xC0F1, WORD_LEN, 0}, +{ 0x88EE, 0xC5E1, WORD_LEN, 0}, +{ 0x88F0, 0xD5EC, WORD_LEN, 0}, +{ 0x88F2, 0x8D04, WORD_LEN, 0}, +{ 0x88F4, 0x8D25, WORD_LEN, 0}, +{ 0x88F6, 0xB808, WORD_LEN, 0}, +{ 0x88F8, 0x7825, WORD_LEN, 0}, +{ 0x88FA, 0x0821, WORD_LEN, 0}, +{ 0x88FC, 0x01DE, WORD_LEN, 0}, +{ 0x88FE, 0xD0EA, WORD_LEN, 0}, +{ 0x8900, 0x8000, WORD_LEN, 0}, +{ 0x8902, 0x8008, WORD_LEN, 0}, +{ 0x8904, 0x7840, WORD_LEN, 0}, +{ 0x8906, 0x8D04, WORD_LEN, 0}, +{ 0x8908, 0x8D25, WORD_LEN, 0}, +{ 0x890A, 0xB808, WORD_LEN, 0}, +{ 0x890C, 0x7825, WORD_LEN, 0}, +{ 0x890E, 0xB8A7, WORD_LEN, 0}, +{ 0x8910, 0x2841, WORD_LEN, 0}, +{ 0x8912, 0x0201, WORD_LEN, 0}, +{ 0x8914, 0xAD24, WORD_LEN, 0}, +{ 0x8916, 0xAD05, WORD_LEN, 0}, +{ 0x8918, 0x09A6, WORD_LEN, 0}, +{ 0x891A, 0x0104, WORD_LEN, 0}, +{ 0x891C, 0x01A9, WORD_LEN, 0}, +{ 0x891E, 0x06C4, WORD_LEN, 0}, +{ 0x8920, 0xC0F1, WORD_LEN, 0}, +{ 0x8922, 0x0932, WORD_LEN, 0}, +{ 0x8924, 0x06E4, WORD_LEN, 0}, +{ 0x8926, 0xDA38, WORD_LEN, 0}, +{ 0x8928, 0xD1E0, WORD_LEN, 0}, +{ 0x892A, 0xD5E1, WORD_LEN, 0}, +{ 0x892C, 0x76A9, WORD_LEN, 0}, +{ 0x892E, 0x0EC6, WORD_LEN, 0}, +{ 0x8930, 0x06A4, WORD_LEN, 0}, +{ 0x8932, 0x70C9, WORD_LEN, 0}, +{ 0x8934, 0xD0DF, WORD_LEN, 0}, +{ 0x8936, 0xA501, WORD_LEN, 0}, +{ 0x8938, 0xD0DF, WORD_LEN, 0}, +{ 0x893A, 0xA503, WORD_LEN, 0}, +{ 0x893C, 0xD0DF, WORD_LEN, 0}, +{ 0x893E, 0xA506, WORD_LEN, 0}, +{ 0x8940, 0xD0DF, WORD_LEN, 0}, +{ 0x8942, 0xA509, WORD_LEN, 0}, +{ 0x8944, 0xD0D8, WORD_LEN, 0}, +{ 0x8946, 0xA0C0, WORD_LEN, 0}, +{ 0x8948, 0xD0DE, WORD_LEN, 0}, +{ 0x894A, 0x802E, WORD_LEN, 0}, +{ 0x894C, 0x9117, WORD_LEN, 0}, +{ 0x894E, 0x0171, WORD_LEN, 0}, +{ 0x8950, 0x06E4, WORD_LEN, 0}, +{ 0x8952, 0xB10E, WORD_LEN, 0}, +{ 0x8954, 0xC0F1, WORD_LEN, 0}, +{ 0x8956, 0xD0D3, WORD_LEN, 0}, +{ 0x8958, 0x8806, WORD_LEN, 0}, +{ 0x895A, 0x080F, WORD_LEN, 0}, +{ 0x895C, 0x0051, WORD_LEN, 0}, +{ 0x895E, 0xD0D2, WORD_LEN, 0}, +{ 0x8960, 0x8000, WORD_LEN, 0}, +{ 0x8962, 0x8008, WORD_LEN, 0}, +{ 0x8964, 0x7840, WORD_LEN, 0}, +{ 0x8966, 0x0A1E, WORD_LEN, 0}, +{ 0x8968, 0x0104, WORD_LEN, 0}, +{ 0x896A, 0xC0D1, WORD_LEN, 0}, +{ 0x896C, 0x7EE0, WORD_LEN, 0}, +{ 0x896E, 0x78E0, WORD_LEN, 0}, +{ 0x8970, 0xC0F1, WORD_LEN, 0}, +{ 0x8972, 0x08D6, WORD_LEN, 0}, +{ 0x8974, 0x06C4, WORD_LEN, 0}, +{ 0x8976, 0xD7CC, WORD_LEN, 0}, +{ 0x8978, 0x8700, WORD_LEN, 0}, +{ 0x897A, 0x8009, WORD_LEN, 0}, +{ 0x897C, 0x7840, WORD_LEN, 0}, +{ 0x897E, 0xE080, WORD_LEN, 0}, +{ 0x8980, 0x0276, WORD_LEN, 0}, +{ 0x8982, 0x0002, WORD_LEN, 0}, +{ 0x8984, 0xD5C7, WORD_LEN, 0}, +{ 0x8986, 0xD6D0, WORD_LEN, 0}, +{ 0x8988, 0x1530, WORD_LEN, 0}, +{ 0x898A, 0x1081, WORD_LEN, 0}, +{ 0x898C, 0x1531, WORD_LEN, 0}, +{ 0x898E, 0x1080, WORD_LEN, 0}, +{ 0x8990, 0xB908, WORD_LEN, 0}, +{ 0x8992, 0x7905, WORD_LEN, 0}, +{ 0x8994, 0x2941, WORD_LEN, 0}, +{ 0x8996, 0x0200, WORD_LEN, 0}, +{ 0x8998, 0x1D32, WORD_LEN, 0}, +{ 0x899A, 0x1002, WORD_LEN, 0}, +{ 0x899C, 0x1D33, WORD_LEN, 0}, +{ 0x899E, 0x1042, WORD_LEN, 0}, +{ 0x89A0, 0x962D, WORD_LEN, 0}, +{ 0x89A2, 0x2540, WORD_LEN, 0}, +{ 0x89A4, 0x15D1, WORD_LEN, 0}, +{ 0x89A6, 0x2941, WORD_LEN, 0}, +{ 0x89A8, 0x0200, WORD_LEN, 0}, +{ 0x89AA, 0x1D30, WORD_LEN, 0}, +{ 0x89AC, 0x1002, WORD_LEN, 0}, +{ 0x89AE, 0x8D06, WORD_LEN, 0}, +{ 0x89B0, 0x2540, WORD_LEN, 0}, +{ 0x89B2, 0x1610, WORD_LEN, 0}, +{ 0x89B4, 0x1D31, WORD_LEN, 0}, +{ 0x89B6, 0x1042, WORD_LEN, 0}, +{ 0x89B8, 0x081B, WORD_LEN, 0}, +{ 0x89BA, 0x0051, WORD_LEN, 0}, +{ 0x89BC, 0x8700, WORD_LEN, 0}, +{ 0x89BE, 0x8008, WORD_LEN, 0}, +{ 0x89C0, 0x7840, WORD_LEN, 0}, +{ 0x89C2, 0xD900, WORD_LEN, 0}, +{ 0x89C4, 0x2941, WORD_LEN, 0}, +{ 0x89C6, 0x0200, WORD_LEN, 0}, +{ 0x89C8, 0xAD00, WORD_LEN, 0}, +{ 0x89CA, 0xAD21, WORD_LEN, 0}, +{ 0x89CC, 0xD801, WORD_LEN, 0}, +{ 0x89CE, 0x1D4D, WORD_LEN, 0}, +{ 0x89D0, 0x1002, WORD_LEN, 0}, +{ 0x89D2, 0x154D, WORD_LEN, 0}, +{ 0x89D4, 0x1080, WORD_LEN, 0}, +{ 0x89D6, 0xB861, WORD_LEN, 0}, +{ 0x89D8, 0xE085, WORD_LEN, 0}, +{ 0x89DA, 0x0218, WORD_LEN, 0}, +{ 0x89DC, 0x000D, WORD_LEN, 0}, +{ 0x89DE, 0x2740, WORD_LEN, 0}, +{ 0x89E0, 0x7381, WORD_LEN, 0}, +{ 0x89E2, 0x2132, WORD_LEN, 0}, +{ 0x89E4, 0x0000, WORD_LEN, 0}, +{ 0x89E6, 0x7914, WORD_LEN, 0}, +{ 0x89E8, 0x7900, WORD_LEN, 0}, +{ 0x89EA, 0x0323, WORD_LEN, 0}, +{ 0x89EC, 0x67BB, WORD_LEN, 0}, +{ 0x89EE, 0xD62E, WORD_LEN, 0}, +{ 0x89F0, 0x8D11, WORD_LEN, 0}, +{ 0x89F2, 0xD1B6, WORD_LEN, 0}, +{ 0x89F4, 0x8924, WORD_LEN, 0}, +{ 0x89F6, 0x2032, WORD_LEN, 0}, +{ 0x89F8, 0x2000, WORD_LEN, 0}, +{ 0x89FA, 0xDE02, WORD_LEN, 0}, +{ 0x89FC, 0x082B, WORD_LEN, 0}, +{ 0x89FE, 0x0040, WORD_LEN, 0}, +{ 0x8A00, 0x8D20, WORD_LEN, 0}, +{ 0x8A02, 0x8D41, WORD_LEN, 0}, +{ 0x8A04, 0xB908, WORD_LEN, 0}, +{ 0x8A06, 0x7945, WORD_LEN, 0}, +{ 0x8A08, 0xB983, WORD_LEN, 0}, +{ 0x8A0A, 0x2941, WORD_LEN, 0}, +{ 0x8A0C, 0x0202, WORD_LEN, 0}, +{ 0x8A0E, 0xAD40, WORD_LEN, 0}, +{ 0x8A10, 0xAD21, WORD_LEN, 0}, +{ 0x8A12, 0xD1AF, WORD_LEN, 0}, +{ 0x8A14, 0x8120, WORD_LEN, 0}, +{ 0x8A16, 0x8121, WORD_LEN, 0}, +{ 0x8A18, 0x7940, WORD_LEN, 0}, +{ 0x8A1A, 0x8D06, WORD_LEN, 0}, +{ 0x8A1C, 0xE001, WORD_LEN, 0}, +{ 0x8A1E, 0xAD06, WORD_LEN, 0}, +{ 0x8A20, 0x1D4D, WORD_LEN, 0}, +{ 0x8A22, 0x1382, WORD_LEN, 0}, +{ 0x8A24, 0xF0E9, WORD_LEN, 0}, +{ 0x8A26, 0x8D06, WORD_LEN, 0}, +{ 0x8A28, 0x1D4D, WORD_LEN, 0}, +{ 0x8A2A, 0x1382, WORD_LEN, 0}, +{ 0x8A2C, 0xE001, WORD_LEN, 0}, +{ 0x8A2E, 0xAD06, WORD_LEN, 0}, +{ 0x8A30, 0x8D00, WORD_LEN, 0}, +{ 0x8A32, 0x8D21, WORD_LEN, 0}, +{ 0x8A34, 0xB808, WORD_LEN, 0}, +{ 0x8A36, 0x7825, WORD_LEN, 0}, +{ 0x8A38, 0xB885, WORD_LEN, 0}, +{ 0x8A3A, 0x2841, WORD_LEN, 0}, +{ 0x8A3C, 0x0201, WORD_LEN, 0}, +{ 0x8A3E, 0xAD20, WORD_LEN, 0}, +{ 0x8A40, 0xAD01, WORD_LEN, 0}, +{ 0x8A42, 0x8D31, WORD_LEN, 0}, +{ 0x8A44, 0xF01A, WORD_LEN, 0}, +{ 0x8A46, 0x8D31, WORD_LEN, 0}, +{ 0x8A48, 0x8D12, WORD_LEN, 0}, +{ 0x8A4A, 0x8D46, WORD_LEN, 0}, +{ 0x8A4C, 0x7822, WORD_LEN, 0}, +{ 0x8A4E, 0x0863, WORD_LEN, 0}, +{ 0x8A50, 0x0082, WORD_LEN, 0}, +{ 0x8A52, 0x1532, WORD_LEN, 0}, +{ 0x8A54, 0x1080, WORD_LEN, 0}, +{ 0x8A56, 0x1533, WORD_LEN, 0}, +{ 0x8A58, 0x1081, WORD_LEN, 0}, +{ 0x8A5A, 0x1531, WORD_LEN, 0}, +{ 0x8A5C, 0x1082, WORD_LEN, 0}, +{ 0x8A5E, 0xB808, WORD_LEN, 0}, +{ 0x8A60, 0x7825, WORD_LEN, 0}, +{ 0x8A62, 0x1530, WORD_LEN, 0}, +{ 0x8A64, 0x1081, WORD_LEN, 0}, +{ 0x8A66, 0xB908, WORD_LEN, 0}, +{ 0x8A68, 0x7945, WORD_LEN, 0}, +{ 0x8A6A, 0xD29A, WORD_LEN, 0}, +{ 0x8A6C, 0x0992, WORD_LEN, 0}, +{ 0x8A6E, 0x0020, WORD_LEN, 0}, +{ 0x8A70, 0x8A40, WORD_LEN, 0}, +{ 0x8A72, 0x8D31, WORD_LEN, 0}, +{ 0x8A74, 0x081F, WORD_LEN, 0}, +{ 0x8A76, 0x0051, WORD_LEN, 0}, +{ 0x8A78, 0x8D06, WORD_LEN, 0}, +{ 0x8A7A, 0x6038, WORD_LEN, 0}, +{ 0x8A7C, 0xD194, WORD_LEN, 0}, +{ 0x8A7E, 0x8120, WORD_LEN, 0}, +{ 0x8A80, 0x8121, WORD_LEN, 0}, +{ 0x8A82, 0x7960, WORD_LEN, 0}, +{ 0x8A84, 0x2132, WORD_LEN, 0}, +{ 0x8A86, 0x2000, WORD_LEN, 0}, +{ 0x8A88, 0x8D06, WORD_LEN, 0}, +{ 0x8A8A, 0xE001, WORD_LEN, 0}, +{ 0x8A8C, 0xAD06, WORD_LEN, 0}, +{ 0x8A8E, 0xD806, WORD_LEN, 0}, +{ 0x8A90, 0xF0B1, WORD_LEN, 0}, +{ 0x8A92, 0xE88F, WORD_LEN, 0}, +{ 0x8A94, 0x8D66, WORD_LEN, 0}, +{ 0x8A96, 0x633B, WORD_LEN, 0}, +{ 0x8A98, 0x63BB, WORD_LEN, 0}, +{ 0x8A9A, 0xD08D, WORD_LEN, 0}, +{ 0x8A9C, 0x8000, WORD_LEN, 0}, +{ 0x8A9E, 0x8021, WORD_LEN, 0}, +{ 0x8AA0, 0x7960, WORD_LEN, 0}, +{ 0x8AA2, 0x8B17, WORD_LEN, 0}, +{ 0x8AA4, 0x8D06, WORD_LEN, 0}, +{ 0x8AA6, 0xE001, WORD_LEN, 0}, +{ 0x8AA8, 0xAD06, WORD_LEN, 0}, +{ 0x8AAA, 0xD803, WORD_LEN, 0}, +{ 0x8AAC, 0xF0A3, WORD_LEN, 0}, +{ 0x8AAE, 0x2032, WORD_LEN, 0}, +{ 0x8AB0, 0x2040, WORD_LEN, 0}, +{ 0x8AB2, 0xAD07, WORD_LEN, 0}, +{ 0x8AB4, 0xD804, WORD_LEN, 0}, +{ 0x8AB6, 0xF09F, WORD_LEN, 0}, +{ 0x8AB8, 0x1532, WORD_LEN, 0}, +{ 0x8ABA, 0x1080, WORD_LEN, 0}, +{ 0x8ABC, 0x1533, WORD_LEN, 0}, +{ 0x8ABE, 0x1081, WORD_LEN, 0}, +{ 0x8AC0, 0x1531, WORD_LEN, 0}, +{ 0x8AC2, 0x1082, WORD_LEN, 0}, +{ 0x8AC4, 0xB808, WORD_LEN, 0}, +{ 0x8AC6, 0x7825, WORD_LEN, 0}, +{ 0x8AC8, 0x1530, WORD_LEN, 0}, +{ 0x8ACA, 0x1081, WORD_LEN, 0}, +{ 0x8ACC, 0xB908, WORD_LEN, 0}, +{ 0x8ACE, 0x7945, WORD_LEN, 0}, +{ 0x8AD0, 0xD280, WORD_LEN, 0}, +{ 0x8AD2, 0x092E, WORD_LEN, 0}, +{ 0x8AD4, 0x0020, WORD_LEN, 0}, +{ 0x8AD6, 0x8A41, WORD_LEN, 0}, +{ 0x8AD8, 0x8D51, WORD_LEN, 0}, +{ 0x8ADA, 0x8D32, WORD_LEN, 0}, +{ 0x8ADC, 0x8DC6, WORD_LEN, 0}, +{ 0x8ADE, 0x7942, WORD_LEN, 0}, +{ 0x8AE0, 0x62DB, WORD_LEN, 0}, +{ 0x8AE2, 0x091F, WORD_LEN, 0}, +{ 0x8AE4, 0x03A2, WORD_LEN, 0}, +{ 0x8AE6, 0x63BB, WORD_LEN, 0}, +{ 0x8AE8, 0xE88B, WORD_LEN, 0}, +{ 0x8AEA, 0x8D00, WORD_LEN, 0}, +{ 0x8AEC, 0x8D21, WORD_LEN, 0}, +{ 0x8AEE, 0xB808, WORD_LEN, 0}, +{ 0x8AF0, 0x7825, WORD_LEN, 0}, +{ 0x8AF2, 0xB885, WORD_LEN, 0}, +{ 0x8AF4, 0x2841, WORD_LEN, 0}, +{ 0x8AF6, 0x0201, WORD_LEN, 0}, +{ 0x8AF8, 0xAD20, WORD_LEN, 0}, +{ 0x8AFA, 0xAD01, WORD_LEN, 0}, +{ 0x8AFC, 0xF1CF, WORD_LEN, 0}, +{ 0x8AFE, 0xDF04, WORD_LEN, 0}, +{ 0x8B00, 0x092B, WORD_LEN, 0}, +{ 0x8B02, 0x03A3, WORD_LEN, 0}, +{ 0x8B04, 0x1D4D, WORD_LEN, 0}, +{ 0x8B06, 0x13C2, WORD_LEN, 0}, +{ 0x8B08, 0x1530, WORD_LEN, 0}, +{ 0x8B0A, 0x108E, WORD_LEN, 0}, +{ 0x8B0C, 0x1531, WORD_LEN, 0}, +{ 0x8B0E, 0x1081, WORD_LEN, 0}, +{ 0x8B10, 0x1533, WORD_LEN, 0}, +{ 0x8B12, 0x108F, WORD_LEN, 0}, +{ 0x8B14, 0xBE08, WORD_LEN, 0}, +{ 0x8B16, 0x7E25, WORD_LEN, 0}, +{ 0x8B18, 0x1532, WORD_LEN, 0}, +{ 0x8B1A, 0x1081, WORD_LEN, 0}, +{ 0x8B1C, 0xB908, WORD_LEN, 0}, +{ 0x8B1E, 0x79E5, WORD_LEN, 0}, +{ 0x8B20, 0x0907, WORD_LEN, 0}, +{ 0x8B22, 0x0382, WORD_LEN, 0}, +{ 0x8B24, 0xE883, WORD_LEN, 0}, +{ 0x8B26, 0x8B16, WORD_LEN, 0}, +{ 0x8B28, 0xF002, WORD_LEN, 0}, +{ 0x8B2A, 0x8B15, WORD_LEN, 0}, +{ 0x8B2C, 0x8D22, WORD_LEN, 0}, +{ 0x8B2E, 0xAD07, WORD_LEN, 0}, +{ 0x8B30, 0x8D03, WORD_LEN, 0}, +{ 0x8B32, 0xD367, WORD_LEN, 0}, +{ 0x8B34, 0xB908, WORD_LEN, 0}, +{ 0x8B36, 0x8DC1, WORD_LEN, 0}, +{ 0x8B38, 0x7905, WORD_LEN, 0}, +{ 0x8B3A, 0x8D00, WORD_LEN, 0}, +{ 0x8B3C, 0xB808, WORD_LEN, 0}, +{ 0x8B3E, 0x78C5, WORD_LEN, 0}, +{ 0x8B40, 0x0921, WORD_LEN, 0}, +{ 0x8B42, 0x011E, WORD_LEN, 0}, +{ 0x8B44, 0xB883, WORD_LEN, 0}, +{ 0x8B46, 0x2841, WORD_LEN, 0}, +{ 0x8B48, 0x0201, WORD_LEN, 0}, +{ 0x8B4A, 0xAD20, WORD_LEN, 0}, +{ 0x8B4C, 0x8320, WORD_LEN, 0}, +{ 0x8B4E, 0xAD01, WORD_LEN, 0}, +{ 0x8B50, 0x8121, WORD_LEN, 0}, +{ 0x8B52, 0x7960, WORD_LEN, 0}, +{ 0x8B54, 0x2032, WORD_LEN, 0}, +{ 0x8B56, 0x2080, WORD_LEN, 0}, +{ 0x8B58, 0x8D06, WORD_LEN, 0}, +{ 0x8B5A, 0xE001, WORD_LEN, 0}, +{ 0x8B5C, 0xAD06, WORD_LEN, 0}, +{ 0x8B5E, 0xF04D, WORD_LEN, 0}, +{ 0x8B60, 0x8D00, WORD_LEN, 0}, +{ 0x8B62, 0x8D21, WORD_LEN, 0}, +{ 0x8B64, 0xB808, WORD_LEN, 0}, +{ 0x8B66, 0x7825, WORD_LEN, 0}, +{ 0x8B68, 0xB886, WORD_LEN, 0}, +{ 0x8B6A, 0x2841, WORD_LEN, 0}, +{ 0x8B6C, 0x0201, WORD_LEN, 0}, +{ 0x8B6E, 0xAD20, WORD_LEN, 0}, +{ 0x8B70, 0xAD01, WORD_LEN, 0}, +{ 0x8B72, 0xD057, WORD_LEN, 0}, +{ 0x8B74, 0x8000, WORD_LEN, 0}, +{ 0x8B76, 0x8021, WORD_LEN, 0}, +{ 0x8B78, 0x7960, WORD_LEN, 0}, +{ 0x8B7A, 0x8D07, WORD_LEN, 0}, +{ 0x8B7C, 0x1545, WORD_LEN, 0}, +{ 0x8B7E, 0x1080, WORD_LEN, 0}, +{ 0x8B80, 0x1546, WORD_LEN, 0}, +{ 0x8B82, 0x1081, WORD_LEN, 0}, +{ 0x8B84, 0xB808, WORD_LEN, 0}, +{ 0x8B86, 0x7825, WORD_LEN, 0}, +{ 0x8B88, 0x085D, WORD_LEN, 0}, +{ 0x8B8A, 0x005E, WORD_LEN, 0}, +{ 0x8B8C, 0x8D06, WORD_LEN, 0}, +{ 0x8B8E, 0xE001, WORD_LEN, 0}, +{ 0x8B90, 0xAD06, WORD_LEN, 0}, +{ 0x8B92, 0xD805, WORD_LEN, 0}, +{ 0x8B94, 0xF02F, WORD_LEN, 0}, +{ 0x8B96, 0x1530, WORD_LEN, 0}, +{ 0x8B98, 0x1082, WORD_LEN, 0}, +{ 0x8B9A, 0x1531, WORD_LEN, 0}, +{ 0x8B9C, 0x1080, WORD_LEN, 0}, +{ 0x8B9E, 0xD14D, WORD_LEN, 0}, +{ 0x8BA0, 0xBA08, WORD_LEN, 0}, +{ 0x8BA2, 0x7A05, WORD_LEN, 0}, +{ 0x8BA4, 0x8903, WORD_LEN, 0}, +{ 0x8BA6, 0x080F, WORD_LEN, 0}, +{ 0x8BA8, 0x0083, WORD_LEN, 0}, +{ 0x8BAA, 0x8902, WORD_LEN, 0}, +{ 0x8BAC, 0x8E44, WORD_LEN, 0}, +{ 0x8BAE, 0x0839, WORD_LEN, 0}, +{ 0x8BB0, 0x0082, WORD_LEN, 0}, +{ 0x8BB2, 0x1545, WORD_LEN, 0}, +{ 0x8BB4, 0x1082, WORD_LEN, 0}, +{ 0x8BB6, 0x1546, WORD_LEN, 0}, +{ 0x8BB8, 0x1080, WORD_LEN, 0}, +{ 0x8BBA, 0xBA08, WORD_LEN, 0}, +{ 0x8BBC, 0x7A05, WORD_LEN, 0}, +{ 0x8BBE, 0x0A29, WORD_LEN, 0}, +{ 0x8BC0, 0x005E, WORD_LEN, 0}, +{ 0x8BC2, 0x8D00, WORD_LEN, 0}, +{ 0x8BC4, 0x8D21, WORD_LEN, 0}, +{ 0x8BC6, 0xB808, WORD_LEN, 0}, +{ 0x8BC8, 0x7825, WORD_LEN, 0}, +{ 0x8BCA, 0xB88D, WORD_LEN, 0}, +{ 0x8BCC, 0x2841, WORD_LEN, 0}, +{ 0x8BCE, 0x0201, WORD_LEN, 0}, +{ 0x8BD0, 0xAD20, WORD_LEN, 0}, +{ 0x8BD2, 0xAD01, WORD_LEN, 0}, +{ 0x8BD4, 0x0A11, WORD_LEN, 0}, +{ 0x8BD6, 0x009E, WORD_LEN, 0}, +{ 0x8BD8, 0xD03D, WORD_LEN, 0}, +{ 0x8BDA, 0x8000, WORD_LEN, 0}, +{ 0x8BDC, 0x8021, WORD_LEN, 0}, +{ 0x8BDE, 0x7960, WORD_LEN, 0}, +{ 0x8BE0, 0x1550, WORD_LEN, 0}, +{ 0x8BE2, 0x1080, WORD_LEN, 0}, +{ 0x8BE4, 0xD800, WORD_LEN, 0}, +{ 0x8BE6, 0x09AA, WORD_LEN, 0}, +{ 0x8BE8, 0x0164, WORD_LEN, 0}, +{ 0x8BEA, 0x1D4D, WORD_LEN, 0}, +{ 0x8BEC, 0x1002, WORD_LEN, 0}, +{ 0x8BEE, 0xF005, WORD_LEN, 0}, +{ 0x8BF0, 0xD800, WORD_LEN, 0}, +{ 0x8BF2, 0x1D4D, WORD_LEN, 0}, +{ 0x8BF4, 0x1002, WORD_LEN, 0}, +{ 0x8BF6, 0x06B1, WORD_LEN, 0}, +{ 0x8BF8, 0x0684, WORD_LEN, 0}, +{ 0x8BFA, 0x78E0, WORD_LEN, 0}, +{ 0x8BFC, 0xC0F1, WORD_LEN, 0}, +{ 0x8BFE, 0x0E4E, WORD_LEN, 0}, +{ 0x8C00, 0x06A4, WORD_LEN, 0}, +{ 0x8C02, 0x7308, WORD_LEN, 0}, +{ 0x8C04, 0x0919, WORD_LEN, 0}, +{ 0x8C06, 0x0023, WORD_LEN, 0}, +{ 0x8C08, 0x721A, WORD_LEN, 0}, +{ 0x8C0A, 0xD026, WORD_LEN, 0}, +{ 0x8C0C, 0x1030, WORD_LEN, 0}, +{ 0x8C0E, 0x0082, WORD_LEN, 0}, +{ 0x8C10, 0x1031, WORD_LEN, 0}, +{ 0x8C12, 0x0081, WORD_LEN, 0}, +{ 0x8C14, 0xBA08, WORD_LEN, 0}, +{ 0x8C16, 0x7A25, WORD_LEN, 0}, +{ 0x8C18, 0xDD00, WORD_LEN, 0}, +{ 0x8C1A, 0xF005, WORD_LEN, 0}, +{ 0x8C1C, 0xDD01, WORD_LEN, 0}, +{ 0x8C1E, 0x7268, WORD_LEN, 0}, +{ 0x8C20, 0x7328, WORD_LEN, 0}, +{ 0x8C22, 0x2302, WORD_LEN, 0}, +{ 0x8C24, 0x0080, WORD_LEN, 0}, +{ 0x8C26, 0x2885, WORD_LEN, 0}, +{ 0x8C28, 0x0901, WORD_LEN, 0}, +{ 0x8C2A, 0x702F, WORD_LEN, 0}, +{ 0x8C2C, 0x0EFA, WORD_LEN, 0}, +{ 0x8C2E, 0x06A4, WORD_LEN, 0}, +{ 0x8C30, 0x7168, WORD_LEN, 0}, +{ 0x8C32, 0xD31C, WORD_LEN, 0}, +{ 0x8C34, 0x8BC6, WORD_LEN, 0}, +{ 0x8C36, 0x8B31, WORD_LEN, 0}, +{ 0x8C38, 0x780F, WORD_LEN, 0}, +{ 0x8C3A, 0xD226, WORD_LEN, 0}, +{ 0x8C3C, 0x663E, WORD_LEN, 0}, +{ 0x8C3E, 0xD123, WORD_LEN, 0}, +{ 0x8C40, 0xBE62, WORD_LEN, 0}, +{ 0x8C42, 0x7ECF, WORD_LEN, 0}, +{ 0x8C44, 0x89E4, WORD_LEN, 0}, +{ 0x8C46, 0x2214, WORD_LEN, 0}, +{ 0x8C48, 0x0381, WORD_LEN, 0}, +{ 0x8C4A, 0xED07, WORD_LEN, 0}, +{ 0x8C4C, 0x2840, WORD_LEN, 0}, +{ 0x8C4E, 0x020E, WORD_LEN, 0}, +{ 0x8C50, 0x7EE5, WORD_LEN, 0}, +{ 0x8C52, 0xB1CC, WORD_LEN, 0}, +{ 0x8C54, 0xF007, WORD_LEN, 0}, +{ 0x8C56, 0x7E12, WORD_LEN, 0}, +{ 0x8C58, 0xE601, WORD_LEN, 0}, +{ 0x8C5A, 0x7ECF, WORD_LEN, 0}, +{ 0x8C5C, 0xBE08, WORD_LEN, 0}, +{ 0x8C5E, 0x7FC5, WORD_LEN, 0}, +{ 0x8C60, 0xB1EC, WORD_LEN, 0}, +{ 0x8C62, 0x080D, WORD_LEN, 0}, +{ 0x8C64, 0x2003, WORD_LEN, 0}, +{ 0x8C66, 0xED0D, WORD_LEN, 0}, +{ 0x8C68, 0xD800, WORD_LEN, 0}, +{ 0x8C6A, 0xF01A, WORD_LEN, 0}, +{ 0x8C6C, 0x134D, WORD_LEN, 0}, +{ 0x8C6E, 0x0080, WORD_LEN, 0}, +{ 0x8C70, 0x080B, WORD_LEN, 0}, +{ 0x8C72, 0x0190, WORD_LEN, 0}, +{ 0x8C74, 0x8A0E, WORD_LEN, 0}, +{ 0x8C76, 0x080B, WORD_LEN, 0}, +{ 0x8C78, 0x0291, WORD_LEN, 0}, +{ 0x8C7A, 0xD801, WORD_LEN, 0}, +{ 0x8C7C, 0xF010, WORD_LEN, 0}, +{ 0x8C7E, 0x1330, WORD_LEN, 0}, +{ 0x8C80, 0x0081, WORD_LEN, 0}, +{ 0x8C82, 0x1331, WORD_LEN, 0}, +{ 0x8C84, 0x008D, WORD_LEN, 0}, +{ 0x8C86, 0xD802, WORD_LEN, 0}, +{ 0x8C88, 0xB908, WORD_LEN, 0}, +{ 0x8C8A, 0x79A5, WORD_LEN, 0}, +{ 0x8C8C, 0xB22A, WORD_LEN, 0}, +{ 0x8C8E, 0x1332, WORD_LEN, 0}, +{ 0x8C90, 0x0081, WORD_LEN, 0}, +{ 0x8C92, 0x1333, WORD_LEN, 0}, +{ 0x8C94, 0x008D, WORD_LEN, 0}, +{ 0x8C96, 0xB908, WORD_LEN, 0}, +{ 0x8C98, 0x79A5, WORD_LEN, 0}, +{ 0x8C9A, 0xB22B, WORD_LEN, 0}, +{ 0x8C9C, 0x0611, WORD_LEN, 0}, +{ 0x8C9E, 0x0684, WORD_LEN, 0}, +{ 0x8CA0, 0xFF80, WORD_LEN, 0}, +{ 0x8CA2, 0x0290, WORD_LEN, 0}, +{ 0x8CA4, 0x8000, WORD_LEN, 0}, +{ 0x8CA6, 0x008C, WORD_LEN, 0}, +{ 0x8CA8, 0x0000, WORD_LEN, 0}, +{ 0x8CAA, 0xF3BC, WORD_LEN, 0}, +{ 0x8CAC, 0xFF80, WORD_LEN, 0}, +{ 0x8CAE, 0x1120, WORD_LEN, 0}, +{ 0x8CB0, 0xFF80, WORD_LEN, 0}, +{ 0x8CB2, 0x08EC, WORD_LEN, 0}, +{ 0x8CB4, 0xFF80, WORD_LEN, 0}, +{ 0x8CB6, 0x0954, WORD_LEN, 0}, +{ 0x8CB8, 0xFF80, WORD_LEN, 0}, +{ 0x8CBA, 0x0970, WORD_LEN, 0}, +{ 0x8CBC, 0xFF80, WORD_LEN, 0}, +{ 0x8CBE, 0x0CD4, WORD_LEN, 0}, +{ 0x8CC0, 0xFF80, WORD_LEN, 0}, +{ 0x8CC2, 0x06C8, WORD_LEN, 0}, +{ 0x8CC4, 0xFF80, WORD_LEN, 0}, +{ 0x8CC6, 0x050C, WORD_LEN, 0}, +{ 0x8CC8, 0xFF80, WORD_LEN, 0}, +{ 0x8CCA, 0x0158, WORD_LEN, 0}, +{ 0x8CCC, 0x8000, WORD_LEN, 0}, +{ 0x8CCE, 0x0008, WORD_LEN, 0}, +{ 0x8CD0, 0xFF80, WORD_LEN, 0}, +{ 0x8CD2, 0x10C8, WORD_LEN, 0}, +{ 0x8CD4, 0xC0F1, WORD_LEN, 0}, +{ 0x8CD6, 0x0D7E, WORD_LEN, 0}, +{ 0x8CD8, 0x0684, WORD_LEN, 0}, +{ 0x8CDA, 0x17C8, WORD_LEN, 0}, +{ 0x8CDC, 0xF00D, WORD_LEN, 0}, +{ 0x8CDE, 0x1545, WORD_LEN, 0}, +{ 0x8CE0, 0x1080, WORD_LEN, 0}, +{ 0x8CE2, 0x1546, WORD_LEN, 0}, +{ 0x8CE4, 0x1081, WORD_LEN, 0}, +{ 0x8CE6, 0xB808, WORD_LEN, 0}, +{ 0x8CE8, 0x7825, WORD_LEN, 0}, +{ 0x8CEA, 0xB8E0, WORD_LEN, 0}, +{ 0x8CEC, 0xDE00, WORD_LEN, 0}, +{ 0x8CEE, 0xF208, WORD_LEN, 0}, +{ 0x8CF0, 0x8D00, WORD_LEN, 0}, +{ 0x8CF2, 0x8D21, WORD_LEN, 0}, +{ 0x8CF4, 0xB808, WORD_LEN, 0}, +{ 0x8CF6, 0x7825, WORD_LEN, 0}, +{ 0x8CF8, 0x2044, WORD_LEN, 0}, +{ 0x8CFA, 0x020E, WORD_LEN, 0}, +{ 0x8CFC, 0x8D00, WORD_LEN, 0}, +{ 0x8CFE, 0x8D21, WORD_LEN, 0}, +{ 0x8D00, 0xB808, WORD_LEN, 0}, +{ 0x8D02, 0x7825, WORD_LEN, 0}, +{ 0x8D04, 0x082F, WORD_LEN, 0}, +{ 0x8D06, 0x00DE, WORD_LEN, 0}, +{ 0x8D08, 0x7108, WORD_LEN, 0}, +{ 0x8D0A, 0x2186, WORD_LEN, 0}, +{ 0x8D0C, 0x0FFE, WORD_LEN, 0}, +{ 0x8D0E, 0x262F, WORD_LEN, 0}, +{ 0x8D10, 0xF04A, WORD_LEN, 0}, +{ 0x8D12, 0xF211, WORD_LEN, 0}, +{ 0x8D14, 0x17BC, WORD_LEN, 0}, +{ 0x8D16, 0xF002, WORD_LEN, 0}, +{ 0x8D18, 0x8A25, WORD_LEN, 0}, +{ 0x8D1A, 0xE906, WORD_LEN, 0}, +{ 0x8D1C, 0xB961, WORD_LEN, 0}, +{ 0x8D1E, 0xAA25, WORD_LEN, 0}, +{ 0x8D20, 0xD806, WORD_LEN, 0}, +{ 0x8D22, 0xF01E, WORD_LEN, 0}, +{ 0x8D24, 0x8A24, WORD_LEN, 0}, +{ 0x8D26, 0xB8A3, WORD_LEN, 0}, +{ 0x8D28, 0xAA25, WORD_LEN, 0}, +{ 0x8D2A, 0x2841, WORD_LEN, 0}, +{ 0x8D2C, 0x0201, WORD_LEN, 0}, +{ 0x8D2E, 0xAD20, WORD_LEN, 0}, +{ 0x8D30, 0xAD01, WORD_LEN, 0}, +{ 0x8D32, 0x0D56, WORD_LEN, 0}, +{ 0x8D34, 0x0144, WORD_LEN, 0}, +{ 0x8D36, 0x1545, WORD_LEN, 0}, +{ 0x8D38, 0x1081, WORD_LEN, 0}, +{ 0x8D3A, 0x1546, WORD_LEN, 0}, +{ 0x8D3C, 0x1082, WORD_LEN, 0}, +{ 0x8D3E, 0xB908, WORD_LEN, 0}, +{ 0x8D40, 0x7945, WORD_LEN, 0}, +{ 0x8D42, 0xB9E0, WORD_LEN, 0}, +{ 0x8D44, 0x26CC, WORD_LEN, 0}, +{ 0x8D46, 0x9022, WORD_LEN, 0}, +{ 0x8D48, 0xF20A, WORD_LEN, 0}, +{ 0x8D4A, 0x8D20, WORD_LEN, 0}, +{ 0x8D4C, 0x8D41, WORD_LEN, 0}, +{ 0x8D4E, 0xB908, WORD_LEN, 0}, +{ 0x8D50, 0x7945, WORD_LEN, 0}, +{ 0x8D52, 0xB983, WORD_LEN, 0}, +{ 0x8D54, 0x2941, WORD_LEN, 0}, +{ 0x8D56, 0x0202, WORD_LEN, 0}, +{ 0x8D58, 0xAD40, WORD_LEN, 0}, +{ 0x8D5A, 0xAD21, WORD_LEN, 0}, +{ 0x8D5C, 0x0561, WORD_LEN, 0}, +{ 0x8D5E, 0x0684, WORD_LEN, 0}, +{ 0x8D60, 0xC0F1, WORD_LEN, 0}, +{ 0x8D62, 0x0CEE, WORD_LEN, 0}, +{ 0x8D64, 0x06A4, WORD_LEN, 0}, +{ 0x8D66, 0x7098, WORD_LEN, 0}, +{ 0x8D68, 0xD284, WORD_LEN, 0}, +{ 0x8D6A, 0x1206, WORD_LEN, 0}, +{ 0x8D6C, 0x0086, WORD_LEN, 0}, +{ 0x8D6E, 0x2240, WORD_LEN, 0}, +{ 0x8D70, 0x0205, WORD_LEN, 0}, +{ 0x8D72, 0x264C, WORD_LEN, 0}, +{ 0x8D74, 0x8000, WORD_LEN, 0}, +{ 0x8D76, 0x20CA, WORD_LEN, 0}, +{ 0x8D78, 0x0101, WORD_LEN, 0}, +{ 0x8D7A, 0xF237, WORD_LEN, 0}, +{ 0x8D7C, 0x8AA7, WORD_LEN, 0}, +{ 0x8D7E, 0x6D69, WORD_LEN, 0}, +{ 0x8D80, 0x7B6D, WORD_LEN, 0}, +{ 0x8D82, 0x0B3F, WORD_LEN, 0}, +{ 0x8D84, 0x0012, WORD_LEN, 0}, +{ 0x8D86, 0x7068, WORD_LEN, 0}, +{ 0x8D88, 0x780D, WORD_LEN, 0}, +{ 0x8D8A, 0x2040, WORD_LEN, 0}, +{ 0x8D8C, 0x007C, WORD_LEN, 0}, +{ 0x8D8E, 0x20A8, WORD_LEN, 0}, +{ 0x8D90, 0x0640, WORD_LEN, 0}, +{ 0x8D92, 0x71CF, WORD_LEN, 0}, +{ 0x8D94, 0xFF80, WORD_LEN, 0}, +{ 0x8D96, 0x0158, WORD_LEN, 0}, +{ 0x8D98, 0x8924, WORD_LEN, 0}, +{ 0x8D9A, 0x2532, WORD_LEN, 0}, +{ 0x8D9C, 0x00C0, WORD_LEN, 0}, +{ 0x8D9E, 0xBD61, WORD_LEN, 0}, +{ 0x8DA0, 0x0819, WORD_LEN, 0}, +{ 0x8DA2, 0x0063, WORD_LEN, 0}, +{ 0x8DA4, 0x7DAF, WORD_LEN, 0}, +{ 0x8DA6, 0x76CF, WORD_LEN, 0}, +{ 0x8DA8, 0xFF80, WORD_LEN, 0}, +{ 0x8DAA, 0x0290, WORD_LEN, 0}, +{ 0x8DAC, 0x8EF1, WORD_LEN, 0}, +{ 0x8DAE, 0x2640, WORD_LEN, 0}, +{ 0x8DB0, 0x1601, WORD_LEN, 0}, +{ 0x8DB2, 0x61E9, WORD_LEN, 0}, +{ 0x8DB4, 0x090F, WORD_LEN, 0}, +{ 0x8DB6, 0x0002, WORD_LEN, 0}, +{ 0x8DB8, 0xAAA7, WORD_LEN, 0}, +{ 0x8DBA, 0xBB61, WORD_LEN, 0}, +{ 0x8DBC, 0x7B6D, WORD_LEN, 0}, +{ 0x8DBE, 0x7088, WORD_LEN, 0}, +{ 0x8DC0, 0xF005, WORD_LEN, 0}, +{ 0x8DC2, 0x8E26, WORD_LEN, 0}, +{ 0x8DC4, 0xAAA7, WORD_LEN, 0}, +{ 0x8DC6, 0xB961, WORD_LEN, 0}, +{ 0x8DC8, 0xAE26, WORD_LEN, 0}, +{ 0x8DCA, 0x0B1F, WORD_LEN, 0}, +{ 0x8DCC, 0x0013, WORD_LEN, 0}, +{ 0x8DCE, 0x1A07, WORD_LEN, 0}, +{ 0x8DD0, 0x0182, WORD_LEN, 0}, +{ 0x8DD2, 0xD26B, WORD_LEN, 0}, +{ 0x8DD4, 0x8A20, WORD_LEN, 0}, +{ 0x8DD6, 0x8A61, WORD_LEN, 0}, +{ 0x8DD8, 0xB908, WORD_LEN, 0}, +{ 0x8DDA, 0x7965, WORD_LEN, 0}, +{ 0x8DDC, 0xB9A3, WORD_LEN, 0}, +{ 0x8DDE, 0x2941, WORD_LEN, 0}, +{ 0x8DE0, 0x020C, WORD_LEN, 0}, +{ 0x8DE2, 0xAA80, WORD_LEN, 0}, +{ 0x8DE4, 0xAA21, WORD_LEN, 0}, +{ 0x8DE6, 0x04D1, WORD_LEN, 0}, +{ 0x8DE8, 0x0684, WORD_LEN, 0}, +{ 0x8DEA, 0x78E0, WORD_LEN, 0}, +{ 0x8DEC, 0xC0F1, WORD_LEN, 0}, +{ 0x8DEE, 0xC5E1, WORD_LEN, 0}, +{ 0x8DF0, 0xD363, WORD_LEN, 0}, +{ 0x8DF2, 0x8B24, WORD_LEN, 0}, +{ 0x8DF4, 0x8B45, WORD_LEN, 0}, +{ 0x8DF6, 0xB908, WORD_LEN, 0}, +{ 0x8DF8, 0x7945, WORD_LEN, 0}, +{ 0x8DFA, 0xE188, WORD_LEN, 0}, +{ 0x8DFC, 0x21CC, WORD_LEN, 0}, +{ 0x8DFE, 0x8422, WORD_LEN, 0}, +{ 0x8E00, 0xF41F, WORD_LEN, 0}, +{ 0x8E02, 0x8B26, WORD_LEN, 0}, +{ 0x8E04, 0x093B, WORD_LEN, 0}, +{ 0x8E06, 0x0051, WORD_LEN, 0}, +{ 0x8E08, 0xD15C, WORD_LEN, 0}, +{ 0x8E0A, 0xD80A, WORD_LEN, 0}, +{ 0x8E0C, 0xA90E, WORD_LEN, 0}, +{ 0x8E0E, 0xD05D, WORD_LEN, 0}, +{ 0x8E10, 0x8804, WORD_LEN, 0}, +{ 0x8E12, 0x1330, WORD_LEN, 0}, +{ 0x8E14, 0x0082, WORD_LEN, 0}, +{ 0x8E16, 0x1331, WORD_LEN, 0}, +{ 0x8E18, 0x008D, WORD_LEN, 0}, +{ 0x8E1A, 0xBA08, WORD_LEN, 0}, +{ 0x8E1C, 0x7AA5, WORD_LEN, 0}, +{ 0x8E1E, 0xB148, WORD_LEN, 0}, +{ 0x8E20, 0x8952, WORD_LEN, 0}, +{ 0x8E22, 0xA90F, WORD_LEN, 0}, +{ 0x8E24, 0x0813, WORD_LEN, 0}, +{ 0x8E26, 0x00A2, WORD_LEN, 0}, +{ 0x8E28, 0x132C, WORD_LEN, 0}, +{ 0x8E2A, 0x0083, WORD_LEN, 0}, +{ 0x8E2C, 0xDA00, WORD_LEN, 0}, +{ 0x8E2E, 0xA953, WORD_LEN, 0}, +{ 0x8E30, 0x7862, WORD_LEN, 0}, +{ 0x8E32, 0x780F, WORD_LEN, 0}, +{ 0x8E34, 0xF005, WORD_LEN, 0}, +{ 0x8E36, 0xDA01, WORD_LEN, 0}, +{ 0x8E38, 0xA953, WORD_LEN, 0}, +{ 0x8E3A, 0x6078, WORD_LEN, 0}, +{ 0x8E3C, 0x780F, WORD_LEN, 0}, +{ 0x8E3E, 0x080E, WORD_LEN, 0}, +{ 0x8E40, 0x0000, WORD_LEN, 0}, +{ 0x8E42, 0x0485, WORD_LEN, 0}, +{ 0x8E44, 0x0684, WORD_LEN, 0}, +{ 0x8E46, 0x78E0, WORD_LEN, 0}, +{ 0x8E48, 0xC0F1, WORD_LEN, 0}, +{ 0x8E4A, 0x0BFE, WORD_LEN, 0}, +{ 0x8E4C, 0x0684, WORD_LEN, 0}, +{ 0x8E4E, 0xD64D, WORD_LEN, 0}, +{ 0x8E50, 0x7508, WORD_LEN, 0}, +{ 0x8E52, 0x8E01, WORD_LEN, 0}, +{ 0x8E54, 0xD14A, WORD_LEN, 0}, +{ 0x8E56, 0x2046, WORD_LEN, 0}, +{ 0x8E58, 0x00C0, WORD_LEN, 0}, +{ 0x8E5A, 0xAE01, WORD_LEN, 0}, +{ 0x8E5C, 0x1145, WORD_LEN, 0}, +{ 0x8E5E, 0x0080, WORD_LEN, 0}, +{ 0x8E60, 0x1146, WORD_LEN, 0}, +{ 0x8E62, 0x0082, WORD_LEN, 0}, +{ 0x8E64, 0xB808, WORD_LEN, 0}, +{ 0x8E66, 0x7845, WORD_LEN, 0}, +{ 0x8E68, 0x0817, WORD_LEN, 0}, +{ 0x8E6A, 0x001E, WORD_LEN, 0}, +{ 0x8E6C, 0x8900, WORD_LEN, 0}, +{ 0x8E6E, 0x8941, WORD_LEN, 0}, +{ 0x8E70, 0xB808, WORD_LEN, 0}, +{ 0x8E72, 0x7845, WORD_LEN, 0}, +{ 0x8E74, 0x080B, WORD_LEN, 0}, +{ 0x8E76, 0x00DE, WORD_LEN, 0}, +{ 0x8E78, 0x70A9, WORD_LEN, 0}, +{ 0x8E7A, 0xFFBA, WORD_LEN, 0}, +{ 0x8E7C, 0x7508, WORD_LEN, 0}, +{ 0x8E7E, 0x1604, WORD_LEN, 0}, +{ 0x8E80, 0x1090, WORD_LEN, 0}, +{ 0x8E82, 0x0D93, WORD_LEN, 0}, +{ 0x8E84, 0x1400, WORD_LEN, 0}, +{ 0x8E86, 0x8EEA, WORD_LEN, 0}, +{ 0x8E88, 0x8E0B, WORD_LEN, 0}, +{ 0x8E8A, 0x214A, WORD_LEN, 0}, +{ 0x8E8C, 0x2040, WORD_LEN, 0}, +{ 0x8E8E, 0x8E2D, WORD_LEN, 0}, +{ 0x8E90, 0xBF08, WORD_LEN, 0}, +{ 0x8E92, 0x7F05, WORD_LEN, 0}, +{ 0x8E94, 0x8E0C, WORD_LEN, 0}, +{ 0x8E96, 0xB808, WORD_LEN, 0}, +{ 0x8E98, 0x7825, WORD_LEN, 0}, +{ 0x8E9A, 0x7710, WORD_LEN, 0}, +{ 0x8E9C, 0x21C2, WORD_LEN, 0}, +{ 0x8E9E, 0x244C, WORD_LEN, 0}, +{ 0x8EA0, 0x081D, WORD_LEN, 0}, +{ 0x8EA2, 0x03E3, WORD_LEN, 0}, +{ 0x8EA4, 0xD9FF, WORD_LEN, 0}, +{ 0x8EA6, 0x2702, WORD_LEN, 0}, +{ 0x8EA8, 0x1002, WORD_LEN, 0}, +{ 0x8EAA, 0x2A05, WORD_LEN, 0}, +{ 0x8EAC, 0x037E, WORD_LEN, 0}, +{ 0x8EAE, 0x0C7A, WORD_LEN, 0}, +{ 0x8EB0, 0x06A4, WORD_LEN, 0}, +{ 0x8EB2, 0x702F, WORD_LEN, 0}, +{ 0x8EB4, 0x7810, WORD_LEN, 0}, +{ 0x8EB6, 0x7F02, WORD_LEN, 0}, +{ 0x8EB8, 0x7FF0, WORD_LEN, 0}, +{ 0x8EBA, 0xF00B, WORD_LEN, 0}, +{ 0x8EBC, 0x78E2, WORD_LEN, 0}, +{ 0x8EBE, 0x2805, WORD_LEN, 0}, +{ 0x8EC0, 0x037E, WORD_LEN, 0}, +{ 0x8EC2, 0x0C66, WORD_LEN, 0}, +{ 0x8EC4, 0x06A4, WORD_LEN, 0}, +{ 0x8EC6, 0x702F, WORD_LEN, 0}, +{ 0x8EC8, 0x7810, WORD_LEN, 0}, +{ 0x8ECA, 0x671F, WORD_LEN, 0}, +{ 0x8ECC, 0x7FF0, WORD_LEN, 0}, +{ 0x8ECE, 0x7FEF, WORD_LEN, 0}, +{ 0x8ED0, 0x8E08, WORD_LEN, 0}, +{ 0x8ED2, 0xBF06, WORD_LEN, 0}, +{ 0x8ED4, 0xD12C, WORD_LEN, 0}, +{ 0x8ED6, 0xB8C3, WORD_LEN, 0}, +{ 0x8ED8, 0x78E5, WORD_LEN, 0}, +{ 0x8EDA, 0xB88F, WORD_LEN, 0}, +{ 0x8EDC, 0x1908, WORD_LEN, 0}, +{ 0x8EDE, 0x0024, WORD_LEN, 0}, +{ 0x8EE0, 0x2841, WORD_LEN, 0}, +{ 0x8EE2, 0x0201, WORD_LEN, 0}, +{ 0x8EE4, 0x1E26, WORD_LEN, 0}, +{ 0x8EE6, 0x1042, WORD_LEN, 0}, +{ 0x8EE8, 0x0D15, WORD_LEN, 0}, +{ 0x8EEA, 0x1423, WORD_LEN, 0}, +{ 0x8EEC, 0x1E27, WORD_LEN, 0}, +{ 0x8EEE, 0x1002, WORD_LEN, 0}, +{ 0x8EF0, 0x214C, WORD_LEN, 0}, +{ 0x8EF2, 0xA000, WORD_LEN, 0}, +{ 0x8EF4, 0x214A, WORD_LEN, 0}, +{ 0x8EF6, 0x2040, WORD_LEN, 0}, +{ 0x8EF8, 0x21C2, WORD_LEN, 0}, +{ 0x8EFA, 0x2442, WORD_LEN, 0}, +{ 0x8EFC, 0x8E21, WORD_LEN, 0}, +{ 0x8EFE, 0x214F, WORD_LEN, 0}, +{ 0x8F00, 0x0040, WORD_LEN, 0}, +{ 0x8F02, 0x090F, WORD_LEN, 0}, +{ 0x8F04, 0x2010, WORD_LEN, 0}, +{ 0x8F06, 0x2145, WORD_LEN, 0}, +{ 0x8F08, 0x0181, WORD_LEN, 0}, +{ 0x8F0A, 0xAE21, WORD_LEN, 0}, +{ 0x8F0C, 0xF003, WORD_LEN, 0}, +{ 0x8F0E, 0xB8A2, WORD_LEN, 0}, +{ 0x8F10, 0xAE01, WORD_LEN, 0}, +{ 0x8F12, 0x0FFE, WORD_LEN, 0}, +{ 0x8F14, 0xFFA3, WORD_LEN, 0}, +{ 0x8F16, 0x70A9, WORD_LEN, 0}, +{ 0x8F18, 0x038D, WORD_LEN, 0}, +{ 0x8F1A, 0x0684, WORD_LEN, 0}, +{ 0x8F1C, 0xC0F1, WORD_LEN, 0}, +{ 0x8F1E, 0xC5E1, WORD_LEN, 0}, +{ 0x8F20, 0xD518, WORD_LEN, 0}, +{ 0x8F22, 0x8D00, WORD_LEN, 0}, +{ 0x8F24, 0xB8E7, WORD_LEN, 0}, +{ 0x8F26, 0x20D1, WORD_LEN, 0}, +{ 0x8F28, 0x80E2, WORD_LEN, 0}, +{ 0x8F2A, 0xF20D, WORD_LEN, 0}, +{ 0x8F2C, 0xD117, WORD_LEN, 0}, +{ 0x8F2E, 0xB8A7, WORD_LEN, 0}, +{ 0x8F30, 0xAD00, WORD_LEN, 0}, +{ 0x8F32, 0xD017, WORD_LEN, 0}, +{ 0x8F34, 0x7228, WORD_LEN, 0}, +{ 0x8F36, 0x8123, WORD_LEN, 0}, +{ 0x8F38, 0xA040, WORD_LEN, 0}, +{ 0x8F3A, 0x7960, WORD_LEN, 0}, +{ 0x8F3C, 0xD801, WORD_LEN, 0}, +{ 0x8F3E, 0xD800, WORD_LEN, 0}, +{ 0x8F40, 0xAD05, WORD_LEN, 0}, +{ 0x8F42, 0x0F56, WORD_LEN, 0}, +{ 0x8F44, 0xFF83, WORD_LEN, 0}, +{ 0x8F46, 0x0381, WORD_LEN, 0}, +{ 0x8F48, 0x0684, WORD_LEN, 0}, +{ 0x8F4A, 0x78E0, WORD_LEN, 0}, +{ 0x8F4C, 0xD20D, WORD_LEN, 0}, +{ 0x8F4E, 0x8A21, WORD_LEN, 0}, +{ 0x8F50, 0xB9A1, WORD_LEN, 0}, +{ 0x8F52, 0x782F, WORD_LEN, 0}, +{ 0x8F54, 0x7FE0, WORD_LEN, 0}, +{ 0x8F56, 0xAA21, WORD_LEN, 0}, +{ 0x8F58, 0xD00E, WORD_LEN, 0}, +{ 0x8F5A, 0xD10C, WORD_LEN, 0}, +{ 0x8F5C, 0xA100, WORD_LEN, 0}, +{ 0x8F5E, 0xD00E, WORD_LEN, 0}, +{ 0x8F60, 0xA101, WORD_LEN, 0}, +{ 0x8F62, 0xD00E, WORD_LEN, 0}, +{ 0x8F64, 0xA102, WORD_LEN, 0}, +{ 0x8F66, 0xD00E, WORD_LEN, 0}, +{ 0x8F68, 0xA103, WORD_LEN, 0}, +{ 0x8F6A, 0xD009, WORD_LEN, 0}, +{ 0x8F6C, 0xA020, WORD_LEN, 0}, +{ 0x8F6E, 0xD005, WORD_LEN, 0}, +{ 0x8F70, 0xD988, WORD_LEN, 0}, +{ 0x8F72, 0xA820, WORD_LEN, 0}, +{ 0x8F74, 0xF1D4, WORD_LEN, 0}, +{ 0x8F76, 0x78E0, WORD_LEN, 0}, +{ 0x8F78, 0xFF80, WORD_LEN, 0}, +{ 0x8F7A, 0x10C8, WORD_LEN, 0}, +{ 0x8F7C, 0xFF80, WORD_LEN, 0}, +{ 0x8F7E, 0x0290, WORD_LEN, 0}, +{ 0x8F80, 0xFF80, WORD_LEN, 0}, +{ 0x8F82, 0x0158, WORD_LEN, 0}, +{ 0x8F84, 0xFF00, WORD_LEN, 0}, +{ 0x8F86, 0x0618, WORD_LEN, 0}, +{ 0x8F88, 0xFF80, WORD_LEN, 0}, +{ 0x8F8A, 0x1158, WORD_LEN, 0}, +{ 0x8F8C, 0x8000, WORD_LEN, 0}, +{ 0x8F8E, 0x0008, WORD_LEN, 0}, +{ 0x8F90, 0xFF80, WORD_LEN, 0}, +{ 0x8F92, 0x0F1C, WORD_LEN, 0}, +{ 0x8F94, 0xFF80, WORD_LEN, 0}, +{ 0x8F96, 0x0DEC, WORD_LEN, 0}, +{ 0x8F98, 0xFF80, WORD_LEN, 0}, +{ 0x8F9A, 0x0F4C, WORD_LEN, 0}, +{ 0x8F9C, 0x0000, WORD_LEN, 0}, +{ 0x8F9E, 0x0998, WORD_LEN, 0}, +{ 0x8FA0, 0xC0F1, WORD_LEN, 0}, +{ 0x8FA2, 0xC5E1, WORD_LEN, 0}, +{ 0x8FA4, 0xD02C, WORD_LEN, 0}, +{ 0x8FA6, 0x0982, WORD_LEN, 0}, +{ 0x8FA8, 0x0664, WORD_LEN, 0}, +{ 0x8FAA, 0x88AE, WORD_LEN, 0}, +{ 0x8FAC, 0x0D23, WORD_LEN, 0}, +{ 0x8FAE, 0x1051, WORD_LEN, 0}, +{ 0x8FB0, 0xD12A, WORD_LEN, 0}, +{ 0x8FB2, 0x1145, WORD_LEN, 0}, +{ 0x8FB4, 0x0080, WORD_LEN, 0}, +{ 0x8FB6, 0x1146, WORD_LEN, 0}, +{ 0x8FB8, 0x0082, WORD_LEN, 0}, +{ 0x8FBA, 0xB808, WORD_LEN, 0}, +{ 0x8FBC, 0x7845, WORD_LEN, 0}, +{ 0x8FBE, 0x0813, WORD_LEN, 0}, +{ 0x8FC0, 0x00DE, WORD_LEN, 0}, +{ 0x8FC2, 0xD027, WORD_LEN, 0}, +{ 0x8FC4, 0x8000, WORD_LEN, 0}, +{ 0x8FC6, 0x8041, WORD_LEN, 0}, +{ 0x8FC8, 0x7A60, WORD_LEN, 0}, +{ 0x8FCA, 0x1150, WORD_LEN, 0}, +{ 0x8FCC, 0x0080, WORD_LEN, 0}, +{ 0x8FCE, 0x02F9, WORD_LEN, 0}, +{ 0x8FD0, 0x0684, WORD_LEN, 0}, +{ 0x8FD2, 0x78E0, WORD_LEN, 0}, +{ 0x8FD4, 0xC0F1, WORD_LEN, 0}, +{ 0x8FD6, 0x0A7E, WORD_LEN, 0}, +{ 0x8FD8, 0x0684, WORD_LEN, 0}, +{ 0x8FDA, 0xD622, WORD_LEN, 0}, +{ 0x8FDC, 0x8EA9, WORD_LEN, 0}, +{ 0x8FDE, 0x8E2A, WORD_LEN, 0}, +{ 0x8FE0, 0xBD08, WORD_LEN, 0}, +{ 0x8FE2, 0x7D25, WORD_LEN, 0}, +{ 0x8FE4, 0x2550, WORD_LEN, 0}, +{ 0x8FE6, 0x10C2, WORD_LEN, 0}, +{ 0x8FE8, 0x2A41, WORD_LEN, 0}, +{ 0x8FEA, 0x0201, WORD_LEN, 0}, +{ 0x8FEC, 0xAE29, WORD_LEN, 0}, +{ 0x8FEE, 0x0F9A, WORD_LEN, 0}, +{ 0x8FF0, 0x05A4, WORD_LEN, 0}, +{ 0x8FF2, 0xAE4A, WORD_LEN, 0}, +{ 0x8FF4, 0x0D17, WORD_LEN, 0}, +{ 0x8FF6, 0x10DE, WORD_LEN, 0}, +{ 0x8FF8, 0x8E09, WORD_LEN, 0}, +{ 0x8FFA, 0x8E2A, WORD_LEN, 0}, +{ 0x8FFC, 0xB808, WORD_LEN, 0}, +{ 0x8FFE, 0x7825, WORD_LEN, 0}, +{ 0x9000, 0xB883, WORD_LEN, 0}, +{ 0x9002, 0x2841, WORD_LEN, 0}, +{ 0x9004, 0x0201, WORD_LEN, 0}, +{ 0x9006, 0xAE29, WORD_LEN, 0}, +{ 0x9008, 0xAE0A, WORD_LEN, 0}, +{ 0x900A, 0x02B5, WORD_LEN, 0}, +{ 0x900C, 0x0684, WORD_LEN, 0}, +{ 0x900E, 0x78E0, WORD_LEN, 0}, +{ 0x9010, 0xC0F1, WORD_LEN, 0}, +{ 0x9012, 0x0A42, WORD_LEN, 0}, +{ 0x9014, 0x06A4, WORD_LEN, 0}, +{ 0x9016, 0xDA34, WORD_LEN, 0}, +{ 0x9018, 0xD113, WORD_LEN, 0}, +{ 0x901A, 0xD514, WORD_LEN, 0}, +{ 0x901C, 0x76A9, WORD_LEN, 0}, +{ 0x901E, 0x0FD6, WORD_LEN, 0}, +{ 0x9020, 0x0664, WORD_LEN, 0}, +{ 0x9022, 0x70C9, WORD_LEN, 0}, +{ 0x9024, 0xD012, WORD_LEN, 0}, +{ 0x9026, 0xA504, WORD_LEN, 0}, +{ 0x9028, 0xD012, WORD_LEN, 0}, +{ 0x902A, 0x0295, WORD_LEN, 0}, +{ 0x902C, 0x06A4, WORD_LEN, 0}, +{ 0x902E, 0xA0C0, WORD_LEN, 0}, +{ 0x9030, 0xC0F1, WORD_LEN, 0}, +{ 0x9032, 0xC5E1, WORD_LEN, 0}, +{ 0x9034, 0xD50D, WORD_LEN, 0}, +{ 0x9036, 0xD110, WORD_LEN, 0}, +{ 0x9038, 0x2540, WORD_LEN, 0}, +{ 0x903A, 0x1D00, WORD_LEN, 0}, +{ 0x903C, 0x0FB6, WORD_LEN, 0}, +{ 0x903E, 0x0664, WORD_LEN, 0}, +{ 0x9040, 0xDA50, WORD_LEN, 0}, +{ 0x9042, 0xD00E, WORD_LEN, 0}, +{ 0x9044, 0x2540, WORD_LEN, 0}, +{ 0x9046, 0x1D01, WORD_LEN, 0}, +{ 0x9048, 0xA517, WORD_LEN, 0}, +{ 0x904A, 0xD00D, WORD_LEN, 0}, +{ 0x904C, 0x0279, WORD_LEN, 0}, +{ 0x904E, 0x06A4, WORD_LEN, 0}, +{ 0x9050, 0xA020, WORD_LEN, 0}, +{ 0x9052, 0x78E0, WORD_LEN, 0}, +{ 0x9054, 0xFF80, WORD_LEN, 0}, +{ 0x9056, 0x07A8, WORD_LEN, 0}, +{ 0x9058, 0xFF80, WORD_LEN, 0}, +{ 0x905A, 0x0290, WORD_LEN, 0}, +{ 0x905C, 0x8000, WORD_LEN, 0}, +{ 0x905E, 0x0008, WORD_LEN, 0}, +{ 0x9060, 0xFF80, WORD_LEN, 0}, +{ 0x9062, 0x02CC, WORD_LEN, 0}, +{ 0x9064, 0x0000, WORD_LEN, 0}, +{ 0x9066, 0xFA88, WORD_LEN, 0}, +{ 0x9068, 0xFF80, WORD_LEN, 0}, +{ 0x906A, 0x1168, WORD_LEN, 0}, +{ 0x906C, 0xFF80, WORD_LEN, 0}, +{ 0x906E, 0x0FD4, WORD_LEN, 0}, +{ 0x9070, 0x8000, WORD_LEN, 0}, +{ 0x9072, 0x0194, WORD_LEN, 0}, +{ 0x9074, 0x0000, WORD_LEN, 0}, +{ 0x9076, 0xFB08, WORD_LEN, 0}, +{ 0x9078, 0xFF80, WORD_LEN, 0}, +{ 0x907A, 0x0FA0, WORD_LEN, 0}, +{ 0x907C, 0x8000, WORD_LEN, 0}, +{ 0x907E, 0x01A0, WORD_LEN, 0}, +{ 0x9080, 0xE280, WORD_LEN, 0}, +{ 0x9082, 0x24CA, WORD_LEN, 0}, +{ 0x9084, 0x7082, WORD_LEN, 0}, +{ 0x9086, 0x78E0, WORD_LEN, 0}, +{ 0x9088, 0x20E8, WORD_LEN, 0}, +{ 0x908A, 0x01A2, WORD_LEN, 0}, +{ 0x908C, 0x1002, WORD_LEN, 0}, +{ 0x908E, 0x0D02, WORD_LEN, 0}, +{ 0x9090, 0x1902, WORD_LEN, 0}, +{ 0x9092, 0x0094, WORD_LEN, 0}, +{ 0x9094, 0x7FE0, WORD_LEN, 0}, +{ 0x9096, 0x7028, WORD_LEN, 0}, +{ 0x9098, 0x7308, WORD_LEN, 0}, +{ 0x909A, 0x1000, WORD_LEN, 0}, +{ 0x909C, 0x0900, WORD_LEN, 0}, +{ 0x909E, 0x7904, WORD_LEN, 0}, +{ 0x90A0, 0x7947, WORD_LEN, 0}, +{ 0x90A2, 0x1B00, WORD_LEN, 0}, +{ 0x90A4, 0x0064, WORD_LEN, 0}, +{ 0x90A6, 0x7EE0, WORD_LEN, 0}, +{ 0x90A8, 0xE280, WORD_LEN, 0}, +{ 0x90AA, 0x24CA, WORD_LEN, 0}, +{ 0x90AC, 0x7082, WORD_LEN, 0}, +{ 0x90AE, 0x78E0, WORD_LEN, 0}, +{ 0x90B0, 0x20E8, WORD_LEN, 0}, +{ 0x90B2, 0x01A2, WORD_LEN, 0}, +{ 0x90B4, 0x1102, WORD_LEN, 0}, +{ 0x90B6, 0x0502, WORD_LEN, 0}, +{ 0x90B8, 0x1802, WORD_LEN, 0}, +{ 0x90BA, 0x00B4, WORD_LEN, 0}, +{ 0x90BC, 0x7FE0, WORD_LEN, 0}, +{ 0x90BE, 0x7028, WORD_LEN, 0}, +{ 0x90C0, 0x0000, WORD_LEN, 0}, +{ 0x90C2, 0x0000, WORD_LEN, 0}, +{ 0x90C4, 0x0000, WORD_LEN, 0}, +{ 0x90C6, 0x0000, WORD_LEN, 0}, +{ 0x098E, 0x0000, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS +{ 0x8016, 0x086C, WORD_LEN, 0}, // MON_ADDRESS_LO +{ 0x8018, 0xFF80, WORD_LEN, 0}, // MON_ADDRESS_HI +{ 0x8002, 0x0001, WORD_LEN, 0}, // MON_CMD +//delay = 100 +{ SEQUENCE_WAIT_MS,100, BYTE_LEN, 0}, + +//[Lens Correction 90% 02/04/13 18:03:18] +//BITFIELD= 0x3210, 0x0008, 0 //PGA_ENABLE +{ 0x3210, 0x0008, WORD_LEN, 0}, +{ 0x3210, 0x49B0, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL +{ 0x3640, 0x0170, WORD_LEN, 0}, // P_G1_P0Q0 +{ 0x3642, 0x0BCC, WORD_LEN, 0}, // P_G1_P0Q1 +{ 0x3644, 0x7210, WORD_LEN, 0}, // P_G1_P0Q2 +{ 0x3646, 0x4C8D, WORD_LEN, 0}, // P_G1_P0Q3 +{ 0x3648, 0xF58D, WORD_LEN, 0}, // P_G1_P0Q4 +{ 0x364A, 0x0610, WORD_LEN, 0}, // P_R_P0Q0 +{ 0x364C, 0x8D6E, WORD_LEN, 0}, // P_R_P0Q1 +{ 0x364E, 0x6E90, WORD_LEN, 0}, // P_R_P0Q2 +{ 0x3650, 0x088F, WORD_LEN, 0}, // P_R_P0Q3 +{ 0x3652, 0xA890, WORD_LEN, 0}, // P_R_P0Q4 +{ 0x3654, 0x0550, WORD_LEN, 0}, // P_B_P0Q0 +{ 0x3656, 0x764C, WORD_LEN, 0}, // P_B_P0Q1 +{ 0x3658, 0x0FB0, WORD_LEN, 0}, // P_B_P0Q2 +{ 0x365A, 0x9A0D, WORD_LEN, 0}, // P_B_P0Q3 +{ 0x365C, 0xF4AD, WORD_LEN, 0}, // P_B_P0Q4 +{ 0x365E, 0x02F0, WORD_LEN, 0}, // P_G2_P0Q0 +{ 0x3660, 0x9A0E, WORD_LEN, 0}, // P_G2_P0Q1 +{ 0x3662, 0x77B0, WORD_LEN, 0}, // P_G2_P0Q2 +{ 0x3664, 0x416D, WORD_LEN, 0}, // P_G2_P0Q3 +{ 0x3666, 0xF24D, WORD_LEN, 0}, // P_G2_P0Q4 +{ 0x3680, 0x018A, WORD_LEN, 0}, // P_G1_P1Q0 +{ 0x3682, 0xD0AD, WORD_LEN, 0}, // P_G1_P1Q1 +{ 0x3684, 0xC62E, WORD_LEN, 0}, // P_G1_P1Q2 +{ 0x3686, 0x736D, WORD_LEN, 0}, // P_G1_P1Q3 +{ 0x3688, 0x0130, WORD_LEN, 0}, // P_G1_P1Q4 +{ 0x368A, 0x52ED, WORD_LEN, 0}, // P_R_P1Q0 +{ 0x368C, 0x682D, WORD_LEN, 0}, // P_R_P1Q1 +{ 0x368E, 0xF02B, WORD_LEN, 0}, // P_R_P1Q2 +{ 0x3690, 0xB68E, WORD_LEN, 0}, // P_R_P1Q3 +{ 0x3692, 0xF4AD, WORD_LEN, 0}, // P_R_P1Q4 +{ 0x3694, 0xC68D, WORD_LEN, 0}, // P_B_P1Q0 +{ 0x3696, 0x440D, WORD_LEN, 0}, // P_B_P1Q1 +{ 0x3698, 0x416E, WORD_LEN, 0}, // P_B_P1Q2 +{ 0x369A, 0xC0CE, WORD_LEN, 0}, // P_B_P1Q3 +{ 0x369C, 0xB46D, WORD_LEN, 0}, // P_B_P1Q4 +{ 0x369E, 0xD90A, WORD_LEN, 0}, // P_G2_P1Q0 +{ 0x36A0, 0xD76D, WORD_LEN, 0}, // P_G2_P1Q1 +{ 0x36A2, 0xFE0D, WORD_LEN, 0}, // P_G2_P1Q2 +{ 0x36A4, 0x0E0D, WORD_LEN, 0}, // P_G2_P1Q3 +{ 0x36A6, 0x0890, WORD_LEN, 0}, // P_G2_P1Q4 +{ 0x36C0, 0x70D0, WORD_LEN, 0}, // P_G1_P2Q0 +{ 0x36C2, 0x10CF, WORD_LEN, 0}, // P_G1_P2Q1 +{ 0x36C4, 0x4592, WORD_LEN, 0}, // P_G1_P2Q2 +{ 0x36C6, 0xB74D, WORD_LEN, 0}, // P_G1_P2Q3 +{ 0x36C8, 0xEEB3, WORD_LEN, 0}, // P_G1_P2Q4 +{ 0x36CA, 0x1991, WORD_LEN, 0}, // P_R_P2Q0 +{ 0x36CC, 0x9B8E, WORD_LEN, 0}, // P_R_P2Q1 +{ 0x36CE, 0x5DCD, WORD_LEN, 0}, // P_R_P2Q2 +{ 0x36D0, 0x1C8D, WORD_LEN, 0}, // P_R_P2Q3 +{ 0x36D2, 0x8C71, WORD_LEN, 0}, // P_R_P2Q4 +{ 0x36D4, 0x00F1, WORD_LEN, 0}, // P_B_P2Q0 +{ 0x36D6, 0x480F, WORD_LEN, 0}, // P_B_P2Q1 +{ 0x36D8, 0x26AF, WORD_LEN, 0}, // P_B_P2Q2 +{ 0x36DA, 0xC2EF, WORD_LEN, 0}, // P_B_P2Q3 +{ 0x36DC, 0xFC8F, WORD_LEN, 0}, // P_B_P2Q4 +{ 0x36DE, 0x0071, WORD_LEN, 0}, // P_G2_P2Q0 +{ 0x36E0, 0x8230, WORD_LEN, 0}, // P_G2_P2Q1 +{ 0x36E2, 0x60B2, WORD_LEN, 0}, // P_G2_P2Q2 +{ 0x36E4, 0x3E51, WORD_LEN, 0}, // P_G2_P2Q3 +{ 0x36E6, 0x8C74, WORD_LEN, 0}, // P_G2_P2Q4 +{ 0x3700, 0x492E, WORD_LEN, 0}, // P_G1_P3Q0 +{ 0x3702, 0x7FAD, WORD_LEN, 0}, // P_G1_P3Q1 +{ 0x3704, 0x93CE, WORD_LEN, 0}, // P_G1_P3Q2 +{ 0x3706, 0xC86F, WORD_LEN, 0}, // P_G1_P3Q3 +{ 0x3708, 0xC830, WORD_LEN, 0}, // P_G1_P3Q4 +{ 0x370A, 0x610E, WORD_LEN, 0}, // P_R_P3Q0 +{ 0x370C, 0x8EC8, WORD_LEN, 0}, // P_R_P3Q1 +{ 0x370E, 0xA930, WORD_LEN, 0}, // P_R_P3Q2 +{ 0x3710, 0xE88D, WORD_LEN, 0}, // P_R_P3Q3 +{ 0x3712, 0x2B51, WORD_LEN, 0}, // P_R_P3Q4 +{ 0x3714, 0xDECD, WORD_LEN, 0}, // P_B_P3Q0 +{ 0x3716, 0xBD8E, WORD_LEN, 0}, // P_B_P3Q1 +{ 0x3718, 0x2E50, WORD_LEN, 0}, // P_B_P3Q2 +{ 0x371A, 0x60AF, WORD_LEN, 0}, // P_B_P3Q3 +{ 0x371C, 0xBB11, WORD_LEN, 0}, // P_B_P3Q4 +{ 0x371E, 0x22CB, WORD_LEN, 0}, // P_G2_P3Q0 +{ 0x3720, 0xEEEC, WORD_LEN, 0}, // P_G2_P3Q1 +{ 0x3722, 0x0251, WORD_LEN, 0}, // P_G2_P3Q2 +{ 0x3724, 0x142D, WORD_LEN, 0}, // P_G2_P3Q3 +{ 0x3726, 0xE271, WORD_LEN, 0}, // P_G2_P3Q4 +{ 0x3740, 0x1D10, WORD_LEN, 0}, // P_G1_P4Q0 +{ 0x3742, 0xE94F, WORD_LEN, 0}, // P_G1_P4Q1 +{ 0x3744, 0x8735, WORD_LEN, 0}, // P_G1_P4Q2 +{ 0x3746, 0xC2CC, WORD_LEN, 0}, // P_G1_P4Q3 +{ 0x3748, 0x23F6, WORD_LEN, 0}, // P_G1_P4Q4 +{ 0x374A, 0xE90F, WORD_LEN, 0}, // P_R_P4Q0 +{ 0x374C, 0x1A30, WORD_LEN, 0}, // P_R_P4Q1 +{ 0x374E, 0xAEF3, WORD_LEN, 0}, // P_R_P4Q2 +{ 0x3750, 0xB2F2, WORD_LEN, 0}, // P_R_P4Q3 +{ 0x3752, 0x2195, WORD_LEN, 0}, // P_R_P4Q4 +{ 0x3754, 0xFFEE, WORD_LEN, 0}, // P_B_P4Q0 +{ 0x3756, 0xD8D0, WORD_LEN, 0}, // P_B_P4Q1 +{ 0x3758, 0xCC92, WORD_LEN, 0}, // P_B_P4Q2 +{ 0x375A, 0x0451, WORD_LEN, 0}, // P_B_P4Q3 +{ 0x375C, 0x5814, WORD_LEN, 0}, // P_B_P4Q4 +{ 0x375E, 0x2470, WORD_LEN, 0}, // P_G2_P4Q0 +{ 0x3760, 0x6151, WORD_LEN, 0}, // P_G2_P4Q1 +{ 0x3762, 0x9555, WORD_LEN, 0}, // P_G2_P4Q2 +{ 0x3764, 0xD5D3, WORD_LEN, 0}, // P_G2_P4Q3 +{ 0x3766, 0x3B56, WORD_LEN, 0}, // P_G2_P4Q4 +{ 0x3782, 0x03DC, WORD_LEN, 0}, // CENTER_ROW +{ 0x3784, 0x04E0, WORD_LEN, 0}, // CENTER_COLUMN +{ 0x3210, 0x49B8, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL +//BITFIELD= 0x3210, 0x0008, 1 //PGA_ENABLE +//{ 0x3210, 0x0008, WORD_LEN, 0}, + + + +//[*********Step6************] +//[Step6-AWB_CCM] +//[AWB_setup] + +{ 0xAC01, 0xBB, BYTE_LEN, 0}, // AWB_MODE +//[CCM] +{ 0xAC46, 0x0221, WORD_LEN, 0}, // AWB_LEFT_CCM_0 +{ 0xAC48, 0xFEAE, WORD_LEN, 0}, // AWB_LEFT_CCM_1 +{ 0xAC4A, 0x0032, WORD_LEN, 0}, // AWB_LEFT_CCM_2 +{ 0xAC4C, 0xFFC5, WORD_LEN, 0}, // AWB_LEFT_CCM_3 +{ 0xAC4E, 0x0154, WORD_LEN, 0}, // AWB_LEFT_CCM_4 +{ 0xAC50, 0xFFE7, WORD_LEN, 0}, // AWB_LEFT_CCM_5 +{ 0xAC52, 0xFFB1, WORD_LEN, 0}, // AWB_LEFT_CCM_6 +{ 0xAC54, 0xFEC5, WORD_LEN, 0}, // AWB_LEFT_CCM_7 +{ 0xAC56, 0x028A, WORD_LEN, 0}, // AWB_LEFT_CCM_8 +{ 0xAC58, 0x00C6, WORD_LEN, 0}, // AWB_LEFT_CCM_R2BRATIO +{ 0xAC5C, 0x01CD, WORD_LEN, 0}, // AWB_RIGHT_CCM_0 +{ 0xAC5E, 0xFF63, WORD_LEN, 0}, // AWB_RIGHT_CCM_1 +{ 0xAC60, 0xFFD0, WORD_LEN, 0}, // AWB_RIGHT_CCM_2 +{ 0xAC62, 0xFFCD, WORD_LEN, 0}, // AWB_RIGHT_CCM_3 +{ 0xAC64, 0x013B, WORD_LEN, 0}, // AWB_RIGHT_CCM_4 +{ 0xAC66, 0xFFF8, WORD_LEN, 0}, // AWB_RIGHT_CCM_5 +{ 0xAC68, 0xFFFB, WORD_LEN, 0}, // AWB_RIGHT_CCM_6 +{ 0xAC6A, 0xFF78, WORD_LEN, 0}, // AWB_RIGHT_CCM_7 +{ 0xAC6C, 0x018D, WORD_LEN, 0}, // AWB_RIGHT_CCM_8 +{ 0xAC6E, 0x0055, WORD_LEN, 0}, // AWB_RIGHT_CCM_R2BRATIO + +//[AWB] +{ 0xB842, 0x0037, WORD_LEN, 0}, // STAT_AWB_GRAY_CHECKER_OFFSET_X +{ 0xB844, 0x0044, WORD_LEN, 0}, // STAT_AWB_GRAY_CHECKER_OFFSET_Y +{ 0x3240, 0x0024, WORD_LEN, 0}, // AWB_XY_SCALE +{ 0x3240, 0x0024, WORD_LEN, 0}, // AWB_XY_SCALE +{ 0x3242, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R0 +{ 0x3244, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R1 +{ 0x3246, 0x0000, WORD_LEN, 0}, // AWB_WEIGHT_R2 +{ 0x3248, 0x7F00, WORD_LEN, 0}, // AWB_WEIGHT_R3 +{ 0x324A, 0xA500, WORD_LEN, 0}, // AWB_WEIGHT_R4 +{ 0x324C, 0x1540, WORD_LEN, 0}, // AWB_WEIGHT_R5 +{ 0x324E, 0x01AC, WORD_LEN, 0}, // AWB_WEIGHT_R6 +{ 0x3250, 0x003E, WORD_LEN, 0}, // AWB_WEIGHT_R7 + +//[Preawb_params] +{ 0xACB0, 0x32, BYTE_LEN, 0}, // AWB_RG_MIN +{ 0xACB1, 0x5A, BYTE_LEN, 0}, // AWB_RG_MAX +{ 0xACB2, 0x32, BYTE_LEN, 0}, // AWB_RG_MIN_BRIGHT +{ 0xACB3, 0x5A, BYTE_LEN, 0}, // AWB_RG_MAX_BRIGHT +{ 0xACB4, 0x23, BYTE_LEN, 0}, // AWB_BG_MIN +{ 0xACB5, 0x55, BYTE_LEN, 0}, // AWB_BG_MAX +{ 0xACB6, 0x49, BYTE_LEN, 0}, // AWB_BG_MIN_BRIGHT +{ 0xACB7, 0x55, BYTE_LEN, 0}, // AWB_BG_MAX_BRIGHT + +//[**********Step7*************] +//[Step7-CPIPE_Calibration] + +//[jpeg_setup] + +{ 0xD80F, 0x04, BYTE_LEN, 0}, // JPEG_QSCALE_0 +{ 0xD810, 0x08, BYTE_LEN, 0}, // JPEG_QSCALE_1 +{ 0xC8D2, 0x04, BYTE_LEN, 0}, // CAM_OUTPUT_1_JPEG_QSCALE_0 +{ 0xC8D3, 0x08, BYTE_LEN, 0}, // CAM_OUTPUT_1_JPEG_QSCALE_1 +{ 0xC8BC, 0x04, BYTE_LEN, 0}, // CAM_OUTPUT_0_JPEG_QSCALE_0 +{ 0xC8BD, 0x08, BYTE_LEN, 0}, // CAM_OUTPUT_0_JPEG_QSCALE_1 + +//[Sys_Settings] +{ 0xDC35, 0x04, BYTE_LEN, 0}, // SYS_UV_COLOR_BOOST +{ 0x326E, 0x0006, WORD_LEN, 0}, // RESERVED_SOC1_326E +{ 0xDC37, 0x62, BYTE_LEN, 0}, // SYS_BRIGHT_COLORKILL +{ 0x35A4, 0x0596, WORD_LEN, 0}, // BRIGHT_COLOR_KILL_CONTROLS +{ 0x35A2, 0x0094, WORD_LEN, 0}, // DARK_COLOR_KILL_CONTROLS +{ 0xDC36, 0x23, BYTE_LEN, 0}, // SYS_DARK_COLOR_KILL + +//[Gamma_Curves_REV3] +{ 0xBC18, 0x00, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_0 +{ 0xBC19, 0x11, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_1 +{ 0xBC1A, 0x23, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_2 +{ 0xBC1B, 0x3F, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_3 +{ 0xBC1C, 0x67, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_4 +{ 0xBC1D, 0x85, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_5 +{ 0xBC1E, 0x9B, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_6 +{ 0xBC1F, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_7 +{ 0xBC20, 0xBB, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_8 +{ 0xBC21, 0xC7, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_9 +{ 0xBC22, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_10 +{ 0xBC23, 0xDA, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_11 +{ 0xBC24, 0xE1, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_12 +{ 0xBC25, 0xE8, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_13 +{ 0xBC26, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_14 +{ 0xBC27, 0xF3, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_15 +{ 0xBC28, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_16 +{ 0xBC29, 0xFB, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_17 +{ 0xBC2A, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_CONTRAST_CURVE_18 +{ 0xBC2B, 0x00, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_0 +{ 0xBC2C, 0x11, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_1 +{ 0xBC2D, 0x23, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_2 +{ 0xBC2E, 0x3F, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_3 +{ 0xBC2F, 0x67, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_4 +{ 0xBC30, 0x85, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_5 +{ 0xBC31, 0x9B, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_6 +{ 0xBC32, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_7 +{ 0xBC33, 0xBB, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_8 +{ 0xBC34, 0xC7, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_9 +{ 0xBC35, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_10 +{ 0xBC36, 0xDA, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_11 +{ 0xBC37, 0xE1, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_12 +{ 0xBC38, 0xE8, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_13 +{ 0xBC39, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_14 +{ 0xBC3A, 0xF3, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_15 +{ 0xBC3B, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_16 +{ 0xBC3C, 0xFB, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_17 +{ 0xBC3D, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_NEUTRAL_CURVE_18 +{ 0xBC3E, 0x00, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_0 +{ 0xBC3F, 0x05, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_1 +{ 0xBC40, 0x0F, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_2 +{ 0xBC41, 0x21, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_3 +{ 0xBC42, 0x3C, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_4 +{ 0xBC43, 0x52, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_5 +{ 0xBC44, 0x67, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_6 +{ 0xBC45, 0x7B, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_7 +{ 0xBC46, 0x8D, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_8 +{ 0xBC47, 0x9E, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_9 +{ 0xBC48, 0xAD, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_10 +{ 0xBC49, 0xBA, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_11 +{ 0xBC4A, 0xC6, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_12 +{ 0xBC4B, 0xD1, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_13 +{ 0xBC4C, 0xDC, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_14 +{ 0xBC4D, 0xE5, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_15 +{ 0xBC4E, 0xEE, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_16 +{ 0xBC4F, 0xF7, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_17 +{ 0xBC50, 0xFF, BYTE_LEN, 0}, // LL_GAMMA_NR_CURVE_18 + +//[BM_Dampening] +{ 0xB801, 0xE0, BYTE_LEN, 0}, // STAT_MODE +{ 0xB862, 0x04, BYTE_LEN, 0}, // STAT_BMTRACKING_SPEED + +//[AE] +{ 0xB829, 0x02, BYTE_LEN, 0}, // STAT_LL_BRIGHTNESS_METRIC_DIVISOR +{ 0xB863, 0x02, BYTE_LEN, 0}, // STAT_BM_MUL +{ 0xB827, 0x0F, BYTE_LEN, 0}, // STAT_AE_EV_SHIFT +{ 0xA409, 0x42, BYTE_LEN, 0}, // AE_RULE_BASE_TARGET + +//[BM_GM_Start_Stop] +{ 0xBC52, 0x00C8, WORD_LEN, 0}, // LL_START_BRIGHTNESS_METRIC +{ 0xBC54, 0x0A28, WORD_LEN, 0}, // LL_END_BRIGHTNESS_METRIC +{ 0xBC58, 0x00C8, WORD_LEN, 0}, // LL_START_GAIN_METRIC +{ 0xBC5A, 0x12C0, WORD_LEN, 0}, // LL_END_GAIN_METRIC +{ 0xBC5E, 0x00FA, WORD_LEN, 0}, // LL_START_APERTURE_GAIN_BM +{ 0xBC60, 0x0258, WORD_LEN, 0}, // LL_END_APERTURE_GAIN_BM +{ 0xBC66, 0x00FA, WORD_LEN, 0}, // LL_START_APERTURE_GM +{ 0xBC68, 0x0258, WORD_LEN, 0}, // LL_END_APERTURE_GM +{ 0xBC86, 0x00C8, WORD_LEN, 0}, // LL_START_FFNR_GM +{ 0xBC88, 0x0640, WORD_LEN, 0}, // LL_END_FFNR_GM +{ 0xBCBC, 0x0040, WORD_LEN, 0}, // LL_SFFB_START_GAIN +{ 0xBCBE, 0x01FC, WORD_LEN, 0}, // LL_SFFB_END_GAIN +{ 0xBCCC, 0x00C8, WORD_LEN, 0}, // LL_SFFB_START_MAX_GM +{ 0xBCCE, 0x0640, WORD_LEN, 0}, // LL_SFFB_END_MAX_GM +{ 0xBC90, 0x00C8, WORD_LEN, 0}, // LL_START_GRB_GM +{ 0xBC92, 0x0640, WORD_LEN, 0}, // LL_END_GRB_GM +{ 0xBC0E, 0x0001, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_START_POS +{ 0xBC10, 0x0002, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_MID_POS +{ 0xBC12, 0x02BC, WORD_LEN, 0}, // LL_GAMMA_CURVE_ADJ_END_POS +{ 0xBCAA, 0x044C, WORD_LEN, 0}, // LL_CDC_THR_ADJ_START_POS +{ 0xBCAC, 0x00AF, WORD_LEN, 0}, // LL_CDC_THR_ADJ_MID_POS +{ 0xBCAE, 0x0009, WORD_LEN, 0}, // LL_CDC_THR_ADJ_END_POS +{ 0xBCD8, 0x00C8, WORD_LEN, 0}, // LL_PCR_START_BM +{ 0xBCDA, 0x0A28, WORD_LEN, 0}, // LL_PCR_END_BM + +//[Kernel] +{ 0x3380, 0x0504, WORD_LEN, 0}, // KERNEL_CONFIG + +//[GRB] +{ 0xBC94, 0x0C, BYTE_LEN, 0}, // LL_GB_START_THRESHOLD_0 +{ 0xBC95, 0x08, BYTE_LEN, 0}, // LL_GB_START_THRESHOLD_1 +{ 0xBC9C, 0x3C, BYTE_LEN, 0}, // RESERVED_LL_9C +{ 0xBC9D, 0x28, BYTE_LEN, 0}, // RESERVED_LL_9D + +//[Demosaic_REV3] +{ 0x33B0, 0x2A16, WORD_LEN, 0}, // FFNR_ALPHA_BETA +{ 0xBC8A, 0x02, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_Y +{ 0xBC8B, 0x0F, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_Y +{ 0xBC8C, 0xFF, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_YGAIN +{ 0xBC8D, 0xFF, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_YGAIN +{ 0xBC8E, 0xFF, BYTE_LEN, 0}, // LL_START_FF_MIX_THRESH_GAIN +{ 0xBC8F, 0x00, BYTE_LEN, 0}, // LL_END_FF_MIX_THRESH_GAIN + +//[CDC] +{ 0xBCB2, 0x20, BYTE_LEN, 0}, // LL_CDC_DARK_CLUS_SLOPE +{ 0xBCB3, 0x3A, BYTE_LEN, 0}, // LL_CDC_DARK_CLUS_SATUR +{ 0xBCB4, 0x39, BYTE_LEN, 0}, // RESERVED_LL_B4 +{ 0xBCB7, 0x39, BYTE_LEN, 0}, // RESERVED_LL_B7 +{ 0xBCB5, 0x20, BYTE_LEN, 0}, // RESERVED_LL_B5 +{ 0xBCB8, 0x3A, BYTE_LEN, 0}, // RESERVED_LL_B8 +{ 0xBCB6, 0x80, BYTE_LEN, 0}, // RESERVED_LL_B6 +{ 0xBCB9, 0x24, BYTE_LEN, 0}, // RESERVED_LL_B9 +{ 0xBCAA, 0x03E8, WORD_LEN, 0}, // LL_CDC_THR_ADJ_START_POS +{ 0xBCAC, 0x012C, WORD_LEN, 0}, // LL_CDC_THR_ADJ_MID_POS +{ 0xBCAE, 0x0009, WORD_LEN, 0}, // LL_CDC_THR_ADJ_END_POS + +//[Aperture_calib] +{ 0x33BA, 0x0084, WORD_LEN, 0}, // APEDGE_CONTROL +{ 0x33BE, 0x0000, WORD_LEN, 0}, // UA_KNEE_L +{ 0x33C2, 0x8800, WORD_LEN, 0}, // UA_WEIGHTS +{ 0xBC5E, 0x0154, WORD_LEN, 0}, // LL_START_APERTURE_GAIN_BM +{ 0xBC60, 0x0640, WORD_LEN, 0}, // LL_END_APERTURE_GAIN_BM +{ 0xBC62, 0x0E, BYTE_LEN, 0}, // LL_START_APERTURE_KPGAIN +{ 0xBC63, 0x14, BYTE_LEN, 0}, // LL_END_APERTURE_KPGAIN +{ 0xBC64, 0x0E, BYTE_LEN, 0}, // LL_START_APERTURE_KNGAIN +{ 0xBC65, 0x14, BYTE_LEN, 0}, // LL_END_APERTURE_KNGAIN +{ 0xBCE2, 0x0A, BYTE_LEN, 0}, // LL_START_POS_KNEE +{ 0xBCE3, 0x2B, BYTE_LEN, 0}, // LL_END_POS_KNEE +{ 0xBCE4, 0x0A, BYTE_LEN, 0}, // LL_START_NEG_KNEE +{ 0xBCE5, 0x2B, BYTE_LEN, 0}, // LL_END_NEG_KNEE +{ 0x3210, 0x49B8, WORD_LEN, 0}, // COLOR_PIPELINE_CONTROL + +//[SFFB_REV3_noisemodel] +{ 0xBCC0, 0x1F, BYTE_LEN, 0}, // LL_SFFB_RAMP_START +{ 0xBCC1, 0x03, BYTE_LEN, 0}, // LL_SFFB_RAMP_STOP +{ 0xBCC2, 0x2C, BYTE_LEN, 0}, // LL_SFFB_SLOPE_START +{ 0xBCC3, 0x10, BYTE_LEN, 0}, // LL_SFFB_SLOPE_STOP +{ 0xBCC4, 0x07, BYTE_LEN, 0}, // LL_SFFB_THSTART +{ 0xBCC5, 0x0B, BYTE_LEN, 0}, // LL_SFFB_THSTOP +{ 0xBCBA, 0x0009, WORD_LEN, 0}, // LL_SFFB_CONFIG + +//[**********Step8*************] +//[FTB_Off] +{ 0xBC14, 0xFFFE, WORD_LEN, 0}, // LL_GAMMA_FADE_TO_BLACK_START_POS +{ 0xBC16, 0xFFFE, WORD_LEN, 0}, // LL_GAMMA_FADE_TO_BLACK_END_POS + +//[Aperture_preference] +{ 0xBC66, 0x0154, WORD_LEN, 0}, // LL_START_APERTURE_GM +{ 0xBC68, 0x07D0, WORD_LEN, 0}, // LL_END_APERTURE_GM +{ 0xBC6A, 0x04, BYTE_LEN, 0}, // LL_START_APERTURE_INTEGER_GAIN +{ 0xBC6B, 0x00, BYTE_LEN, 0}, // LL_END_APERTURE_INTEGER_GAIN +{ 0xBC6C, 0x00, BYTE_LEN, 0}, // LL_START_APERTURE_EXP_GAIN +{ 0xBC6D, 0x00, BYTE_LEN, 0}, // LL_END_APERTURE_EXP_GAIN + +//[Gain_max] +{ 0xA81C, 0x0040, WORD_LEN, 0}, // AE_TRACK_MIN_AGAIN +{ 0xA820, 0x012C, WORD_LEN, 0}, // AE_TRACK_MAX_AGAIN +{ 0xA822, 0x0060, WORD_LEN, 0}, // AE_TRACK_MIN_DGAIN +{ 0xA824, 0x00E5, WORD_LEN, 0}, // AE_TRACK_MAX_DGAIN + +//[Saturation_REV3] +{ 0xBC56, 0x64, BYTE_LEN, 0}, // LL_START_CCM_SATURATION +{ 0xBC57, 0x1E, BYTE_LEN, 0}, // LL_END_CCM_SATURATION + +//[DCCM_REV3] +{ 0xBCDE, 0x03, BYTE_LEN, 0}, // LL_START_SYS_THRESHOLD +{ 0xBCDF, 0x50, BYTE_LEN, 0}, // LL_STOP_SYS_THRESHOLD +{ 0xBCE0, 0x08, BYTE_LEN, 0}, // LL_START_SYS_GAIN +{ 0xBCE1, 0x03, BYTE_LEN, 0}, // LL_STOP_SYS_GAIN + +//[Sobel_REV3] +{ 0xBCD0, 0x000A, WORD_LEN, 0}, // LL_SFFB_SOBEL_FLAT_START +{ 0xBCD2, 0x00FE, WORD_LEN, 0}, // LL_SFFB_SOBEL_FLAT_STOP +{ 0xBCD4, 0x001E, WORD_LEN, 0}, // LL_SFFB_SOBEL_SHARP_START +{ 0xBCD6, 0x00FF, WORD_LEN, 0}, // LL_SFFB_SOBEL_SHARP_STOP +{ 0xBCC6, 0x00, BYTE_LEN, 0}, // LL_SFFB_SHARPENING_START +{ 0xBCC7, 0x00, BYTE_LEN, 0}, // LL_SFFB_SHARPENING_STOP +{ 0xBCC8, 0x20, BYTE_LEN, 0}, // LL_SFFB_FLATNESS_START +{ 0xBCC9, 0x40, BYTE_LEN, 0}, // LL_SFFB_FLATNESS_STOP +{ 0xBCCA, 0x04, BYTE_LEN, 0}, // LL_SFFB_TRANSITION_START +{ 0xBCCB, 0x00, BYTE_LEN, 0}, // LL_SFFB_TRANSITION_STOP + +//[SFFB_slope_zero_enable] +{ 0xBCE6, 0x03, BYTE_LEN, 0}, // LL_SFFB_ZERO_ENABLE +{ 0xBCE6, 0x03, BYTE_LEN, 0}, // LL_SFFB_ZERO_ENABLE + + +//[AE_preference] +{ 0xA410, 0x04, BYTE_LEN, 0}, // AE_RULE_TARGET_AE_6 +{ 0xA411, 0x06, BYTE_LEN, 0}, // AE_RULE_TARGET_AE_7 + + +//[**********Step9*************] +//[JPEG Quantization] +//[Sepia effect] +{ 0xDC3A, 0x23, BYTE_LEN, 0}, // SYS_SEPIA_CR +{ 0xDC3B, 0xB2, BYTE_LEN, 0}, // SYS_SEPIA_CB + + +//[Touch Focus + Fast Focus AF_AFM_INIT] +{ 0x8411, 0x00, BYTE_LEN, 0}, // SEQ_STATE_CFG_0_AF +{ 0x8419, 0x04, BYTE_LEN, 0}, // SEQ_STATE_CFG_1_AF + +{ 0xB002, 0x0002, WORD_LEN, 0}, // AF_MODE +{ 0xC40A, 0x0030, WORD_LEN, 0}, // AFM_POS_MIN +{ 0xC40C, 0x00A0, WORD_LEN, 0}, // AFM_POS_MAX +{ 0xB045, 0x000C, WORD_LEN, 0}, // AF_MODE_EX + + +//AF Window size +{ 0xB854, 0x60, BYTE_LEN, 0}, // STAT_SM_WINDOW_POS_X +{ 0xB855, 0x60, BYTE_LEN, 0}, // STAT_SM_WINDOW_POS_Y +{ 0xB856, 0x40, BYTE_LEN, 0}, // STAT_SM_WINDOW_SIZE_X +{ 0xB857, 0x40, BYTE_LEN, 0}, // STAT_SM_WINDOW_SIZE_Y +{ 0xB012, 0x0A, BYTE_LEN, 0}, // AF_FS_NUM_STEPS +{ 0xB018, 0x00, BYTE_LEN, 0}, // AF_FS_POS_0 +{ 0xB019, 0x30, BYTE_LEN, 0}, // AF_FS_POS_1 +{ 0xB01A, 0x48, BYTE_LEN, 0}, // AF_FS_POS_2 +{ 0xB01B, 0x60, BYTE_LEN, 0}, // AF_FS_POS_3 +{ 0xB01C, 0x78, BYTE_LEN, 0}, // AF_FS_POS_4 +{ 0xB01D, 0x90, BYTE_LEN, 0}, // AF_FS_POS_5 +{ 0xB01E, 0xA8, BYTE_LEN, 0}, // AF_FS_POS_6 +{ 0xB01F, 0xC0, BYTE_LEN, 0}, // AF_FS_POS_7 +{ 0xB020, 0xE0, BYTE_LEN, 0}, // AF_FS_POS_8 +{ 0xB021, 0xFF, BYTE_LEN, 0}, // AF_FS_POS_9 +{ 0xB022, 0x00, BYTE_LEN, 0}, // AF_FS_POS_10 +{ 0xB011, 0x00, BYTE_LEN, 0}, // AF_FS_INIT_POS + +//INIT PATCH PAGE used in FF +{ 0x098E, 0xD40E, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS +{ 0xD40E, 0x0000, WORD_LEN, 0}, +{ 0xD40F, 0x0000, WORD_LEN, 0}, +{ 0xD410, 0x0000, WORD_LEN, 0}, +{ 0xD411, 0x0000, WORD_LEN, 0}, +{ 0xD412, 0x0000, WORD_LEN, 0}, +{ 0xD413, 0x0000, WORD_LEN, 0}, +{ 0xD414, 0x0000, WORD_LEN, 0}, +{ 0xD415, 0x0000, WORD_LEN, 0}, +{ 0xD416, 0x0000, WORD_LEN, 0}, +{ 0xD417, 0x0000, WORD_LEN, 0}, +{ 0xD418, 0x0000, WORD_LEN, 0}, +{ 0xD418, 0x0000, WORD_LEN, 0}, +{ 0xD419, 0x0000, WORD_LEN, 0}, +{ 0xD41A, 0x0000, WORD_LEN, 0}, +{ 0xD41B, 0x0000, WORD_LEN, 0}, +{ 0xD41C, 0x0000, WORD_LEN, 0}, +{ 0xD41D, 0x0000, WORD_LEN, 0}, +{ 0xD41E, 0x0000, WORD_LEN, 0}, +{ 0xD420, 0x0000, WORD_LEN, 0}, +{ 0xD406, 0x0000, WORD_LEN, 0}, +{ 0xD407, 0x0000, WORD_LEN, 0}, +{ 0xD422, 0x0000, WORD_LEN, 0}, +{ 0xD423, 0x0000, WORD_LEN, 0}, +{ 0xD424, 0x0000, WORD_LEN, 0}, +{ 0xD425, 0x0000, WORD_LEN, 0}, +{ 0xD426, 0x0000, WORD_LEN, 0}, +{ 0xD427, 0x0000, WORD_LEN, 0}, +{ 0xD428, 0x0000, WORD_LEN, 0}, +{ 0xD429, 0x0000, WORD_LEN, 0}, +{ 0xD42A, 0x0000, WORD_LEN, 0}, +{ 0xD42B, 0x0000, WORD_LEN, 0}, +{ 0xD400, 0x0001, WORD_LEN, 0}, +{ 0xD401, 0x0000, WORD_LEN, 0}, +{ 0xD402, 0x0028, WORD_LEN, 0}, +{ 0xD403, 0x0080, WORD_LEN, 0}, +{ 0xD404, 0x0000, WORD_LEN, 0}, +{ 0xD405, 0x0000, WORD_LEN, 0}, +{ 0xD406, 0x0000, WORD_LEN, 0}, +{ 0xD407, 0x0000, WORD_LEN, 0}, +{ 0xD408, 0x0030, WORD_LEN, 0}, +{ 0xD409, 0x0040, WORD_LEN, 0}, +{ 0xD40A, 0x0050, WORD_LEN, 0}, +{ 0xD40B, 0x0070, WORD_LEN, 0}, +{ 0xD40C, 0x0080, WORD_LEN, 0}, +{ 0xD40D, 0x0090, WORD_LEN, 0}, + +{ 0x0018, 0x2008, WORD_LEN, 0}, // STANDBY_CONTROL_AND_STATUS + +{SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, + + { SEQUENCE_END, 0x00, 0, 0} + + + +}; + +/* 720p 15fps @ 1280x720 */ +static struct reginfo sensor_720p[]= +{ + //{SEQUENCE_END, 0x00}, + {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [CAM_CORE_A_Y_ADDR_START] + {0x843C, 0x01, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x01, BYTE_LEN, 0 }, // SEQ_CMD + {0x0016, 0x0447, WORD_LEN, 0}, // CLOCKS_CONTROL + {0xC83A, 0x0106, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_START + {0xC83C, 0x0018, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_START + {0xC83E, 0x06B7, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_END + {0xC840, 0x0A45, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_END + {0xC86C, 0x0518, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH + {0xC86E, 0x02D8, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT + {0xC870, 0x0014, WORD_LEN, 0}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK + {0xC858, 0x0003, WORD_LEN, 0}, // CAM_CORE_A_COARSE_ITMIN + {0xC8B8, 0x0004, WORD_LEN, 0}, // CAM_OUTPUT_0_JPEG_CONTROL +/****bug:part pixsels data not to be aquired *****/ +#if ADJUST_FOR_720P_FALG + {0xC8AA, 0x0500, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_WIDTH + {0xC8AC, 0x02D1, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_HEIGHT +#else + {0xC8AA, 0x0500, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_WIDTH + {0xC8AC, 0x02D0, WORD_LEN, 0}, // CAM_OUTPUT_0_IMAGE_HEIGHT +#endif + {0xC8AE, 0x0001, WORD_LEN, 0}, // CAM_OUTPUT_0_OUTPUT_FORMAT + {0x8404, 0x06, BYTE_LEN, 0 }, // SEQ_CMD + + {SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, + + { SEQUENCE_END, 0x00, 0, 0} +}; + +/* 1080p, 0x15fps, 0xyuv @1920x1080 */ +static struct reginfo sensor_1080p[]= +{ +{ SEQUENCE_END, 0x00, 0, 0} +}; + +/* 2592X1944 QSXGA */ +#if ADJUST_FOR_CAPTURE_FALG +static struct reginfo sensor_qsxga[] = +{ + + {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] + {0xC8C0, 0x0A20,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH + {0xC8C2, 0x0798,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT + {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD + {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, + + {SEQUENCE_END, 0x00, 0, 0} +}; +#else +static struct reginfo sensor_qsxga[] = +{ + {SEQUENCE_PROPERTY,SEQUENCE_CAPTURE}, + { SEQUENCE_END, 0x00, 0, 0} +}; +#endif + +/* 2048*1536 QXGA */ +#if ADJUST_FOR_CAPTURE_FALG +// send extra two lines to forbid to be captured error +static struct reginfo sensor_qxga[] = +{ + {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] + {0xC8C0, 0x0800,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH + {0xC8C2, 0x0602,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT + {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD + {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, + + {SEQUENCE_END, 0x00, 0, 0} +}; +#else +static struct reginfo sensor_qxga[] = +{ +{ SEQUENCE_END, 0x00, 0, 0} +}; +#endif + +/* 1600X1200 UXGA */ +#if ADJUST_FOR_CAPTURE_FALG +static struct reginfo sensor_uxga[] = +{ + {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] + {0xC8C0, 0x0640,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH + {0xC8C2, 0x04b2,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT + {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD + {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, + + {SEQUENCE_END, 0x00, 0, 0} +}; +#else +static struct reginfo sensor_uxga[] = +{ + { SEQUENCE_END, 0x00, 0, 0} +}; +#endif + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {SEQUENCE_END, 0x00} +}; + +/* 1024X768 XGA */ +#if ADJUST_FOR_CAPTURE_FALG +static struct reginfo sensor_xga[] = +{ + {0x098E, 0x48C0,WORD_LEN,0}, // LOGICAL_ADDRESS_ACCESS [CAM_OUTPUT_1_IMAGE_WIDTH] + {0xC8C0, 0x0403,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_WIDTH + {0xC8C2, 0x0302,WORD_LEN,0}, // CAM_OUTPUT_1_IMAGE_HEIGHT + {0x8404, 0x06 ,BYTE_LEN,0}, // SEQ_CMD + {SEQUENCE_WAIT_MS,100,WORD_LEN,0}, + + {SEQUENCE_END, 0x00, 0, 0} +}; +#else +static struct reginfo sensor_xga[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +#endif + + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + { SEQUENCE_END, 0x00, 0, 0} +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + //720p2vga + {0xC83A, 0x000C, WORD_LEN, 0}, // CAM_CORE_A_Y_ADDR_START + {0xC83C, 0x0018, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_START + {0xC83E, 0x07B1, WORD_LEN, 0 }, // CAM_CORE_A_Y_ADDR_END + {0xC840, 0x0A45, WORD_LEN, 0}, // CAM_CORE_A_X_ADDR_END + {0xC868, 0x0423, WORD_LEN, 0}, // CAM_CORE_A_FRAME_LENGTH_LINES + {0xC86A, 0x1194, WORD_LEN, 0}, // CAM_CORE_A_LINE_LENGTH_PCK + {0xC86C, 0x0518, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_WIDTH + {0xC86E, 0x03D4, WORD_LEN, 0}, // CAM_CORE_A_OUTPUT_SIZE_HEIGHT + {0xC870, 0x0014, WORD_LEN, 0}, // CAM_CORE_A_RX_FIFO_TRIGGER_MARK + {0xC858, 0x0003, WORD_LEN, 0}, // CAM_CORE_A_COARSE_ITMIN + {0xC8A4, 0x0A28, WORD_LEN, 0}, // CAM_CORE_B_OUTPUT_SIZE_WIDTH + {0xC8A6, 0x07A0, WORD_LEN, 0 }, // CAM_CORE_B_OUTPUT_SIZE_HEIGHT + {0xC8AA, 0x0280, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_WIDTH + {0xC8AC, 0x01E0, WORD_LEN, 0 }, // CAM_OUTPUT_0_IMAGE_HEIGHT + {0xC8AE, 0x0001, WORD_LEN, 0 }, // CAM_OUTPUT_0_OUTPUT_FORMAT + {0x8404, 0x06, BYTE_LEN, 0 }, // SEQ_CMD + {SEQUENCE_WAIT_MS,100, WORD_LEN, 0}, + {SEQUENCE_END, 0x00, 0, 0} + +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {SEQUENCE_END, 0x00} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + {SEQUENCE_END, 0x00} +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + {SEQUENCE_END, 0x00} +}; +#endif +static struct reginfo sensor_Preview2Capture[]= +{ + //capture2preview + {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] + {0x843C, 0xFF, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x02, BYTE_LEN, 0 }, // SEQ_CMD + {SEQUENCE_END, 0x00, 0, 0} + +}; + +static struct reginfo sensor_Capture2Preview[]= +{ + //snap2preview + {0x098E, 0x843C, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [SEQ_STATE_CFG_5_MAX_FRAME_CNT] + {0x843C, 0x01, BYTE_LEN, 0 }, // SEQ_STATE_CFG_5_MAX_FRAME_CNT + {0x8404, 0x01, BYTE_LEN, 0 }, // SEQ_CMD + {0x0016, 0x0447, WORD_LEN, 0}, // CLOCKS_CONTRO + {SEQUENCE_END, 0x00, 0, 0} + +}; +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {SEQUENCE_END, 0x00} +}; + + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + //Auto + {0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] + {0xACB0, 0x31, BYTE_LEN, 0 }, // AWB_RG_MIN + {0xACB1, 0x5B, BYTE_LEN, 0 }, // AWB_RG_MAX + {0xACB4, 0x2A, BYTE_LEN, 0 }, // AWB_BG_MIN + {0xACB5, 0x5B, BYTE_LEN, 0 }, // AWB_BG_MAX + {0xACB2, 0x40, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT + {0xACB3, 0x48, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT + {0xACB6, 0x3f, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT + {0xACB7, 0x48, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT + {0xAC44, 0x00, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT + {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT + {SEQUENCE_END, 0x00, 0, 0} + +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + //[V. DL 7500] + { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] + {0xACB0, 0x38, BYTE_LEN, 0 }, // AWB_RG_MIN + {0xACB1, 0x42, BYTE_LEN, 0 }, // AWB_RG_MAX + {0xACB4, 0x44, BYTE_LEN, 0 }, // AWB_BG_MIN + {0xACB5, 0x4C, BYTE_LEN, 0 }, // AWB_BG_MAX + {0xACB2, 0x38, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT + {0xACB3, 0x42, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT + {0xACB6, 0x44, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT + {0xACB7, 0x4C, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT + {0xAC44, 0x7C, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT + {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT + {0xAC04, 0x3E, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO + {0xAC05, 0x48, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO + {0xAC08, 0x7F, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS + {SEQUENCE_END, 0x00, 0, 0} + +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //[IV Day Light] + { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] + {0xACB0, 0x3A, BYTE_LEN, 0 }, // AWB_RG_MIN + {0xACB1, 0x44, BYTE_LEN, 0 }, // AWB_RG_MAX + {0xACB4, 0x40, BYTE_LEN, 0 }, // AWB_BG_MIN + {0xACB5, 0x4A, BYTE_LEN, 0 }, // AWB_BG_MAX + {0xACB2, 0x3A, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT + {0xACB3, 0x44, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT + {0xACB6, 0x40, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT + {0xACB7, 0x4A, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT + {0xAC44, 0x7C, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT + {0xAC45, 0x7F, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT + {0xAC04, 0x40, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO + {0xAC05, 0x48, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO + {0xAC08, 0x7F, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS + {SEQUENCE_END, 0x00, 0, 0} + +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //[III Fluorescent] + { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] + {0xACB0, 0x44, BYTE_LEN, 0 }, // AWB_RG_MIN + {0xACB1, 0x4B, BYTE_LEN, 0 }, // AWB_RG_MAX + {0xACB4, 0x2C, BYTE_LEN, 0 }, // AWB_BG_MIN + {0xACB5, 0x34, BYTE_LEN, 0 }, // AWB_BG_MAX + {0xACB2, 0x44, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT + {0xACB3, 0x4B, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT + {0xACB6, 0x2C, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT + {0xACB7, 0x34, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT + {0xAC44, 0x40, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT + {0xAC45, 0x4A, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT + {0xAC04, 0x47, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO + {0xAC05, 0x30, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO + {0xAC08, 0x45, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS + {SEQUENCE_END, 0x00, 0, 0} +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //[II. Incandescent] + { 0x098E, 0xACB0, WORD_LEN, 0}, // LOGICAL_ADDRESS_ACCESS [AWB_MIN_ACCEPTED_PRE_AWB_R2G_RATIO] + {0xACB0, 0x57, BYTE_LEN, 0 }, // AWB_RG_MIN + {0xACB1, 0x5F, BYTE_LEN, 0 }, // AWB_RG_MAX + {0xACB4, 0x26, BYTE_LEN, 0 }, // AWB_BG_MIN + {0xACB5, 0x2E, BYTE_LEN, 0 }, // AWB_BG_MAX + {0xACB2, 0x57, BYTE_LEN, 0 }, // AWB_RG_MIN_BRIGHT + {0xACB3, 0x5F, BYTE_LEN, 0 }, // AWB_RG_MAX_BRIGHT + {0xACB6, 0x26, BYTE_LEN, 0 }, // AWB_BG_MIN_BRIGHT + {0xACB7, 0x2E, BYTE_LEN, 0 }, // AWB_BG_MAX_BRIGHT + {0xAC44, 0x00, BYTE_LEN, 0 }, // AWB_LEFT_CCM_POS_RANGE_LIMIT + {0xAC45, 0x08, BYTE_LEN, 0 }, // AWB_RIGHT_CCM_POS_RANGE_LIMIT + {0xAC04, 0x5B, BYTE_LEN, 0 }, // AWB_PRE_AWB_R2G_RATIO + {0xAC05, 0x2A, BYTE_LEN, 0 }, // AWB_PRE_AWB_B2G_RATIO + {0xAC08, 0x00, BYTE_LEN, 0 }, // AWB_CUR_CCM_POS + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x098e,0xdc38, WORD_LEN, 0}, + {0xdc38,0x00, BYTE_LEN, 0 }, + {0x8404,0x06, BYTE_LEN, 0 }, + {SEQUENCE_END, 0x00, 0, 0} +}; +#if 0 +static struct reginfo sensor_Effect_WandB[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +#endif +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x098e,0xdc38, WORD_LEN, 0}, + {0xdc38,0x02, BYTE_LEN, 0 }, + {0xdc3a,0x10, BYTE_LEN, 0 }, + {0xdc3b,0xe0, BYTE_LEN, 0 }, + {0x8404,0x06, BYTE_LEN, 0 }, + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + {0x098e,0xdc38, WORD_LEN, 0}, + {0xdc38,0x03, BYTE_LEN, 0 }, + {0x8404,0x06, BYTE_LEN, 0 }, + {SEQUENCE_END, 0x00, 0, 0} +}; +#if 0 +static struct reginfo sensor_Effect_Bluish[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +#endif +static struct reginfo sensor_Effect_Solarize[] = +{ + {0x098e,0xdc38, WORD_LEN, 0}, + {0xdc38,0x05, BYTE_LEN, 0 }, + {0xdc39,0x20, BYTE_LEN, 0 }, + {0x8404,0x06, BYTE_LEN, 0 }, + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Solarize,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + {SEQUENCE_END, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif + +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_SceneNight[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif + +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_Zoom1[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + +static struct reginfo sensor_Zoom2[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {SEQUENCE_END, 0x00, 0, 0} +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "negative", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "sepia", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "solarize", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + { + .id = V4L2_CID_FOCUSZONE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "FocusZone Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + },{ + .id = V4L2_CID_FOCUS_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Focus Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + },/*{ + .id = V4L2_CID_FOCUS_CONTINUOUS, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Focus Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + },*/ + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 2, + //.maximum = 3 + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +enum sensor_wq_cmd +{ + WqCmd_af_init, + WqCmd_af_single, + WqCmd_af_special_pos, + WqCmd_af_far_pos, + WqCmd_af_near_pos, + WqCmd_af_continues, + WqCmd_af_return_idle, +}; +enum sensor_wq_result +{ + WqRet_success = 0, + WqRet_fail = -1, + WqRet_inval = -2 +}; +struct sensor_work +{ + struct i2c_client *client; + struct delayed_work dwork; + enum sensor_wq_cmd cmd; + wait_queue_head_t done; + enum sensor_wq_result result; + bool wait; + int var; + int zone_center_pos[2]; +}; +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int auto_focus; + int affm_reinit; + int flash; + int exposure; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + bool snap2preview; + bool video2preview; + int capture_w; + int capture_h; + int preview_w; + int preview_h; + struct reginfo *winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int enable; + unsigned int funmodule_state; +} sensor_info_priv_t; + + + +struct sensor_parameter +{ + unsigned short int preview_maxlines; + unsigned short int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int capture_framerate; + unsigned short int preview_framerate; +}; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + struct sensor_parameter parameter; + struct workqueue_struct *sensor_wq; + struct sensor_work sensor_wk; + struct mutex wq_lock; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif +} +/*sensor register write */ +static int sensor_write(struct i2c_client *client, struct reginfo *reg_info) +{ + int err=0,cnt; + u8 buf[4]; + struct i2c_msg msg[1]; + + switch (reg_info->reg) + { + case SEQUENCE_WAIT_MS: + { + if (in_atomic()) + mdelay(reg_info->val); + else + msleep(reg_info->val); + break; + } + + case SEQUENCE_WAIT_US: + { + udelay(reg_info->val); + break; + } + case SEQUENCE_PROPERTY: + { + break; + } + default: + { + buf[0] = reg_info->reg >> 8; + buf[1] = reg_info->reg & 0xFF; + if (reg_info->reg_len == WORD_LEN) { + buf[2] = reg_info->val >> 8; + buf[3] = reg_info->val & 0xFF; + msg->len = 4; + } else if (reg_info->reg_len == BYTE_LEN) { + buf[2] = reg_info->val; + msg->len = 3; + } + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); + udelay(10); + } + } + } + } + return err; +} + +/** + *sensor_write_Multiple_data - sensor register write with Multiple data + * @i2c_client: + * @reg_info: the first register address + * @count: data number + * + * Returns negative errno, else the number of messages executed. + * + * Note that it + */ +static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo *reg_info, int count) +{ + int err=0,cnt; + int i=0; + int sum =0; + struct reginfo *tmpval = NULL; + u8 *buf; + struct i2c_msg msg[1]; + tmpval = reg_info; + + if(count < 1 || tmpval==NULL||tmpval->reg==0x0000) + return -EINVAL; + + memset((char*)&msg[0],0,sizeof(struct i2c_msg)); + buf = kmalloc((count*2+10)*sizeof(u8),GFP_KERNEL); + if (buf == NULL) { + SENSOR_TR("%s %s fail,because kmalloc failed",SENSOR_NAME_STRING(),__FUNCTION__); + err = -1; + goto sensor_write_Multiple_data_end; + } + memset(buf,0,sizeof(buf)); + + switch (reg_info->reg) + { + case SEQUENCE_WAIT_MS: + { + if (in_atomic()) + mdelay(reg_info->val); + else + msleep(reg_info->val); + break; + } + + case SEQUENCE_WAIT_US: + { + udelay(reg_info->val); + break; + } + + case SEQUENCE_PROPERTY: + { + break; + } + default: + { + + buf[0] = tmpval->reg >> 8; + buf[1] = tmpval->reg & 0xFF; + i= 2; + if (tmpval->reg_len == WORD_LEN) + { + sum = (count+1)*2; + while(ival >> 8; + buf[i+1] = tmpval->val & 0xFF; + i=i+2; + tmpval++; + } + msg->len = sum; + } else if (tmpval->reg_len == BYTE_LEN) { + sum = count+2; + while(ival; + i++; + tmpval++; + } + msg->len = sum; + } + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); + udelay(10); + } + } + } + } +sensor_write_Multiple_data_end: + if (buf) { + kfree(buf); + buf = NULL; + } + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u16 reg, u16 *val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[2]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 2; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +static int sensor_read1(struct i2c_client *client, struct reginfo *reg_info) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[2]; + + buf[0] = reg_info->reg >> 8; + buf[1] = reg_info->reg & 0xFF; + + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + if (reg_info->reg_len == WORD_LEN) { + msg[1].len = 2; + } else if (reg_info->reg_len == BYTE_LEN) { + msg[1].len = 1; + } + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + if (reg_info->reg_len == WORD_LEN) { + reg_info->val = buf[0]; + reg_info->val <<= 8; + reg_info->val |= buf[1]; + } else if (reg_info->reg_len == BYTE_LEN) { + reg_info->val = buf[0]; + } + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg_info->reg, reg_info->val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0,j=0; + int num = 0; + u16 temp = 0; + +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + cnt = 0; + + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + // SENSOR_TR("%s ..%s..\n",SENSOR_NAME_STRING(),__FUNCTION__); + + while (regarray[i].reg != SEQUENCE_END) { + num =1; + j= i+1; + #if 0 + while((regarray[j].reg_len ==regarray[i].reg_len)&®array[j].reg != SEQUENCE_END) + { + temp = regarray[j].reg - regarray[j-1].reg; + if((regarray[j].reg_len==WORD_LEN && temp!=0x0002)||(regarray[j].reg_len==BYTE_LEN && temp!=0x0001)) + break; + num++; + j++; + } + #endif + err = sensor_write_Multiple_data(client, ®array[i], num) ; + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + + i=i+num; + } +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} + +/* write sensor initial data */ +static int sensor_write_init_data(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; + int num = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + int ti=0; + int table[167] = { /*written data numbers every time*/ + 3,1,1,3,1,1,1,1,11,2,2,13,1,1,1,2,11,2,2,13, + 1,2,1,1,2,1,1,1,1,1,8,1,1,1,1,1,1,714,1,1, + 1,1,1,1,1,42,1,3,9,1,1,2,2,1,1,1,1,3,1,1, + 1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,8,2,2,2, + 2,2,1,1,1,1,10,10,9,6,4,2,9,2,2,2,1,1,1,1, + 1,1,1,1,1,1,1,1,58,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,3,3,2,1,1,1,1,1, 2,2,1, + 6,3,1,1,1,1,1,6,1,2,4,4,1,1,1,4,5,2,2,4, + 4,6,1,1,1,1,1 + }; + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != SEQUENCE_END) { + #if 0 + if(ti < 167){ + num = table[ti]; + ti++; + } + #else + num = 1; + #endif + err = sensor_write_Multiple_data(client, ®array[i], num) ; + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i=i+num; + } +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} + +#if 0 +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != SEQUENCE_END) { + + err = sensor_write(client, ®array[i]); + + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#endif +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != SEQUENCE_END) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif + +#if CONFIG_SENSOR_Focus + +static struct reginfo sensor_af_trigger[] = +{ + { 0xB854, 0x4040, WORD_LEN, 0}, // STAT_SM_WINDOW_POS_X; POS_Y + { 0xB856, 0x4040, WORD_LEN, 0}, // STAT_SM_WINDOW_SIZE_X; SIZE_Y + { 0xB006, 0x01, BYTE_LEN, 0}, //run AF - af.progress + {SEQUENCE_END, 0x00, 0, 0} +}; +static int sensor_af_touch_zone(struct i2c_client *client, int *zone_center_pos) +{ + int ret = 0; + + zone_center_pos[0] = zone_center_pos[0]*0x100/2000; + zone_center_pos[1] = zone_center_pos[1]*0x100/2000; + + zone_center_pos[0] = zone_center_pos[0]/0x40*0x40; + zone_center_pos[1] = zone_center_pos[1]/0x40*0x40; + + sensor_af_trigger[0].val = (zone_center_pos[0]<<8)|zone_center_pos[1]; + +sensor_af_zone_end: + return ret; +} +static int sensor_af_single(struct i2c_client *client) +{ + int ret = 0; + char cnt=0; + struct reginfo reg; + + ret = sensor_write_array(client, sensor_af_trigger); + if (ret<0) { + SENSOR_TR("%s sensor auto focus trigger fail!!\n",SENSOR_NAME_STRING()); + } else { + + reg.reg_len = BYTE_LEN; + reg.reg = 0xb006; + reg.val = 0x01; + + do { + msleep(30); + sensor_read1(client,®); + + } while ((reg.val != 0) && (cnt++ < 50)); + + SENSOR_DG("%s sensor auto focus trigger(0x%x) success! state: %d, cnt: %d\n",SENSOR_NAME_STRING(), + sensor_af_trigger[0].val,reg.val,cnt); + } + + +sensor_af_single_end: + return ret; +} + +static int sensor_af_const(struct i2c_client *client) +{ + int ret = 0; + +sensor_af_const_end: + return ret; +} + +static int sensor_af_init(struct i2c_client *client) +{ + int ret = 0; + return 0; +} +static int sensor_af_downfirmware(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + int ret=0; + struct soc_camera_device *icd = client->dev.platform_data; + struct v4l2_mbus_framefmt mf; + + SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__); + + if (sensor_af_init(client)) { + sensor->info_priv.funmodule_state &= (~SENSOR_AF_IS_OK); + ret = -1; + } else { + sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; + + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; + if (sensor_fmt_videochk(NULL, &mf) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ + ret = sensor_af_const(client); + } else { + switch (sensor->info_priv.auto_focus) + { + case SENSOR_AF_MODE_AUTO: + { + ret = sensor_af_single(client); + break; + } + case SENSOR_AF_MODE_CLOSE: + { + ret = 0; + break; + } + case SENSOR_AF_MODE_CONTINUOUS: + { + ret = sensor_af_const(client); + break; + } + default: + { + SENSOR_DG("%s focus mode(0x%x) is unkonwn\n",SENSOR_NAME_STRING(),sensor->info_priv.auto_focus); + goto sensor_af_downfirmware_end; + } + } + } + SENSOR_DG("%s sensor_af_downfirmware set focus mode(0x%x) ret:0x%x\n",SENSOR_NAME_STRING(), sensor->info_priv.auto_focus,ret); + } + +sensor_af_downfirmware_end: + + return ret; +} +static void sensor_af_workqueue(struct work_struct *work) +{ + struct sensor_work *sensor_work = container_of(work, struct sensor_work, dwork.work); + struct i2c_client *client = sensor_work->client; + struct sensor *sensor = to_sensor(client); + //struct af_cmdinfo cmdinfo; + + SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd); + + mutex_lock(&sensor->wq_lock); + + switch (sensor_work->cmd) + { + case WqCmd_af_init: + { + if (sensor_af_downfirmware(client) < 0) { + SENSOR_TR("%s Sensor_af_init is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); + } + break; + } + case WqCmd_af_single: + { + if ((sensor_work->zone_center_pos[0] >=0) && (sensor_work->zone_center_pos[1]>=0)) + sensor_af_touch_zone(client,sensor_work->zone_center_pos); + + if (sensor_af_single(client) < 0) { + SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); + sensor_work->result = WqRet_fail; + } else { + sensor_work->result = WqRet_success; + } + break; + } + #if 0 + case WqCmd_af_special_pos: + { + sensor_af_idlechk(client); + + cmdinfo.cmd_tag = StepFocus_Spec_Tag; + cmdinfo.cmd_para[0] = sensor_work->var; + cmdinfo.validate_bit = 0x81; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_near_pos: + { + sensor_af_idlechk(client); + cmdinfo.cmd_tag = StepFocus_Near_Tag; + cmdinfo.validate_bit = 0x80; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_far_pos: + { + sensor_af_idlechk(client); + cmdinfo.cmd_tag = StepFocus_Far_Tag; + cmdinfo.validate_bit = 0x80; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + #endif + case WqCmd_af_continues: + { + if (sensor_af_const(client) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + #if 0 + case WqCmd_af_return_idle: + { + if (sensor_af_idlechk(client) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + #endif + default: + SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING()); + break; + } +set_end: + if (sensor_work->wait == false) { + kfree((void*)sensor_work); + } else { + wake_up(&sensor_work->done); + } + mutex_unlock(&sensor->wq_lock); + return; +} + +static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait, int *zone_pos) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + struct sensor_work *wk; + int ret=0; + + if (sensor->sensor_wq == NULL) { + ret = -EINVAL; + goto sensor_af_workqueue_set_end; + } + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) != SENSOR_AF_IS_OK) { + if (cmd != WqCmd_af_init) { + SENSOR_TR("%s %s cmd(%d) ingore,because af module isn't ready!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + ret = -1; + goto sensor_af_workqueue_set_end; + } + } + + wk = kzalloc(sizeof(struct sensor_work), GFP_KERNEL); + if (wk) { + wk->client = client; + INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue); + wk->cmd = cmd; + wk->result = WqRet_inval; + wk->wait = wait; + wk->var = var; + + if (zone_pos) { + *zone_pos += 1000; + *(zone_pos+1) += 1000; + *(zone_pos+2) += 1000; + *(zone_pos+3) += 1000; + wk->zone_center_pos[0] = ((*zone_pos + *(zone_pos+2))>>1); + wk->zone_center_pos[1] = ((*(zone_pos+1) + *(zone_pos+3))>>1); + } + + init_waitqueue_head(&wk->done); + + /* ddl@rock-chips.com: + * video_lock is been locked in v4l2_ioctl function, but auto focus may slow, + * As a result any other ioctl calls will proceed very, very slowly since each call + * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF + * and VIDIOC_DQBUF is sched. so unlock video_lock here. + */ + if (wait == true) { + queue_delayed_work(sensor->sensor_wq,&(wk->dwork),0); + mutex_unlock(&icd->video_lock); + if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) { //hhb + SENSOR_TR("%s %s cmd(%d) is timeout!\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + } + ret = wk->result; + kfree((void*)wk); + mutex_lock(&icd->video_lock); + } else { + queue_delayed_work(sensor->sensor_wq,&(wk->dwork),msecs_to_jiffies(10)); + } + + } else { + SENSOR_TR("%s %s cmd(%d) ingore,because struct sensor_work malloc failed!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + ret = -1; + } +sensor_af_workqueue_set_end: + return ret; +} +#endif + +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + printk( "Sensor_Flash on = %d\n", on ); +#if 0 + if(on){ + //flash off after 2 secs + if ( flash_off_timer.status ){ + hrtimer_cancel(&(flash_off_timer.timer)); + } + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + flash_off_timer.status = 1; + }else{ + flash_off_timer.status = 0; + } +#endif + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } + +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *hrtimer){ + struct flash_timer *fps_timer = container_of(hrtimer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + printk("%s %s = 0x%x !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__, fps_timer ); + return 0; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); +#if (ADJUST_OPTIMIZE_TIME_FALG == 0) + const struct v4l2_queryctrl *qctrl; +#endif + const struct sensor_datafmt *fmt; + int ret,pid = 0; + int index =0 ; +#if (SENSOR_RESET_REG != SEQUENCE_END) + struct reginfo reg_info; +#endif + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + SENSOR_DG("\n soft reset..%s.\n",SENSOR_NAME_STRING()); + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + +#if (SENSOR_RESET_REG != SEQUENCE_END) + reg_info.reg = SENSOR_RESET_REG; + reg_info.val = SENSOR_RESET_VAL; + reg_info.reg_len = SENSOR_RESET_REG_LEN; + ret = sensor_write(client, ®_info); + if (ret != 0) { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + mdelay(5); //delay 5 microseconds +#endif + + /* check if it is an sensor sensor */ +#if (SENSOR_ID_REG != SEQUENCE_END) + ret = sensor_read(client, SENSOR_ID_REG, &pid); + if (ret != 0) { + SENSOR_TR("read chip id failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); +#else + pid = SENSOR_ID; +#endif + + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING()); + + ret =sensor_write_init_data(client, sensor_init_data); + if (ret != 0) { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + sensor->info_priv.preview_w = SENSOR_INIT_WIDTH; + sensor->info_priv.preview_h = SENSOR_INIT_HEIGHT; + sensor->info_priv.capture_w = SENSOR_MAX_WIDTH; + sensor->info_priv.capture_h = SENSOR_MAX_HEIGHT; + sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ +#if ADJUST_OPTIMIZE_TIME_FALG + SENSOR_DG("\n optimize code..%s.\n",SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_WhiteBalance + sensor->info_priv.whiteBalance = 0; + #endif + #if CONFIG_SENSOR_Brightness + sensor->info_priv.brightness = 0; + #endif + #if CONFIG_SENSOR_Effect + sensor->info_priv.effect = 0; + #endif + #if CONFIG_SENSOR_Exposure + sensor->info_priv.exposure = 0; + #endif + #if CONFIG_SENSOR_Saturation + sensor->info_priv.saturation = 0; + #endif + #if CONFIG_SENSOR_Contrast + sensor->info_priv.contrast = 0; + #endif + #if CONFIG_SENSOR_Mirror + sensor->info_priv.mirror = 1; + #endif + #if CONFIG_SENSOR_Flip + sensor->info_priv.flip = 1; + index++; + #endif + #if CONFIG_SENSOR_Scene + sensor->info_priv.scene = 0; + index++; + #endif + #if CONFIG_SENSOR_DigitalZoom + sensor->info_priv.digitalzoom = 0; + #endif + #if CONFIG_SENSOR_Focus + sensor->info_priv.focus = 125 ; + if (sensor_af_init(client) < 0) { + sensor->info_priv.funmodule_state &= ~SENSOR_AF_IS_OK; + SENSOR_TR("%s auto focus module init is fail!\n",SENSOR_NAME_STRING()); + } else { + sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; + SENSOR_DG("%s auto focus module init is success!\n",SENSOR_NAME_STRING()); + } + #endif + #if CONFIG_SENSOR_Flash + sensor->info_priv.flash = 0 ; + #endif + +#else + SENSOR_DG("\n origin code..%s.\n",SENSOR_NAME_STRING()); + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + + #if CONFIG_SENSOR_Focus + if (sensor_af_init(client) < 0) { + sensor->info_priv.funmodule_state &= ~SENSOR_AF_IS_OK; + SENSOR_TR("%s auto focus module init is fail!\n",SENSOR_NAME_STRING()); + } else { + sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; + SENSOR_DG("%s auto focus module init is success!\n",SENSOR_NAME_STRING()); + } + #endif + #ifdef CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + printk( "flash_off_timer.timer.function\n" ); + + #endif +#endif + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + + + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend..pm_msg.event=%d \n", SENSOR_NAME_STRING(),pm_msg.event); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + return 0; +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h) +{ + struct reginfo *winseqe_set_addr = NULL; + + if (set_w*240 == set_h*320) { + if (((set_w >= 320) && (set_h >= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qvga; + *ret_w = 320; + *ret_h = 240; + } + +#if ADJUST_FOR_VGA_FALG + // to forbid preview err + if (((set_w >= 576) && (set_h >= 432)) && (sensor_vga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_vga; + *ret_w = 576; + *ret_h = 432; + } +#else + if (((set_w >= 640) && (set_h >= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_vga; + *ret_w = 640; + *ret_h = 480; + } + +#endif + + if (((set_w >= 800) && (set_h >= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_svga; + *ret_w = 800; + *ret_h = 600; + } + + if (((set_w >= 1024) && (set_h >= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_xga; + *ret_w = 1024; + *ret_h = 768; + } + + if (((set_w >= 1280) && (set_h >= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_sxga; + *ret_w = 1280; + *ret_h = 1024; + } + + if (((set_w >= 1600) && (set_h >= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_uxga; + *ret_w = 1600; + *ret_h = 1200; + } + + if (((set_w >= 2048) && (set_h >= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qxga; + *ret_w = 2048; + *ret_h = 1536; + } + + if (((set_w >= 2592) && (set_h >= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qsxga; + *ret_w = 2592; + *ret_h = 1944; + } + + if (winseqe_set_addr == NULL) { + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qcif; + *ret_w = 176; + *ret_h = 144; + } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_cif; + *ret_w = 352; + *ret_h = 288; + } + + if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_720p; + *ret_w = 1280; + *ret_h = 720; + } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_1080p; + *ret_w = 1920; + *ret_h = 1080; + } + } + + } else if (set_w*288 == set_h*352) { + if (((set_w >= 176) && (set_h >= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qcif; + *ret_w = 176; + *ret_h = 144; + } else if (((set_w >= 352) && (set_h >= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_cif; + *ret_w = 352; + *ret_h = 288; + } + + if (winseqe_set_addr == NULL) { + if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qvga; + *ret_w = 320; + *ret_h = 240; + } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_vga; + *ret_w = 640; + *ret_h = 480; + } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_svga; + *ret_w = 800; + *ret_h = 600; + } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_xga; + *ret_w = 1024; + *ret_h = 768; + } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_sxga; + *ret_w = 1280; + *ret_h = 1024; + } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_uxga; + *ret_w = 1600; + *ret_h = 1200; + } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qxga; + *ret_w = 2048; + *ret_h = 1536; + } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qsxga; + *ret_w = 2592; + *ret_h = 1944; + } + + + if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_720p; + *ret_w = 1280; + *ret_h = 720; + } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_1080p; + *ret_w = 1920; + *ret_h = 1080; + } + } + } else if (set_w*720 == set_h*1280) { + if (((set_w >= 1280) && (set_h >= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_720p; + *ret_w = 1280; + *ret_h = 720; + } else if (((set_w >= 1920) && (set_h >= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_1080p; + *ret_w = 1920; + *ret_h = 1080; + } + + if (winseqe_set_addr == NULL) { + + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qcif; + *ret_w = 176; + *ret_h = 144; + } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_cif; + *ret_w = 352; + *ret_h = 288; + } + + if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qvga; + *ret_w = 320; + *ret_h = 240; + } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_vga; + *ret_w = 640; + *ret_h = 480; + } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_svga; + *ret_w = 800; + *ret_h = 600; + } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_xga; + *ret_w = 1024; + *ret_h = 768; + } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_sxga; + *ret_w = 1280; + *ret_h = 1024; + } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_uxga; + *ret_w = 1600; + *ret_h = 1200; + } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qxga; + *ret_w = 2048; + *ret_h = 1536; + } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qsxga; + *ret_w = 2592; + *ret_h = 1944; + } + } + } else { + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qcif; + *ret_w = 176; + *ret_h = 144; + } else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qvga; + *ret_w = 320; + *ret_h = 240; + } else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_cif; + *ret_w = 352; + *ret_h = 288; + } else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_vga; + *ret_w = 640; + *ret_h = 480; + } else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_svga; + *ret_w = 800; + *ret_h = 600; + } else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_xga; + *ret_w = 1024; + *ret_h = 768; + } else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_720p; + *ret_w = 1280; + *ret_h = 720; + } else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_sxga; + *ret_w = 1280; + *ret_h = 1024; + } else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_uxga; + *ret_w = 1600; + *ret_h = 1200; + } else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_1080p; + *ret_w = 1920; + *ret_h = 1080; + } else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qxga; + *ret_w = 2048; + *ret_h = 1536; + } else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) { + winseqe_set_addr = sensor_qsxga; + *ret_w = 2592; + *ret_h = 1944; + } + } + + return winseqe_set_addr; +} + +/*modify image with resolution 2592*1944;solve bug that the first 32 pixel data*/ +/*in the first line have misplace with the last 32 pixel data in the last line*/ +static int sensor_cb(void *arg) +{ + void __iomem *vbpmem; + struct videobuf_buffer *buffer; + char *imagey_addr =NULL; + char *imageuv_addr = NULL; + char *tempaddr = NULL; + int tempsize = 0; + + buffer = (struct videobuf_buffer*)arg; + if(buffer->width!=SENSOR_MAX_WIDTH||buffer->height!=SENSOR_MAX_HEIGHT||buffer==NULL) + return -EINVAL; + + if (buffer->bsize< YUV420_BUFFER_MAX_SIZE) //yuv420 format size + return -EINVAL; + + + vbpmem = ioremap(buffer->boff,buffer->bsize); + if(vbpmem == NULL) { + SENSOR_DG("\n%s..%s..ioremap fail\n",__FUNCTION__,SENSOR_NAME_STRING()); + return -ENXIO; + } + + imagey_addr = (char*)vbpmem; // y data to be dealed with + imageuv_addr = imagey_addr+buffer->width*buffer->height; + + tempaddr = imageuv_addr - 32; + memcpy(tempaddr,imagey_addr,32); + + tempaddr = imagey_addr+32; + memcpy(imagey_addr,tempaddr,32); + + //uv data to be dealed with + tempsize = YUV420_BUFFER_MAX_SIZE-32; + tempaddr = imagey_addr+tempsize; + memcpy(tempaddr,imageuv_addr,32); + + tempaddr = imageuv_addr+32; + memcpy(imageuv_addr,tempaddr,32); + return 0; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + struct reginfo *winseqe_set_addr=NULL; + int ret = 0, set_w,set_h,cnt; + u16 seq_state=0; + int time = 0; + u16 targetbrightness,realbrightness; + + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h); + + if ((winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) && winseqe_set_addr) + { + /*solve bug that video set is ineffective */ + /*set five times to make sure sensor_720p set go into effect*/ + if(winseqe_set_addr==sensor_720p) + { + time = 5; + }else{ + time = 1; + } + + while(time > 0) + { + time--; + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + goto sensor_s_fmt_end; + } + udelay(10); + } + sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; + if (winseqe_set_addr==sensor_qxga ||winseqe_set_addr==sensor_qsxga||winseqe_set_addr==sensor_uxga ||winseqe_set_addr==sensor_xga) + { + SENSOR_DG("\n%s..%s..Capture icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } else { + SENSOR_DG("\n%s..%s..Video icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + sensor->info_priv.preview_w = mf->width; + sensor->info_priv.preview_h = mf->height; + } + } + + if (winseqe_set_addr && (winseqe_set_addr==sensor_qxga ||winseqe_set_addr==sensor_qsxga||winseqe_set_addr==sensor_uxga ||winseqe_set_addr==sensor_xga)) + { + ret |= sensor_write_array(client, sensor_Preview2Capture); + if (ret != 0) { + SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING()); + goto sensor_s_fmt_end; + } + + /*check state of register 0x8405 to make sure set is successful*/ + /*set sensor_Preview2Capture more times to make sure set go into effect */ + cnt = 0; + time =0; + do{ + ret = 0; + msleep(50); + ret =sensor_read(client,0x8405, &seq_state); + if (ret < 0) + goto sensor_s_fmt_end; + cnt++; + if(cnt > 9) + { + time++; + cnt = 0; + ret |= sensor_write_array(client, sensor_Preview2Capture); + if (ret != 0||time >2) { + SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING()); + goto sensor_s_fmt_end; + } + SENSOR_DG("mt9p111 Preview 2 Capture again\n"); + } + SENSOR_DG("mt9p111 Preview 2 Capture count = %d;seq_state = 0x%x\n",cnt,seq_state); + } while((seq_state != 0x07) && (time < 4)); + + SENSOR_TR("%s Preview 2 Capture successs\n", SENSOR_NAME_STRING()); + + #if CONFIG_SENSOR_Flash + /*The 0xA409 is AE target register address.*/ + /*The 0xB804 is currently total brightness Y value of sensor.*/ + targetbrightness = 0; + realbrightness =0; + if((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) + { + if(sensor->info_priv.flash == 1) + { + ret =sensor_read(client,0xA409, &targetbrightness); + if (ret < 0) + SENSOR_DG("%s ..%s..get targetbrightness fail\n", SENSOR_NAME_STRING(),__FUNCTION__); + + ret =sensor_read(client, 0xB804, &realbrightness); + if (ret < 0) + SENSOR_DG("%s ..%s..get realbrightness fail\n", SENSOR_NAME_STRING(),__FUNCTION__); + } + + if((realbrightness < targetbrightness)|| (sensor->info_priv.flash == 2)) + { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on,realbrightness=%d,targetbrightness=%d\n", SENSOR_NAME_STRING(),realbrightness,targetbrightness); + }else{ + SENSOR_DG("%s not need to flash in capture!\n", SENSOR_NAME_STRING()); + } + } + #endif + sensor->info_priv.capture_w = set_w; + sensor->info_priv.capture_h = set_h; + sensor->info_priv.snap2preview = true; + } else if (sensor->info_priv.snap2preview == true) { + if (winseqe_set_addr || ((sensor->info_priv.preview_w == mf->width) && (sensor->info_priv.preview_h == mf->height))) { + ret |= sensor_write_array(client, sensor_Capture2Preview); + if (ret != 0) { + SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING()); + goto sensor_s_fmt_end; + } + + cnt = 0; + do{ //check state of register 0x8405 to make sure set is successful + ret = 0; + msleep(50); + ret =sensor_read(client,0x8405, &seq_state); + if (ret < 0) + goto sensor_s_fmt_end; + SENSOR_DG("mt9p111 Capture 2 Preview seq_state = 0x%x\n",seq_state); + } while((seq_state != 0x03) && (cnt < 20)); + + SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING()); + + #if CONFIG_SENSOR_Flash + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + #endif + sensor->info_priv.preview_w = mf->width; + sensor->info_priv.preview_h = mf->height; + sensor->info_priv.snap2preview = false; + } else { + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + } + + mf->width = set_w; + mf->height = set_h; +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + if (sensor_fmt_catch(mf->width, mf->height, &mf->width, &mf->height) == NULL) { + mf->width = 0; + mf->height = 0; + } + mf->colorspace = fmt->colorspace; + + return ret; +} + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + int time =5; + int ret =0 ; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + /*set five times to make sure the set go into effect*/ + /*solve bug for setting invalidate during changing from preview to video*/ + while(time >0) + { + time--; + ret |=sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]); + if(ret != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + msleep(50); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + printk("=====sensor_set_flash====== Flash On\n"); + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + printk("=====sensor_set_flash====== Flash off\n"); + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Focus +static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int ret = 0; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (!qctrl_info) + return -EINVAL; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { + + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EINVAL; + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + } + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } + +sensor_set_focus_absolute_end: + return ret; +} +static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int ret = 0; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE); + if (!qctrl_info) + return -EINVAL; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { + + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EINVAL; + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + } + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } +sensor_set_focus_relative_end: + return ret; +} + +static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int *zone_pos) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int ret = 0; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + switch (value) + { + case SENSOR_AF_MODE_AUTO: + { + ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true, zone_pos); + break; + } + + /*case SENSOR_AF_MODE_MACRO: + { + ret = sensor_set_focus_absolute(icd, qctrl, 0xff); + break; + } + + case SENSOR_AF_MODE_INFINITY: + { + ret = sensor_set_focus_absolute(icd, qctrl, 0x00); + break; + } + */ + case SENSOR_AF_MODE_CONTINUOUS: + { + ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true,NULL); + break; + } + default: + SENSOR_TR("\n %s..%s AF value(0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,value); + break; + + } + + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } + + return ret; + +} +#endif +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + #if 0 + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (sensor_set_focus_absolute(icd, qctrl,ext_ctrl->value) == 0) { + if (ext_ctrl->value == qctrl->minimum) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_INFINITY; + } else if (ext_ctrl->value == qctrl->maximum) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_MACRO; + } else { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_FIXED; + } + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + sensor_set_focus_relative(icd, qctrl,ext_ctrl->value); + break; + } + #endif + case V4L2_CID_FOCUS_AUTO: + { + if (ext_ctrl->value) { + if ((ext_ctrl->value==1) || (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus)) { + if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO,ext_ctrl->rect) != 0) { + if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; + } + return -EINVAL; + } + } + if (ext_ctrl->value == 1) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; + } else if (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus){ + if (ext_ctrl->value == 0) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; + } + break; + } + case V4L2_CID_FOCUS_CONTINUOUS: + { + if (SENSOR_AF_MODE_CONTINUOUS != sensor->info_priv.auto_focus) { + if (ext_ctrl->value == 1) { + if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_CONTINUOUS,NULL) != 0) { + if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; + } + return -EINVAL; + } + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; + } + } else { + if (ext_ctrl->value == 0) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + #if CONFIG_SENSOR_Focus + struct soc_camera_device *icd = client->dev.platform_data; + struct v4l2_mbus_framefmt mf; + #endif + + if (enable == 1) { + sensor->info_priv.enable = 1; + #if CONFIG_SENSOR_Focus + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; + /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ + if (sensor_fmt_capturechk(sd, &mf) == false) { + if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { + sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false,NULL); + sensor->info_priv.affm_reinit = 0; + } + } + #endif + } else if (enable == 0) { + sensor->info_priv.enable = 0; + #if CONFIG_SENSOR_Focus + flush_workqueue(sensor->sensor_wq); + #endif + } + return 0; +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + int ret,pid = 0; + struct sensor *sensor = to_sensor(client); +#if (SENSOR_RESET_REG != SEQUENCE_END) + struct reginfo reg_info; +#endif + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ +#if (SENSOR_RESET_REG != SEQUENCE_END) + reg_info.reg = SENSOR_RESET_REG; + reg_info.val = SENSOR_RESET_VAL; + reg_info.reg_len = SENSOR_RESET_REG_LEN; + ret = sensor_write(client, ®_info); + if (ret != 0) { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + mdelay(5); //delay 5 microseconds +#endif + + /* check if it is an sensor sensor */ +#if (SENSOR_ID_REG != SEQUENCE_END) + ret = sensor_read(client, SENSOR_ID_REG, &pid); + if (ret != 0) { + SENSOR_TR("read chip id failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); +#else + pid = SENSOR_ID; +#endif + + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); +//#if CONFIG_SENSOR_Flash + int i; +//#endif + int ret = 0; + + rk29_camera_sensor_cb_s *icd_cb =NULL; + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + case RK29_CAM_SUBDEV_CB_REGISTER: + { + icd_cb = (rk29_camera_sensor_cb_s*)(arg); + icd_cb->sensor_cb = sensor_cb; + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, + .s_stream = sensor_s_stream, +}; +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } else { + #if CONFIG_SENSOR_Focus + sensor->sensor_wq = create_singlethread_workqueue(SENSOR_NAME_STRING(_af_workqueue)); + if (sensor->sensor_wq == NULL) + SENSOR_TR("%s create fail!", SENSOR_NAME_STRING(_af_workqueue)); + mutex_init(&sensor->wq_lock); + #endif + } + flash_off_timer.status = 0; + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + #if CONFIG_SENSOR_Focus + if (sensor->sensor_wq) { + destroy_workqueue(sensor->sensor_wq); + sensor->sensor_wq = NULL; + } + #endif + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/nt99160_2way.c b/drivers/media/video/nt99160_2way.c new file mode 100755 index 000000000000..a78867d69b00 --- /dev/null +++ b/drivers/media/video/nt99160_2way.c @@ -0,0 +1,1264 @@ + +#include "generic_sensor.h" + +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + +static int debug =1; +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_i2c_slave_id 0x54 +#define SENSOR_NAME RK29_CAM_SENSOR_NT99160 +#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99160 +#define SENSOR_ID 0x1600 +#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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 5000 // 5fps +#define SENSOR_FULLRES_M_FPS 10000 // 5fps +#define SENSOR_FULLRES_H_FPS 15000 // 15-20fps +#define SENSOR_720P_FPS 5000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0x3100, 0x03}, + {0x3101, 0x80}, + {0x3102, 0x09}, + {0x3104, 0x03}, + {0x3105, 0x03}, + {0x3106, 0x05}, + {0x3107, 0x40}, + {0x3108, 0x00}, + {0x3109, 0x82}, + {0x310A, 0x04}, + {0x310B, 0x00}, + {0x310C, 0x00}, + {0x3111, 0x56}, + {0x3113, 0x66}, + {0x3118, 0xA7}, + {0x3119, 0xA7}, + {0x311A, 0xA7}, + {0x311B, 0x1F}, + {0x303f, 0x0e}, + {0x3041, 0x04}, + {0x3051, 0xf4}, + {0x320A, 0x5A}, + {0x3250, 0x80}, + {0x3251, 0x01}, + {0x3252, 0x38}, + {0x3253, 0xA8}, + {0x3254, 0x01}, + {0x3255, 0x00}, + {0x3256, 0x8C}, + {0x3257, 0x70}, + {0x329B, 0x00}, + {0x32A1, 0x00}, + {0x32A2, 0xd8}, + {0x32A3, 0x01}, + {0x32A4, 0x5d}, + {0x32A5, 0x01}, + {0x32A6, 0x0c}, + {0x32A7, 0x01}, + {0x32A8, 0xa8}, + {0x3210, 0x32}, + {0x3211, 0x2a}, + {0x3212, 0x30}, + {0x3213, 0x32}, + {0x3214, 0x2e}, + {0x3215, 0x2e}, + {0x3216, 0x2e}, + {0x3217, 0x2e}, + {0x3218, 0x2c}, + {0x3219, 0x2e}, + {0x321A, 0x2a}, + {0x321B, 0x2a}, + {0x321C, 0x2e}, + {0x321D, 0x2e}, + {0x321E, 0x28}, + {0x321F, 0x2c}, + {0x3220, 0x01}, + {0x3221, 0x48}, + {0x3222, 0x01}, + {0x3223, 0x48}, + {0x3224, 0x01}, + {0x3225, 0x48}, + {0x3226, 0x01}, + {0x3227, 0x48}, + {0x3228, 0x00}, + {0x3229, 0xa4}, + {0x322A, 0x00}, + {0x322B, 0xa4}, + {0x322C, 0x00}, + {0x322D, 0xa4}, + {0x322E, 0x00}, + {0x322F, 0xa4}, + {0x3243, 0xc2}, + {0x3270, 0x10}, + {0x3271, 0x1B}, + {0x3272, 0x26}, + {0x3273, 0x3E}, + {0x3274, 0x4F}, + {0x3275, 0x5E}, + {0x3276, 0x78}, + {0x3277, 0x8F}, + {0x3278, 0xA3}, + {0x3279, 0xB4}, + {0x327A, 0xD2}, + {0x327B, 0xE3}, + {0x327C, 0xF0}, + {0x327D, 0xF7}, + {0x327E, 0xFF}, + {0x32F6, 0x0C}, + {0x33c2, 0xF0}, + {0x3302, 0x00}, + {0x3303, 0x3E}, + {0x3304, 0x00}, + {0x3305, 0xC2}, + {0x3306, 0x00}, + {0x3307, 0x00}, + {0x3308, 0x07}, + {0x3309, 0xC4}, + {0x330A, 0x06}, + {0x330B, 0xED}, + {0x330C, 0x01}, + {0x330D, 0x4F}, + {0x330E, 0x01}, + {0x330F, 0x41}, + {0x3310, 0x06}, + {0x3311, 0xDD}, + {0x3312, 0x07}, + {0x3313, 0xE3}, + {0x3326, 0x14}, + {0x3327, 0x04}, + {0x3328, 0x04}, + {0x3329, 0x02}, + {0x332A, 0x02}, + {0x332B, 0x1D}, + {0x332C, 0x1D}, + {0x332D, 0x04}, + {0x332E, 0x1E}, + {0x332F, 0x1F}, + {0x3331, 0x0a}, + {0x3332, 0x40}, + {0x33C9, 0xD8}, + {0x33C0, 0x01}, + {0x333F, 0x07}, + {0x3360, 0x10}, + {0x3361, 0x18}, + {0x3362, 0x1f}, + {0x3363, 0xb3}, + {0x3368, 0xb0}, + {0x3369, 0xa0}, + {0x336A, 0x90}, + {0x336B, 0x80}, + {0x336C, 0x00}, + {0x3363, 0xB3}, + {0x3364, 0x00}, + {0x3365, 0x10}, + {0x3366, 0x06}, + {0x336d, 0x18}, + {0x336e, 0x18}, + {0x336f, 0x10}, + {0x3370, 0x10}, + {0x3371, 0x3F}, + {0x3372, 0x3F}, + {0x3373, 0x3F}, + {0x3374, 0x3F}, + {0x3375, 0x20}, + {0x3376, 0x20}, + {0x3377, 0x28}, + {0x3378, 0x30}, + {0x32f6, 0x0C}, + {0x33A0, 0xE0}, + {0x33A1, 0x20}, + {0x33A2, 0x00}, + {0x33A3, 0x40}, + {0x33A4, 0x00}, + {0x32BF, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x84}, + {0x32C1, 0x84}, + {0x32C2, 0x84}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x95}, + {0x32C9, 0x84}, + {0x32CA, 0xA4}, + {0x32CB, 0xA4}, + {0x32CC, 0xA4}, + {0x32CD, 0xA4}, + {0x32DB, 0x72}, + {0x3241, 0x8B}, + {0x32F0, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302C, 0x07}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x05}, + {0x3007, 0x03},//x_end =1283 + {0x3008, 0x02}, + {0x3009, 0xD3},//y_end =723 + {0x300A, 0x06}, + {0x300B, 0x48},//pixel_num=1608 + {0x300C, 0x0B}, + {0x300D, 0xA9},//line_num=2985 + {0x300E, 0x05}, + {0x300F, 0x00},//x_width = 1280 + {0x3010, 0x02}, + {0x3011, 0xD0},//y_height=720 + {0x32B8, 0x3F}, + {0x32B9, 0x31}, + {0x32BB, 0x87}, + {0x32BC, 0x38}, + {0x32BD, 0x3C}, + {0x32BE, 0x34}, + {0x3201, 0x3F}, + {0x3109, 0x82}, + {0x310B, 0x00}, + {0x3530, 0xC0}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; + + +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_midfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x74}, + {0x32C1, 0x74}, + {0x32C2, 0x74}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x95}, + {0x32C9, 0x74}, + {0x32CA, 0x94}, + {0x32CB, 0x94}, + {0x32CC, 0x94}, + {0x32CD, 0x94}, + {0x32DB, 0x72}, + {0x3241, 0x83}, + {0x32F0, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302C, 0x07}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x05}, + {0x3007, 0x03},//x_end = 1283 + {0x3008, 0x02}, + {0x3009, 0xD3},//y_end =723 + {0x300A, 0x06}, + {0x300B, 0x48},//pixel_num = 1608 + {0x300C, 0x05}, + {0x300D, 0xD4},//line_num = 1492 + {0x300E, 0x05}, + {0x300F, 0x00},//x_width = 1280 + {0x3010, 0x02}, + {0x3011, 0xD0},//y_height=720 + {0x32B8, 0x3F}, + {0x32B9, 0x31}, + {0x32BB, 0x87}, + {0x32BC, 0x38}, + {0x32BD, 0x3C}, + {0x32BE, 0x34}, + {0x3201, 0x3F}, + {0x3109, 0x82}, + {0x310B, 0x00}, + {0x3530, 0xC0}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x95}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x72}, + {0x3241, 0x7E}, + {0x32F0, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302C, 0x07}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x05}, + {0x3007, 0x03},//x_end=1283 x_width=1280 + {0x3008, 0x02}, + {0x3009, 0xD3},//y_end=723 y_height=720 + {0x300A, 0x06}, + {0x300B, 0x48},//line_pixel_num =1608 + {0x300C, 0x02}, + {0x300D, 0xEA},//line_num=746 + {0x300E, 0x05}, + {0x300F, 0x00},//x_width = 1280 + {0x3010, 0x02}, + {0x3011, 0xD0},//y_height = 720 + {0x32B8, 0x3F}, + {0x32B9, 0x31}, + {0x32BB, 0x87}, + {0x32BC, 0x38}, + {0x32BD, 0x3C}, + {0x32BE, 0x34}, + {0x3201, 0x3F}, + {0x3109, 0x82}, + {0x310B, 0x00}, + {0x3530, 0xC0}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0xBA}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x77}, + {0x3241, 0x80}, + {0x32E0, 0x03}, + {0x32E1, 0x20}, + {0x32E2, 0x02}, + {0x32E3, 0x58}, + {0x32E4, 0x00}, + {0x32E5, 0x33}, + {0x32E6, 0x00}, + {0x32E7, 0x33}, + {0x32E8, 0x01}, + {0x32F0, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302C, 0x07}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0xA4},//x_start=164 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x04}, + {0x3007, 0x63},//x_end=1123 + {0x3008, 0x02}, + {0x3009, 0xD3},//y_end=723 + {0x300A, 0x05}, + {0x300B, 0x08},//pixel_num=1288 + {0x300C, 0x02}, + {0x300D, 0xE0},//line_num=736 + {0x300E, 0x03}, + {0x300F, 0xC0},//x_width=960 + {0x3010, 0x02}, + {0x3011, 0xD0},//y_height=720 + {0x32B8, 0x3F}, + {0x32B9, 0x31}, + {0x32BB, 0x87}, + {0x32BC, 0x38}, + {0x32BD, 0x3C}, + {0x32BE, 0x34}, + {0x3201, 0x7F}, + {0x3109, 0x82}, + {0x310B, 0x00}, + {0x3530, 0xC0}, + {0x3021, 0x06}, + {0x3060, 0x01}, + + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + + {0x32BF, 0x60}, + {0x32C0, 0x84}, + {0x32C1, 0x84}, + {0x32C2, 0x84}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x95}, + {0x32C9, 0x84}, + {0x32CA, 0xA4}, + {0x32CB, 0xA4}, + {0x32CC, 0xA4}, + {0x32CD, 0xA4}, + {0x32DB, 0x72}, + {0x3241, 0x8B}, + {0x32F0, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302C, 0x07}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x05}, + {0x3007, 0x03},//x_end =1283 + {0x3008, 0x02}, + {0x3009, 0xD3},//y_end =723 + {0x300A, 0x06}, + {0x300B, 0x48},//pixel_num=1608 + {0x300C, 0x0B}, + {0x300D, 0xA9},//line_num=2985 + {0x300E, 0x05}, + {0x300F, 0x00},//x_width = 1280 + {0x3010, 0x02}, + {0x3011, 0xD0},//y_height=720 + {0x32B8, 0x3F}, + {0x32B9, 0x31}, + {0x32BB, 0x87}, + {0x32BC, 0x38}, + {0x32BD, 0x3C}, + {0x32BE, 0x34}, + {0x3201, 0x3F}, + {0x3109, 0x82}, + {0x310B, 0x00}, + {0x3530, 0xC0}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0x3021,0x61), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x3000,0), + SensorRegVal(0x3001,0), + 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[]= +{ + {0x3201, 0x3F}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x3201, 0x2F}, + {0x3290, 0x01}, + {0x3291, 0x51}, + {0x3296, 0x01}, + {0x3297, 0x00}, + {0x3060, 0x01}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + {0x3201, 0x2F}, + {0x3290, 0x01}, + {0x3291, 0x38}, + {0x3296, 0x01}, + {0x3297, 0x68}, + {0x3060, 0x01}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //INCANDESCENCE + {0x3201, 0x2F}, + {0x3290, 0x01}, + {0x3291, 0x30}, + {0x3296, 0x01}, + {0x3297, 0xCB}, + {0x3060, 0x01}, + SensorEnd +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //FLUORESCENT] + {0x3201, 0x2F}, + {0x3290, 0x01}, + {0x3291, 0x70}, + {0x3296, 0x01}, + {0x3297, 0xFF}, + {0x3060, 0x01}, + SensorEnd +}; + +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]= +{ + //TUNGSTEN] + {0x3201, 0x2F}, + {0x3290, 0x01}, + {0x3291, 0x00}, + {0x3296, 0x02}, + {0x3297, 0x30}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,sensor_WhiteB_TungstenLamp3,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[] = +{ + {0x32F1, 0x00}, + {0x32F4, 0x80}, + {0x32F5, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + //Grayscale + {0x32F1, 0x01}, + {0x32F6, 0X08}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + //Sepia + {0x32F1, 0x02}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Inverse[] = +{ + //Inverse + {0x32F1, 0x03}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x32F1, 0x05}, + {0x32F4, 0xF0}, + {0x32F5, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + //Greenish + {0x32F1, 0x05}, + {0x32F4, 0x60}, + {0x32F5, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Solarization[] = +{ + //Solarization + {0x32F1, 0x04}, + SensorEnd +}; + + +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia, + sensor_Effect_Bluish,sensor_Effect_Green,sensor_Effect_Solarization, NULL, +}; + +static struct rk_sensor_reg sensor_Exposure04[]= +{ + //[EV-4] + {0x32F6, 0X0C}, + {0x32F2, 0x40}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Exposure03[]= +{ + //[EV-3] + {0x32F6, 0X0C}, + {0x32F2, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure02[]= +{ + //[EV-2] + {0x32F6, 0X0C}, + {0x32F2, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure01[]= +{ + //[EV-1] + {0x32F6, 0X0C}, + {0x32F2, 0x70}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure00[]= +{ + //[EV+0] + {0x32F6, 0X0C}, + {0x32F2, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure11[]= +{ + //[EV+1] + {0x32F6, 0X0C}, + {0x32F2, 0x90}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure12[]= +{ + //[EV+2] + {0x32F6, 0X0C}, + {0x32F2, 0xA0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure13[]= +{ + //[EV+3] + {0x32F6, 0X0C}, + {0x32F2, 0xB0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure14[]= +{ + //[EV+4] + {0x32F6, 0X0C}, + {0x32F2, 0xC0}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00, + sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,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_Contrast04[]= +{ + //[Contrast : -4] + {0x32F6, 0x0C}, + {0x32C2, 0x40}, + {0x32F2, 0x40}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast03[]= +{ + //[Contrast : -3] + {0x32F6, 0x0C}, + {0x32C2, 0x30}, + {0x32F2, 0x50}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast02[]= +{ + //[Contrast : -2] + {0x32F6, 0x0C}, + {0x32C2, 0x20}, + {0x32F2, 0x60}, + {0x3060, 0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Contrast01[]= +{ + //[Contrast : -1] + {0x32F6, 0x0C}, + {0x32C2, 0x10}, + {0x32F2, 0x70}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast00[]= +{ + //[Contrast : 0] + {0x32F6, 0x0C}, + {0x32C2, 0x00}, + {0x32F2, 0x80}, + {0x3060, 0x01}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast11[]= +{ + //[Contrast : +1] + {0x32F6, 0x0C}, + {0x32C2, 0xF0}, + {0x32F2, 0x90}, + {0x3060, 0x01}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast12[]= +{ + //[Contrast : +2] + {0x32F6, 0x0C}, + {0x32C2, 0xE0}, + {0x32F2, 0xA0}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast13[]= +{ + //[Contrast : +3] + {0x32F6, 0x0C}, + {0x32C2, 0xD0}, + {0x32F2, 0xB0}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast14[]= +{ + //[Contrast : +4] + {0x32F6, 0x0C}, + {0x32C2, 0xC0}, + {0x32F2, 0xC0}, + {0x3060, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01, + sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,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), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",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,"posterize",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",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, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe), + new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe), +}; + + +//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}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +#define NT99160_FULL_PERIOD_PIXEL_NUMS (1608) // default pixel#(w/o dummy pixels) in UXGA mode +#define NT99160_FULL_PERIOD_LINE_NUMS (746) // default line#(w/o dummy lines) in UXGA mode +#define NT99160_PV_PERIOD_PIXEL_NUMS (1288) // default pixel#(w/o dummy pixels) in SVGA mode +#define NT99160_PV_PERIOD_LINE_NUMS (736) // default line#(w/o dummy lines) in SVGA mode + +/* SENSOR EXPOSURE LINE LIMITATION */ +#define NT99160_FULL_EXPOSURE_LIMITATION (1492) +#define NT99160_PV_EXPOSURE_LIMITATION (736) + +// SENSOR UXGA SIZE +#define NT99160_IMAGE_SENSOR_FULL_WIDTH (1280) +#define NT99160_IMAGE_SENSOR_FULL_HEIGHT (720) + +#define NT99160_FULL_GRAB_WIDTH (NT99160_IMAGE_SENSOR_FULL_WIDTH - 16) +#define NT99160_FULL_GRAB_HEIGHT (NT99160_IMAGE_SENSOR_FULL_HEIGHT - 12) + +/* +********************************************************** +* 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) +{ + u8 reg_val; + + SENSOR_DG("%s\n",__FUNCTION__); + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + u8 reg_val; + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */ + + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + } + + 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 0; +} +/* +* 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) +{ + return 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) +{ + int ret=0; + + SENSOR_DG("Resume"); + //ret = generic_sensor_ioctrl(icd, Sensor_PowerDown, 0); + + return ret; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x02; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfd; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x01; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfe; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} + +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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + + 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/nt99240_2way.c b/drivers/media/video/nt99240_2way.c new file mode 100755 index 000000000000..1b52ad2dba5d --- /dev/null +++ b/drivers/media/video/nt99240_2way.c @@ -0,0 +1,1200 @@ + +#include "generic_sensor.h" + +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + +static int debug =1; +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_SENSOR_NT99240 +#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99240 +#define SENSOR_ID 0x2400 +#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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 5000 // 5fps +#define SENSOR_FULLRES_H_FPS 10000 // 10fps +#define SENSOR_720P_FPS 15000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain_dr; + unsigned short int preview_gain_ar; + unsigned short int preview_gain_dgr; + unsigned short int preview_gain_agr; + unsigned short int preview_gain_dgb; + unsigned short int preview_gain_agb; + unsigned short int preview_gain_db; + unsigned short int preview_gain_ab; + unsigned short int preview_gain_dglobal; + unsigned short int preview_gain_aglobal; + unsigned short int preview_awb_r; + unsigned short int preview_awb_b; + + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0x32F0, 0x01}, + {0x3028, 0x07}, + {0x3029, 0x00}, + {0x302a, 0x04}, + {0x3290, 0x01}, + {0x3291, 0x94}, + {0x3296, 0x01}, + {0x3297, 0x6D}, + {0x3210, 0x3A}, + {0x3211, 0x3A}, + {0x3212, 0x3A}, + {0x3213, 0x3A}, + {0x3214, 0x2A}, + {0x3215, 0x2A}, + {0x3216, 0x2A}, + {0x3217, 0x2A}, + {0x3218, 0x2A}, + {0x3219, 0x2A}, + {0x321A, 0x2A}, + {0x321B, 0x2A}, + {0x321C, 0x22}, + {0x321D, 0x22}, + {0x321E, 0x22}, + {0x321F, 0x22}, + {0x3230, 0x30}, + {0x3231, 0x00}, + {0x3232, 0xCF}, + {0x3233, 0x00}, + {0x3234, 0x05}, + {0x3302, 0x00}, + {0x3303, 0x5F}, + {0x3304, 0x00}, + {0x3305, 0x7E}, + {0x3306, 0x00}, + {0x3307, 0x22}, + {0x3308, 0x07}, + {0x3309, 0xC3}, + {0x330A, 0x07}, + {0x330B, 0x33}, + {0x330C, 0x01}, + {0x330D, 0x0A}, + {0x330E, 0x00}, + {0x330F, 0xD3}, + {0x3310, 0x07}, + {0x3311, 0x3B}, + {0x3312, 0x07}, + {0x3313, 0xF2}, + {0x3024, 0x00}, + {0x303E, 0x04}, + {0x303F, 0x02}, + {0x3040, 0xFF}, + {0x3041, 0x02}, + {0x3051, 0xE0}, + {0x3052, 0x10}, + {0x305f, 0x22}, + {0x32b0, 0x00}, + {0x32b1, 0x90}, + {0x32BB, 0x0b}, + {0x32bd, 0x08}, + {0x32be, 0x06}, + {0x32bf, 0x4a}, + {0x32c0, 0x20}, + {0x32C3, 0x06}, + {0x32c5, 0x28}, + {0x32cd, 0x02}, + {0x32d3, 0x12}, + {0x3118, 0xF2}, + {0x3119, 0xF2}, + {0x311A, 0x13}, + {0x3106, 0x03}, + {0x3108, 0x00}, + {0x3112, 0xF1}, + {0x3113, 0x55}, + {0x3114, 0x05}, + {0x3012, 0x03}, + {0x3013, 0xC0}, + {0x3326, 0x02}, + {0x3327, 0x04}, + {0x3328, 0x04}, + {0x3329, 0x02}, + {0x332A, 0x02}, + {0x332B, 0x1D}, + {0x332C, 0x1D}, + {0x332D, 0x04}, + {0x332E, 0x1E}, + {0x332F, 0x1F}, + {0x32f6, 0x0B}, + {0x3343, 0xE0}, + {0x333B, 0x10}, + {0x333C, 0x14}, + {0x333D, 0x30}, + {0x333E, 0x30}, + {0x333F, 0x88}, + {0x3340, 0x84}, + {0x3341, 0x50}, + {0x3342, 0x50}, + {0x3344, 0x20}, + {0x3345, 0x28}, + {0x3346, 0x3F}, + {0x3347, 0x3F}, + {0x3348, 0xF0}, + {0x3349, 0x40}, + {0x334A, 0x40}, + {0x334B, 0x20}, + {0x334C, 0x20}, + {0x334D, 0x00}, + {0x32f6, 0x0B}, + {0x32f9, 0x63}, + {0x32fA, 0x36}, + {0x3338, 0x18}, + {0x3339, 0xC6}, + {0x333A, 0x6C}, + {0x3109, 0x82}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0x3200, 0x3e}, + {0x3201, 0x0f}, + {0x3028, 0x07}, + {0x3029, 0x00}, + {0x302a, 0x04}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04}, + {0x3004, 0x00}, + {0x3005, 0x04}, + {0x3006, 0x06}, + {0x3007, 0x43}, + {0x3008, 0x04}, + {0x3009, 0xb3}, + {0x300a, 0x09}, + {0x300b, 0xc4}, + {0x300c, 0x07}, + {0x300d, 0x80}, + {0x300e, 0x06}, + {0x300f, 0x40}, + {0x3010, 0x04}, + {0x3011, 0xb0}, + {0x3052, 0x10}, + {0x32bb, 0x1b}, + {0x32bc, 0x40}, + {0x32c1, 0x27}, + {0x32c2, 0x80}, + {0x32c8, 0x60}, + {0x32c9, 0x50}, + {0x32c4, 0x00}, + {0x3201, 0x3f}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + {0x3200, 0x3e}, + {0x3201, 0x0f}, + {0x3028, 0x07}, + {0x3029, 0x00}, + {0x302a, 0x04}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04}, + {0x3004, 0x00}, + {0x3005, 0x04}, + {0x3006, 0x06}, + {0x3007, 0x43}, + {0x3008, 0x04}, + {0x3009, 0xb3}, + {0x300a, 0x08}, + {0x300b, 0x34}, + {0x300c, 0x04}, + {0x300d, 0xbd}, + {0x300e, 0x06}, + {0x300f, 0x40}, + {0x3010, 0x04}, + {0x3011, 0xb0}, + {0x3052, 0x10}, + {0x32bb, 0x1b}, + {0x32bc, 0x40}, + {0x32c1, 0x24}, + {0x32c2, 0x74}, + {0x32c8, 0x72}, + {0x32c9, 0x5f}, + {0x32c4, 0x00}, + {0x3201, 0x3f}, + {0x3021, 0x16}, + {0x3060, 0x01}, + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + {0x32e0, 0x03}, + {0x32e1, 0x20}, + {0x32e2, 0x02}, + {0x32e3, 0x58}, + {0x32e4, 0x01}, + {0x32e5, 0x00}, + {0x32e6, 0x00}, + {0x32e7, 0x00}, + {0x3200, 0x3e}, + {0x3201, 0x0f}, + {0x3028, 0x07}, + {0x3029, 0x00}, + {0x302a, 0x04}, + {0x3022, 0x24}, + {0x3023, 0x64}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04}, + {0x3004, 0x00}, + {0x3005, 0x04}, + {0x3006, 0x06}, + {0x3007, 0x43}, + {0x3008, 0x04}, + {0x3009, 0xb3}, + {0x300a, 0x09}, + {0x300b, 0xc4}, + {0x300c, 0x02}, + {0x300d, 0x80}, + {0x300e, 0x06}, + {0x300f, 0x40}, + {0x3010, 0x02}, + {0x3011, 0x58}, + {0x3052, 0x10}, + {0x32bb, 0x1b}, + {0x32bc, 0x40}, + {0x32c1, 0x22}, + {0x32c2, 0xa0}, + {0x32c8, 0x60}, + {0x32c9, 0x50}, + {0x32c4, 0x00}, + {0x3201, 0x7f}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + {0x3200, 0x3e}, + {0x3201, 0x0f}, + {0x3028, 0x07}, + {0x3029, 0x00}, + {0x302a, 0x04}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0xa4}, + {0x3004, 0x00}, + {0x3005, 0xf4}, + {0x3006, 0x05}, + {0x3007, 0xa3}, + {0x3008, 0x03}, + {0x3009, 0xc3}, + {0x300a, 0x06}, + {0x300b, 0xf4}, + {0x300c, 0x03}, + {0x300d, 0x82}, + {0x300e, 0x05}, + {0x300f, 0x00}, + {0x3010, 0x02}, + {0x3011, 0xd0}, + {0x3052, 0x10}, + {0x32bb, 0x1b}, + {0x32bc, 0x40}, + {0x32c1, 0x23}, + {0x32c2, 0xaa}, + {0x32c8, 0x86}, + {0x32c9, 0x70}, + {0x32c4, 0x00}, + {0x3201, 0x3f}, + {0x3021, 0x16}, + {0x3060, 0x01}, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0x3021,0x61), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x3000,0), + SensorRegVal(0x3001,0), + 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[]= +{ + {0x3201, 0x7F}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + //[WB-CLOUDY] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x51}, + {0x3296, 0x01}, + {0x3297, 0x00}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //[WB-DAYLIGHT] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0xD8}, + {0x3296, 0x01}, + {0x3297, 0x58}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //[WB-INCANDESCENCE] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x30}, + {0x3296, 0x01}, + {0x3297, 0xCB}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //[WB-FLUORESCENT] + {0x3201, 0x6F}, + {0x3290, 0x02}, + {0x3291, 0x00}, + {0x3296, 0x02}, + {0x3297, 0x00}, + SensorEnd +}; +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]= +{ + //[WB-TUNGSTEN] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x00}, + {0x3296, 0x02}, + {0x3297, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy, sensor_WhiteB_TungstenLamp3,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[] = +{ + {0x32F1, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + //[SE-GrayScale] + {0x32F1, 0x01}, +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + //[SE-SEPIA] + {0x32F1, 0x02}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Inverse[] = +{ + //[SE-Inverse] + {0x32F1, 0x03}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + //[SE-SEPIABlue] + {0x32F1, 0x05}, + {0x32F4, 0xF0}, + {0x32F5, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + //[SE-SEPIAGreen] + {0x32F1, 0x05}, + {0x32F4, 0x60}, + {0x32F5, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Solarization[] = +{ + + //[SE-Solarization] + {0x32F1, 0x04}, + SensorEnd +}; + + +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Solarization,NULL, +}; + +static struct rk_sensor_reg sensor_Exposure04[]= +{ + //[EV-4] + {0x32F6, 0X0C}, + {0x32F2, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure03[]= +{ + //[EV-3] + {0x32F6, 0X0C}, + {0x32F2, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure02[]= +{ + //[EV-2] + {0x32F6, 0X0C}, + {0x32F2, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure01[]= +{ + //[EV-1] + {0x32F6, 0X0C}, + {0x32F2, 0x70}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure00[]= +{ + + //[EV+0] + {0x32F6, 0X0C}, + {0x32F2, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure11[]= +{ + //[EV+1] + {0x32F6, 0X0C}, + {0x32F2, 0x90}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure12[]= +{ + //[EV+2] + {0x32F6, 0X0C}, + {0x32F2, 0xA0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure13[]= +{ + //[EV+3] + {0x32F6, 0X0C}, + {0x32F2, 0xB0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure14[]= +{ + //[EV+4] + {0x32F6, 0X0C}, + {0x32F2, 0xC0}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00, + sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,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_Contrast04[]= +{ + //[Contrast : -4] + {0x32F6, 0x0C}, + {0x32C2, 0x40}, + {0x32F2, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast03[]= +{ + //[Contrast : -3] + {0x32F6, 0x0C}, + {0x32C2, 0x30}, + {0x32F2, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast02[]= +{ + //[Contrast : -2] + {0x32F6, 0x0C}, + {0x32C2, 0x20}, + {0x32F2, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast01[]= +{ + //[Contrast : -1] + {0x32F6, 0x0C}, + {0x32C2, 0x10}, + {0x32F2, 0x70}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast00[]= +{ + //[Contrast : 0] + {0x32F6, 0x0C}, + {0x32C2, 0x00}, + {0x32F2, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast11[]= +{ + //[Contrast : +1] + {0x32F6, 0x0C}, + {0x32C2, 0xF0}, + {0x32F2, 0x90}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast12[]= +{ + //[Contrast : +2] + {0x32F6, 0x0C}, + {0x32C2, 0xE0}, + {0x32F2, 0xA0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast13[]= +{ + //[Contrast : +3] + {0x32F6, 0x0C}, + {0x32C2, 0xD0}, + {0x32F2, 0xB0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast14[]= +{ + //[Contrast : +4] + {0x32F6, 0x0C}, + {0x32C2, 0xC0}, + {0x32F2, 0xC0}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01, + sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,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), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",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,"posterize",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",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, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe), + new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe), +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +static int sensor_parameter_record(struct i2c_client *client) +{ + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + + sensor_read(client, 0x3200, &ret_l); + sensor_write(client, 0x3200, ret_l&0xf9); + sensor_read(client, 0x3201, &ret_l); + sensor_write(client, 0x3201, ret_l&0xcf); //stop ae awb + + //read back ae + sensor_read(client,0x3012,&ret_h); + sensor_read(client,0x3013, &ret_l); + tp_l = ret_l; + tp_h = ret_h; + spsensor->parameter.preview_exposure = ((tp_h<<8) & 0xF0) |((tp_l) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x3014, &ret_l); + spsensor->parameter.preview_gain_dr = ret_l; + sensor_read(client,0x3015, &ret_l); + spsensor->parameter.preview_gain_ar = ret_l; + sensor_read(client,0x3016, &ret_l); + spsensor->parameter.preview_gain_dgr = ret_l; + sensor_read(client,0x3017, &ret_l); + spsensor->parameter.preview_gain_agr = ret_l; + sensor_read(client,0x3018, &ret_l); + spsensor->parameter.preview_gain_dgb = ret_l; + sensor_read(client,0x3019, &ret_l); + spsensor->parameter.preview_gain_agb = ret_l; + sensor_read(client,0x301a, &ret_l); + spsensor->parameter.preview_gain_db = ret_l; + sensor_read(client,0x301b, &ret_l); + spsensor->parameter.preview_gain_ab = ret_l; + sensor_read(client,0x301c, &ret_l); + spsensor->parameter.preview_gain_dglobal= ret_l; + sensor_read(client,0x301d, &ret_l); + spsensor->parameter.preview_gain_aglobal= ret_l; + + spsensor->parameter.CapturePclk = 48000; + spsensor->parameter.PreviewPclk = 48000; + sensor_read(client,0x300a, &ret_h); + sensor_read(client,0x300b, &ret_l); + tp_l = ret_l; + tp_h = ret_h; + spsensor->parameter.PreviewDummyPixels = (tp_l&0x0F) | ((tp_h<<8)&0xF0); + spsensor->parameter.CaptureDummyPixels = 0; + + #if 0 + sensor_read(client,0x3290, &ret_h); + sensor_read(client,0x3291, &ret_l); + tp_l = ret_l; + tp_h = ret_h; + spsensor->parameter.preview_awb_r = (tp_l&0x0F) | ((tp_h<<8)&0x10); + + sensor_read(client,0x3296, &ret_h); + sensor_read(client,0x3297, &ret_l); + tp_l = ret_l; + tp_h = ret_h; + spsensor->parameter.preview_awb_b = (tp_l&0x0F) | ((tp_h<<8)&0x10); + #endif + return 0; +} +#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode +#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode +#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode +#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode + +/* SENSOR EXPOSURE LINE LIMITATION */ +#define OV2659_FULL_EXPOSURE_LIMITATION (1236) +#define OV2659_PV_EXPOSURE_LIMITATION (618) + +// SENSOR UXGA SIZE +#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600) +#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200) + +#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16) +#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12) + +static int sensor_ae_transfer(struct i2c_client *client) +{ + unsigned int prev_line_len,cap_line_len,shutter; + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + int preview_ae_integration, capture_ae_integration; + int capture_pixel; + u8 ret_h,ret_l; + int val_h, val_l; + + mdelay(100); + + sensor_read(client, 0x3200, &ret_h); + val_h=ret_h; + sensor_write(client, 0x3200, ret_h&0xfd); + sensor_read(client, 0x3201, &ret_l); + val_l=ret_l; + sensor_write(client, 0x3201, ret_l&0xdf); //stop ae awb + + sensor_read(client,0x300a, &ret_h); + sensor_read(client,0x300b, &ret_l); + capture_pixel = (ret_l&0x0F) | ((ret_h<<8)&0xF0); + preview_ae_integration = spsensor->parameter.preview_exposure*spsensor->parameter.PreviewDummyPixels; + capture_ae_integration = preview_ae_integration/capture_pixel; + + //write back ae + sensor_write(client,0x3012,(capture_ae_integration>>8)&0x0F); + sensor_write(client,0x3013,capture_ae_integration&0x0F); + + //write back AGC Gain for preview + sensor_write(client,0x3014, spsensor->parameter.preview_gain_dr); + sensor_write(client,0x3015, spsensor->parameter.preview_gain_ar); + sensor_write(client,0x3016, spsensor->parameter.preview_gain_dgr); + sensor_write(client,0x3017, spsensor->parameter.preview_gain_agr); + sensor_write(client,0x3018, spsensor->parameter.preview_gain_dgb); + sensor_write(client,0x3019, spsensor->parameter.preview_gain_agb); + sensor_write(client,0x301a, spsensor->parameter.preview_gain_db); + sensor_write(client,0x301b, spsensor->parameter.preview_gain_ab); + sensor_write(client,0x301c, spsensor->parameter.preview_gain_dglobal); + sensor_write(client,0x301d, spsensor->parameter.preview_gain_aglobal); + + #if 0 + sensor_write(client,0x3290, (spsensor->parameter.preview_awb_r>>8)&0x01); + sensor_write(client,0x3291, spsensor->parameter.preview_awb_r&0x0F); + sensor_write(client,0x3296, (spsensor->parameter.preview_awb_b>>8)&0x01 ); + sensor_write(client,0x3297, spsensor->parameter.preview_awb_b&0x0F ); + #endif + + //sensor_write(client, 0x3200, val_h); + //sensor_write(client, 0x3201, val_l); //enable ae awb + return 0; +} +/* +********************************************************** +* 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) +{ + u8 reg_val; + + SENSOR_DG("%s",__FUNCTION__); + + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + u8 reg_val; + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;; + } + + 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) +{ + printk("set fmt set!!!!!!!!!!!!"); + + if (capture) { + sensor_parameter_record(client); + printk("set fmt set!!!!!!!!!!!!"); + } + + + return 0; +} +/* +* 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) +{ + u8 val; + + if (capture) { + sensor_ae_transfer(client); + printk("set fmt set!!!!!!!!!!!!"); + } + + + 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x02; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfd; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x01; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfe; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} + +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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/nt99252_3way.c b/drivers/media/video/nt99252_3way.c new file mode 100755 index 000000000000..7c0b9f5be004 --- /dev/null +++ b/drivers/media/video/nt99252_3way.c @@ -0,0 +1,1177 @@ + +#include "generic_sensor.h" + +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + +static int debug =1; +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_SENSOR_NT99252 +#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99252 +#define SENSOR_ID 0x2520 +#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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 5000 // 7.5fps +#define SENSOR_FULLRES_H_FPS 10000 // 7.5fps +#define SENSOR_720P_FPS 1 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0x302A, 0x00}, + {0x301F, 0x80}, + {0x303f, 0x0e}, + {0x3051, 0xE8}, + {0x320A, 0x00}, + {0x302E, 0x01}, + {0x3069, 0x04}, + {0x306a, 0x04}, + {0x3101, 0x80}, + {0x3104, 0x03}, + {0x3105, 0x03}, + {0x3106, 0x0D}, + {0x310A, 0x62}, + {0x310D, 0x60}, + {0x3111, 0x5B}, + {0x3131, 0x58}, + {0x3127, 0x01}, + {0x3210, 0x1E}, + {0x3211, 0x1E}, + {0x3212, 0x1E}, + {0x3213, 0x1E}, + {0x3214, 0x17}, + {0x3215, 0x17}, + {0x3216, 0x17}, + {0x3217, 0x17}, + {0x3218, 0x17}, + {0x3219, 0x17}, + {0x321A, 0x17}, + {0x321B, 0x17}, + {0x321C, 0x0F}, + {0x321D, 0x10}, + {0x321E, 0x0F}, + {0x321F, 0x0F}, + {0x3230, 0x00}, + {0x3231, 0x00}, + {0x3232, 0x00}, + {0x3233, 0x00}, + {0x3234, 0x00}, + {0x3235, 0x00}, + {0x3236, 0x00}, + {0x3237, 0x08}, + {0x3238, 0x20}, + {0x3239, 0x20}, + {0x323A, 0x20}, + {0x3243, 0xC3}, + {0x3244, 0x00}, + {0x3245, 0x00}, + {0x3302, 0x00}, + {0x3303, 0x54}, + {0x3304, 0x00}, + {0x3305, 0x91}, + {0x3306, 0x00}, + {0x3307, 0x1A}, + {0x3308, 0x07}, + {0x3309, 0xCD}, + {0x330A, 0x07}, + {0x330B, 0x51}, + {0x330C, 0x00}, + {0x330D, 0xE3}, + {0x330E, 0x00}, + {0x330F, 0xC6}, + {0x3310, 0x07}, + {0x3311, 0x4A}, + {0x3312, 0x07}, + {0x3313, 0xF1}, + {0x3270, 0x00}, + {0x3271, 0x0B}, + {0x3272, 0x16}, + {0x3273, 0x2B}, + {0x3274, 0x3F}, + {0x3275, 0x51}, + {0x3276, 0x72}, + {0x3277, 0x8F}, + {0x3278, 0xA7}, + {0x3279, 0xBC}, + {0x327A, 0xDC}, + {0x327B, 0xF0}, + {0x327C, 0xFA}, + {0x327D, 0xFE}, + {0x327E, 0xFF}, + {0x3327, 0x00}, + {0x3326, 0x1F}, + {0x3360, 0x08}, + {0x3361, 0x0E}, + {0x3362, 0x14}, + {0x3363, 0xB3}, + {0x3331, 0x0C}, + {0x3332, 0x60}, + {0x3365, 0x10}, + {0x3366, 0x10}, + {0x3368, 0x08}, + {0x3369, 0x08}, + {0x336A, 0x06}, + {0x336B, 0x00}, + {0x336d, 0x14}, + {0x336e, 0x14}, + {0x336f, 0x00}, + {0x3370, 0x00}, + {0x3379, 0x0A}, + {0x337A, 0x0A}, + {0x337B, 0x0A}, + {0x337C, 0x0A}, + {0x3371, 0x38}, + {0x3372, 0x38}, + {0x3373, 0x3F}, + {0x3374, 0x3F}, + {0x33A2, 0x00}, + {0x33A3, 0x30}, + {0x33A4, 0x01}, + {0x33c0, 0x03}, + {0x33c9, 0xCF}, + {0x33ca, 0x36}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x84}, + {0x32C1, 0x84}, + {0x32C2, 0x84}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x10}, + {0x32C6, 0x18}, + {0x32C7, 0x00}, + {0x32C8, 0x7E}, + {0x32C9, 0x84}, + {0x32CA, 0x94}, + {0x32CB, 0x94}, + {0x32CC, 0x9C}, + {0x32CD, 0x9C}, + {0x32DB, 0x6F}, + {0x3241, 0x89}, + {0x33A0, 0xAF}, + {0x33A1, 0x64}, + {0x3200, 0x3E}, + {0x3201, 0x3F}, + {0x302A, 0x00}, + {0x302C, 0x0C}, + {0x302C, 0x0B}, + {0x302D, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04}, + {0x3004, 0x00}, + {0x3005, 0x04}, + {0x3006, 0x06}, + {0x3007, 0x43}, + {0x3008, 0x04}, + {0x3009, 0xCC}, + {0x300A, 0x07}, + {0x300B, 0x6C}, + {0x300C, 0x09}, + {0x300D, 0xDE}, + {0x300E, 0x06}, + {0x300F, 0x40}, + {0x3010, 0x04}, + {0x3011, 0xB0}, + {0x32BB, 0x87}, + {0x32B8, 0x36}, + {0x32B9, 0x2A}, + {0x32BC, 0x30}, + {0x32BD, 0x33}, + {0x32BE, 0x2D}, + {0x325C, 0x03}, + {0x320A, 0x00}, + {0x3021, 0x06}, + {0x334A, 0x34}, + {0x334B, 0x14}, + {0x334C, 0x10}, + {0x3060, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x74}, + {0x32C1, 0x74}, + {0x32C2, 0x74}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x10}, + {0x32C6, 0x18}, + {0x32C7, 0x00}, + {0x32C8, 0x7E}, + {0x32C9, 0x74}, + {0x32CA, 0x84}, + {0x32CB, 0x84}, + {0x32CC, 0x8C}, + {0x32CD, 0x8C}, + {0x32DB, 0x6F}, + {0x3241, 0x81}, + {0x33A0, 0xAF}, + {0x33A1, 0x54}, + {0x3200, 0x3E}, + {0x3201, 0x3F}, + {0x302A, 0x00}, + {0x302C, 0x0C}, + {0x302C, 0x0B}, + {0x302D, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0x04}, + {0x3004, 0x00}, + {0x3005, 0x04}, + {0x3006, 0x06}, + {0x3007, 0x43}, + {0x3008, 0x04}, + {0x3009, 0xCC}, + {0x300A, 0x07}, + {0x300B, 0x6C}, + {0x300C, 0x04}, + {0x300D, 0xEF}, + {0x300E, 0x06}, + {0x300F, 0x40}, + {0x3010, 0x04}, + {0x3011, 0xB0}, + {0x32BB, 0x87}, + {0x32B8, 0x36}, + {0x32B9, 0x2A}, + {0x32BC, 0x30}, + {0x32BD, 0x33}, + {0x32BE, 0x2D}, + {0x325C, 0x03}, + {0x320A, 0x00}, + {0x3021, 0x06}, + {0x334A, 0x34}, + {0x334B, 0x14}, + {0x334C, 0x10}, + {0x3060, 0x01}, + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0xB9}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x77}, + {0x3241, 0x80}, + {0x33A0, 0xB7}, + {0x33A1, 0x4A}, + {0x32E0, 0x03}, + {0x32E1, 0x20}, + {0x32E2, 0x02}, + {0x32E3, 0x58}, + {0x32E4, 0x00}, + {0x32E5, 0x00}, + {0x32E6, 0x00}, + {0x32E7, 0x00}, + {0x3200, 0x3E}, + {0x3201, 0x7F}, + {0x302A, 0x00}, + {0x302C, 0x0C}, + {0x302C, 0x0B}, + {0x302D, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x6E}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x06}, + {0x3007, 0x43},//x_end=1603 + {0x3008, 0x04}, + {0x3009, 0xCC},//y_end=1228 + {0x300A, 0x05}, + {0x300B, 0x14},//pixel=1300 + {0x300C, 0x02}, + {0x300D, 0x67},//line=615 + {0x300E, 0x03}, + {0x300F, 0x20},//x_width=800 + {0x3010, 0x02}, + {0x3011, 0x58},//y_width=600 + {0x32BB, 0x87}, + {0x32B8, 0x36}, + {0x32B9, 0x2A}, + {0x32BC, 0x30}, + {0x32BD, 0x33}, + {0x32BE, 0x2D}, + {0x325C, 0x02}, + {0x320A, 0x00}, + {0x3021, 0x06}, + {0x334A, 0x00}, + {0x334B, 0x7F}, + {0x334C, 0x1F}, + {0x3060, 0x01}, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x98}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x73}, + {0x3241, 0x7E}, + {0x33A0, 0xB3}, + {0x33A1, 0x4A}, + {0x3200, 0x3E}, + {0x3201, 0x3F}, + {0x302A, 0x00}, + {0x302C, 0x0C}, + {0x302C, 0x0B}, + {0x302D, 0x02}, + {0x3022, 0x24}, + {0x3023, 0x24}, + {0x3002, 0x00}, + {0x3003, 0xA4}, + {0x3004, 0x00}, + {0x3005, 0xF4}, + {0x3006, 0x05}, + {0x3007, 0xA3}, + {0x3008, 0x04}, + {0x3009, 0xCC}, + {0x300A, 0x06}, + {0x300B, 0x2C}, + {0x300C, 0x02}, + {0x300D, 0xDC}, + {0x300E, 0x05}, + {0x300F, 0x00}, + {0x3010, 0x02}, + {0x3011, 0xD0}, + {0x32BB, 0x87}, + {0x32B8, 0x36}, + {0x32B9, 0x2A}, + {0x32BC, 0x30}, + {0x32BD, 0x33}, + {0x32BE, 0x2D}, + {0x325C, 0x03}, + {0x320A, 0x00}, + {0x3021, 0x06}, + {0x334A, 0x00}, + {0x334B, 0x7F}, + {0x334C, 0x1F}, + {0x3060, 0x01}, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0x3021,0x61), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x3000,0), + SensorRegVal(0x3001,0), + 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[]= +{ + //[WB-AUTO] + {0x3201, 0x7F}, //AWB auto, bit[4]:1,auto + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + //[WB-CLOUDY] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x51}, + {0x3296, 0x01}, + {0x3297, 0x00}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //[WB-DAYLIGHT] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x38}, + {0x3296, 0x01}, + {0x3297, 0x68}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //[WB-INCANDESCENCE] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x30}, + {0x3296, 0x01}, + {0x3297, 0xCB}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //[WB-FLUORESCENT] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x70}, + {0x3296, 0x01}, + {0x3297, 0xFF}, + SensorEnd +}; +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]= +{ + //[WB-TUNGSTEN] + {0x3201, 0x6F}, + {0x3290, 0x01}, + {0x3291, 0x00}, + {0x3296, 0x02}, + {0x3297, 0x30}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy, sensor_WhiteB_TungstenLamp3, 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[] = +{ + {0x32f1, 0x00}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + //[SE-GrayScale] + {0x32f1, 0x01}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + //[SE-SEPIA] + {0x32f1, 0x02}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //[SE-Inverse] + {0x32f1, 0x03}, + {0x32f8, 0x01}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + //[SE-SEPIABlue] + {0x32f1, 0x05}, + {0x32f4, 0xf0}, + {0x32f5, 0x80}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + //[SE-SEPIAGreen] + {0x32f1, 0x05}, + {0x32f4, 0x60}, + {0x32f5, 0x20}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Solarization[] = +{ + //[SE-Solarization] + {0x32f1, 0x04}, + {0x32f8, 0x01}, + 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, sensor_Effect_Solarization, NULL, +}; + +static struct rk_sensor_reg sensor_Exposure04[]= +{ + //[EV-4] + {0x32F2, 0x40}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure03[]= +{ + //[EV-3] + {0x32F2, 0x50}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure02[]= +{ + //[EV-2] + {0x32F2, 0x60}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure01[]= +{ + //[EV-1] + {0x32F2, 0x70}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure00[]= +{ + //[EV+0] + {0x32F2, 0x80}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure11[]= +{ + //[EV+1] + {0x32F2, 0x90}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure12[]= +{ + //[EV+2] + {0x32F2, 0xA0}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure13[]= +{ + //[EV+3] + {0x32F2, 0xB0}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure14[]= +{ + //[EV+4] + {0x32F2, 0xC0}, + {0x32F8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00, + sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,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_Contrast04[]= +{ + //[Contrast : -4] + {0x32FC, 0x40}, + {0x32F2, 0x40}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast03[]= +{ + //[Contrast : -3] + {0x32FC, 0x30}, + {0x32F2, 0x50}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast02[]= +{ + //[Contrast : -2] + {0x32FC, 0x20}, + {0x32F2, 0x60}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast01[]= +{ + //[Contrast : -1] + {0x32FC, 0x10}, + {0x32F2, 0x70}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast00[]= +{ + //[Contrast : 0] + {0x32FC, 0x00}, + {0x32F2, 0x80}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast11[]= +{ + //[Contrast : +1] + {0x32FC, 0xF0}, + {0x32F2, 0x90}, + {0x32f8, 0x01}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast12[]= +{ + //[Contrast : +2] + {0x32FC, 0xE0}, + {0x32F2, 0xA0}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast13[]= +{ + //[Contrast : +3] + {0x32FC, 0xD0}, + {0x32F2, 0xB0}, + {0x32f8, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast14[]= +{ + //[Contrast : +4] + {0x32FC, 0xC0}, + {0x32F2, 0xC0}, + {0x32f8, 0x01}, + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01, + sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,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), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",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,"posterize",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",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, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe), + new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe), +}; + +//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}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +static int sensor_parameter_record(struct i2c_client *client) +{ + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + + sensor_read(client,0x3a00, &ret_l); + sensor_write(client,0x3a00, ret_l&0xfb); + + sensor_write(client,0x3503,0x07); //stop AE/AG + + sensor_read(client,0x3500,&ret_h); + sensor_read(client,0x3501, &ret_m); + sensor_read(client,0x3502, &ret_l); + tp_l = ret_l; + tp_m = ret_m; + tp_h = ret_h; + spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x350b, &ret_l); + spsensor->parameter.preview_gain = ret_l; + + spsensor->parameter.CapturePclk = 24000; + spsensor->parameter.PreviewPclk = 24000; + spsensor->parameter.PreviewDummyPixels = 0; + spsensor->parameter.CaptureDummyPixels = 0; + SENSOR_DG("Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x", + ret_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l); + return 0; +} +#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode +#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode +#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode +#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode + +/* SENSOR EXPOSURE LINE LIMITATION */ +#define OV2659_FULL_EXPOSURE_LIMITATION (1236) +#define OV2659_PV_EXPOSURE_LIMITATION (618) + +// SENSOR UXGA SIZE +#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600) +#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200) + +#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16) +#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12) + +/* +********************************************************** +* 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) +{ + u8 reg_val; + + SENSOR_DG("%s",__FUNCTION__); + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + u8 reg_val; + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + } + 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) +{ + if (capture) { + //sensor_parameter_record(client); + } + + return 0; +} +/* +* 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) +{ + if (capture) { + //sensor_ae_transfer(client); + } + 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x02; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfd; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x01; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfe; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/nt99340_2way.c b/drivers/media/video/nt99340_2way.c new file mode 100755 index 000000000000..e88658322019 --- /dev/null +++ b/drivers/media/video/nt99340_2way.c @@ -0,0 +1,1183 @@ + +#include "generic_sensor.h" + +static int version = KERNEL_VERSION(0,1,0); +module_param(version, int, S_IRUGO); + +static int debug =1; +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_SENSOR_NT99340 +#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99340 +#define SENSOR_ID 0x3400 +#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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 5000 // 7.5fps +#define SENSOR_FULLRES_H_FPS 10000 // 7.5fps +#define SENSOR_720P_FPS 15000 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; +}; + +/* +* 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[] ={ + {0x32F0, 0x00}, + {0x32FF, 0x00}, + {0x303E, 0x0C}, + {0x303F, 0x02}, + {0x3040, 0xFF}, + {0x3041, 0x00}, + {0x3042, 0x00}, + {0x3051, 0xFC}, + {0x3052, 0x10}, + {0x3069, 0x03}, + {0x306a, 0x03}, + {0x3118, 0xA7}, + {0x3119, 0xA7}, + {0x311A, 0xA7}, + {0x3100, 0x03}, + {0x3101, 0x80}, + {0x3102, 0x09}, + {0x3103, 0x09}, + {0x3104, 0x01}, + {0x3105, 0x01}, + {0x3106, 0x03}, + {0x3107, 0x20}, + {0x3108, 0x00}, + {0x3109, 0x82}, + {0x310A, 0x04}, + {0x3030, 0x0A}, + {0x306C, 0x0C}, + {0x306D, 0x0C}, + {0x3583, 0x18}, + {0x3587, 0x02}, + {0x3584, 0x00}, + {0x3585, 0x00}, + {0x3580, 0xB2}, + {0x3600, 0x66}, + {0x3601, 0x99}, + {0x3604, 0x15}, + {0x3605, 0x13}, + {0x3614, 0x20}, + {0x361A, 0x10}, + {0x3615, 0x24}, + {0x3610, 0x02}, + {0x3290, 0x01}, + {0x3291, 0x80}, + {0x3296, 0x01}, + {0x3297, 0x60}, + {0x3250, 0x80}, + {0x3251, 0x01}, + {0x3252, 0x27}, + {0x3253, 0x9D}, + {0x3254, 0x00}, + {0x3255, 0xE3}, + {0x3256, 0x81}, + {0x3257, 0x70}, + {0x329B, 0x00}, + {0x32A1, 0x00}, + {0x32A2, 0xEC}, + {0x32A3, 0x01}, + {0x32A4, 0x7A}, + {0x32A5, 0x01}, + {0x32A6, 0x14}, + {0x32A7, 0x01}, + {0x32A8, 0xB3}, + {0x3270, 0x00}, + {0x3271, 0x0B}, + {0x3272, 0x16}, + {0x3273, 0x2B}, + {0x3274, 0x3F}, + {0x3275, 0x51}, + {0x3276, 0x72}, + {0x3277, 0x8F}, + {0x3278, 0xA7}, + {0x3279, 0xBC}, + {0x327A, 0xDC}, + {0x327B, 0xF0}, + {0x327C, 0xFA}, + {0x327D, 0xFE}, + {0x327E, 0xFF}, + {0x3302, 0x00}, + {0x3303, 0x4D}, + {0x3304, 0x00}, + {0x3305, 0x96}, + {0x3306, 0x00}, + {0x3307, 0x1D}, + {0x3308, 0x07}, + {0x3309, 0xC7}, + {0x330A, 0x07}, + {0x330B, 0x0A}, + {0x330C, 0x01}, + {0x330D, 0x30}, + {0x330E, 0x01}, + {0x330F, 0x07}, + {0x3310, 0x06}, + {0x3311, 0xFF}, + {0x3312, 0x07}, + {0x3313, 0xFA}, + {0x3210, 0x1E}, + {0x3211, 0x20}, + {0x3212, 0x20}, + {0x3213, 0x1E}, + {0x3214, 0x18}, + {0x3215, 0x1A}, + {0x3216, 0x1A}, + {0x3217, 0x18}, + {0x3218, 0x18}, + {0x3219, 0x1A}, + {0x321A, 0x1A}, + {0x321B, 0x18}, + {0x321C, 0x16}, + {0x321D, 0x1A}, + {0x321E, 0x17}, + {0x321F, 0x15}, + {0x3234, 0x0F}, + {0x3235, 0x0F}, + {0x3236, 0x0F}, + {0x3237, 0x0F}, + {0x3238, 0x40}, + {0x3239, 0x40}, + {0x323A, 0x40}, + {0x3241, 0x40}, + {0x3243, 0x41}, + {0x32F6, 0x0F}, + {0x32F9, 0x42}, + {0x32FA, 0x24}, + {0x3338, 0x18}, + {0x3339, 0xC6}, + {0x333A, 0x6C}, + {0x3335, 0x60}, + {0x3336, 0x20}, + {0x3337, 0x40}, + {0x333B, 0xC6}, + {0x333C, 0x6C}, + {0x3325, 0xAF}, + {0x3326, 0x02}, + {0x3327, 0x00}, + {0x3331, 0x08}, + {0x3332, 0xFF}, + {0x333F, 0x07}, + {0x334A, 0x34}, + {0x334B, 0x14}, + {0x334C, 0x10}, + {0x3363, 0x33}, + {0x3360, 0x08}, + {0x3361, 0x10}, + {0x3362, 0x18}, + {0x3364, 0x88}, + {0x3365, 0x80}, + {0x3366, 0x68}, + {0x3367, 0x40}, + {0x3368, 0x50}, + {0x3369, 0x40}, + {0x336A, 0x30}, + {0x336B, 0x20}, + {0x336C, 0x00}, + {0x336D, 0x1A}, + {0x336E, 0x16}, + {0x336F, 0x14}, + {0x3370, 0x0C}, + {0x3371, 0x3F}, + {0x3372, 0x3F}, + {0x3373, 0x3F}, + {0x3374, 0x3F}, + {0x3375, 0x0E}, + {0x3376, 0x10}, + {0x3377, 0x14}, + {0x3378, 0x20}, + {0x3012, 0x02}, + {0x3013, 0x58}, + {0x301D, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x84}, + {0x32C1, 0x84}, + {0x32C2, 0x84}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x9E}, + {0x32C9, 0x84}, + {0x32CA, 0xA4}, + {0x32CB, 0xA4}, + {0x32CC, 0xA4}, + {0x32CD, 0xA4}, + {0x32DB, 0x73}, + {0x32D0, 0x01}, + {0x3200, 0x3F}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302B, 0x01}, + {0x302C, 0x0F}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x24}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x08}, + {0x3007, 0x03},//x_end=2051 + {0x3008, 0x06}, + {0x3009, 0x03},//y_end=1539 + {0x300A, 0x0B}, + {0x300B, 0xD0},//pixel=3024 + {0x300C, 0x0C}, + {0x300D, 0x66},//line=3174 + {0x300E, 0x08}, + {0x300F, 0x00},//x=2048 + {0x3010, 0x06}, + {0x3011, 0x00},//y=1536 + {0x3052, 0x10}, + {0x32BB, 0x87}, + {0x32B8, 0x3B}, + {0x32B9, 0x2D}, + {0x32BC, 0x34}, + {0x32BD, 0x38}, + {0x32BE, 0x30}, + {0x3201, 0xBF}, + {0x3109, 0x82}, + {0x3530, 0xC0}, + {0x320A, 0x42}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + {0x32BF, 0x60}, + {0x32C0, 0x74}, + {0x32C1, 0x74}, + {0x32C2, 0x74}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0x9E}, + {0x32C9, 0x74}, + {0x32CA, 0x94}, + {0x32CB, 0x94}, + {0x32CC, 0x94}, + {0x32CD, 0x94}, + {0x32DB, 0x73}, + {0x32D0, 0x01}, + {0x3200, 0x3F}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302B, 0x01}, + {0x302C, 0x0F}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x24}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x08}, + {0x3007, 0x03},//x_end=2051 + {0x3008, 0x06}, + {0x3009, 0x03},//y_end=1539 + {0x300A, 0x0B}, + {0x300B, 0xD0},//pixel=3024 + {0x300C, 0x06}, + {0x300D, 0x33},//line=1587 + {0x300E, 0x08}, + {0x300F, 0x00},//x=2048 + {0x3010, 0x06}, + {0x3011, 0x00},//y=1536 + {0x3052, 0x10}, + {0x32BB, 0x87}, + {0x32B8, 0x3B}, + {0x32B9, 0x2D}, + {0x32BC, 0x34}, + {0x32BD, 0x38}, + {0x32BE, 0x30}, + {0x3201, 0xBF}, + {0x3109, 0x82}, + {0x3530, 0xC0}, + {0x320A, 0x42}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x00}, + {0x32C8, 0xF0}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x7E}, + {0x32D0, 0x01}, + {0x32E0, 0x03}, + {0x32E1, 0x20}, + {0x32E2, 0x02}, + {0x32E3, 0x58}, + {0x32E4, 0x00}, + {0x32E5, 0x48}, + {0x32E6, 0x00}, + {0x32E7, 0x48}, + {0x3200, 0x3F}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302B, 0x01}, + {0x302C, 0x0F}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x6E}, + {0x3128, 0x01}, + {0x3002, 0x00}, + {0x3003, 0x04},//x_start=4 + {0x3004, 0x00}, + {0x3005, 0x04},//y_start=4 + {0x3006, 0x08}, + {0x3007, 0x03},//x_end=2051 + {0x3008, 0x06}, + {0x3009, 0x03},//y_end=1539 + {0x300A, 0x07}, + {0x300B, 0xD0},//pixel=2000 + {0x300C, 0x03}, + {0x300D, 0x20},//line=800 + {0x300E, 0x04}, + {0x300F, 0x00},//x=1024 + {0x3010, 0x03}, + {0x3011, 0x00},//y=768 + {0x3052, 0x10}, + {0x32BB, 0x87}, + {0x32B8, 0x3B}, + {0x32B9, 0x2D}, + {0x32BC, 0x34}, + {0x32BD, 0x38}, + {0x32BE, 0x30}, + {0x3201, 0xFF}, + {0x3109, 0x82}, + {0x3530, 0xC0}, + {0x320A, 0x42}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + {0x32BF, 0x60}, + {0x32C0, 0x6A}, + {0x32C1, 0x6A}, + {0x32C2, 0x6A}, + {0x32C3, 0x00}, + {0x32C4, 0x20}, + {0x32C5, 0x20}, + {0x32C6, 0x20}, + {0x32C7, 0x40}, + {0x32C8, 0x08}, + {0x32C9, 0x6A}, + {0x32CA, 0x8A}, + {0x32CB, 0x8A}, + {0x32CC, 0x8A}, + {0x32CD, 0x8A}, + {0x32DB, 0x80}, + {0x32D0, 0x01}, + {0x32E0, 0x05}, + {0x32E1, 0x00}, + {0x32E2, 0x02}, + {0x32E3, 0xD0}, + {0x32E4, 0x00}, + {0x32E5, 0x28}, + {0x32E6, 0x00}, + {0x32E7, 0x28}, + {0x3200, 0x3F}, + {0x3201, 0x0F}, + {0x302A, 0x00}, + {0x302B, 0x01}, + {0x302C, 0x0F}, + {0x302D, 0x00}, + {0x302E, 0x00}, + {0x302F, 0x02}, + {0x3022, 0x27}, + {0x3023, 0x24}, + {0x3128, 0x00}, + {0x3002, 0x01}, + {0x3003, 0x20},//x_start=288 + {0x3004, 0x01}, + {0x3005, 0x64},//y_start = 356 + {0x3006, 0x06}, + {0x3007, 0xE7},//x_end = 1767 + {0x3008, 0x04}, + {0x3009, 0xA3},//y_end=1187 + {0x300A, 0x07}, + {0x300B, 0x14},//pixel=1812 + {0x300C, 0x03}, + {0x300D, 0x73},//line=883 + {0x300E, 0x05}, + {0x300F, 0xC8},//x=1480 + {0x3010, 0x03}, + {0x3011, 0x40},//y=832 + {0x3052, 0x10}, + {0x32BB, 0x87}, + {0x32B8, 0x3B}, + {0x32B9, 0x2D}, + {0x32BC, 0x34}, + {0x32BD, 0x38}, + {0x32BE, 0x30}, + {0x3201, 0xFF}, + {0x3109, 0x82}, + {0x3530, 0xC0}, + {0x320A, 0x42}, + {0x3021, 0x06}, + {0x3060, 0x01}, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0x3021,0x61), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x3000,0), + SensorRegVal(0x3001,0), + 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[]= +{ + //[WB-AUTO] + {0x3201, 0xFF}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + //[WB-CLOUDY] + {0x3201, 0xEF}, + {0x3290, 0x01}, + {0x3291, 0x51}, + {0x3296, 0x01}, + {0x3297, 0x00}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //[WB-DAYLIGHT] + {0x3201, 0xEF}, + {0x3290, 0x01}, + {0x3291, 0x38}, + {0x3296, 0x01}, + {0x3297, 0x68}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //[WB-INCANDESCENCE] + {0x3201, 0xEF}, + {0x3290, 0x01}, + {0x3291, 0x30}, + {0x3296, 0x01}, + {0x3297, 0xCB}, + SensorEnd +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //[WB-FLUORESCENT] + {0x3201, 0xEF}, + {0x3290, 0x01}, + {0x3291, 0x70}, + {0x3296, 0x01}, + {0x3297, 0xFF}, + SensorEnd +}; +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]= +{ + //[WB-TUNGSTEN] + {0x3201, 0xEF}, + {0x3290, 0x01}, + {0x3291, 0x00}, + {0x3296, 0x02}, + {0x3297, 0x30}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,sensor_WhiteB_TungstenLamp3,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[] = +{ + //[SE-Normal] + {0x32F1, 0x00}, + {0x32F4, 0x80}, + {0x32F5, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + //[SE-GrayScale] + {0x32F1, 0x01}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + //[SE-SEPIA] + {0x32F1, 0x02}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Inverse[] = +{ + //[SE-Inverse] + {0x32F1, 0x03}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + //[SE-SEPIABlue] + {0x32F1, 0x05}, + {0x32F4, 0xF0}, + {0x32F5, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + //[SE-SEPIAGreen] + {0x32F1, 0x05}, + {0x32F4, 0x60}, + {0x32F5, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Solarization[] = +{ + //[SE-Solarization] + {0x32F1, 0x04}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Solarization,NULL, +}; + +static struct rk_sensor_reg sensor_Exposure04[]= +{ + //[EV-4] + {0x32F2, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure03[]= +{ + //[EV-3] + {0x32F2, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure02[]= +{ + //[EV-2] + {0x32F2, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure01[]= +{ + //[EV-1] + {0x32F2, 0x70}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure00[]= +{ + //[EV+0] + {0x32F2, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure11[]= +{ + //[EV+1] + {0x32F2, 0x90}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure12[]= +{ + //[EV+2] + {0x32F2, 0xA0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure13[]= +{ + //[EV+3] + {0x32F2, 0xB0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure14[]= +{ + //[EV+4] + {0x32F2, 0xC0}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00, + sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,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_Contrast04[]= +{ + //[Contrast : -4] + {0x32C2, 0x40}, + {0x32F2, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast03[]= +{ + //[Contrast : -3] + {0x32C2, 0x30}, + {0x32F2, 0x50}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast02[]= +{ + //[Contrast : -2] + {0x32C2, 0x20}, + {0x32F2, 0x60}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast01[]= +{ + //[Contrast : -1] + {0x32C2, 0x10}, + {0x32F2, 0x70}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast00[]= +{ + //[Contrast : 0] + {0x32C2, 0x00}, + {0x32F2, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast11[]= +{ + //[Contrast : +1] + {0x32C2, 0xF0}, + {0x32F2, 0x90}, + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast12[]= +{ + //[Contrast : +2] + {0x32C2, 0xE0}, + {0x32F2, 0xA0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast13[]= +{ + //[Contrast : +3] + {0x32C2, 0xD0}, + {0x32F2, 0xB0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast14[]= +{ + //[Contrast : +4] + {0x32C2, 0xC0}, + {0x32F2, 0xC0}, + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01, + sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,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), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",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,"posterize",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",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, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe), + new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe), +}; + +//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}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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) +{ + u8 reg_val; + struct soc_camera_device *icd = client->dev.platform_data; + //generic_sensor_ioctrl(icd, Sensor_PowerDown, 0); + + SENSOR_DG("%s",__FUNCTION__); + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + u8 reg_val; + struct generic_sensor *sensor = to_generic_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + SENSOR_DG("%s",__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + } + + 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) +{ + if (capture) { + // sensor_parameter_record(client); + } + + return 0; +} +/* +* 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) +{ + if (capture) { + // sensor_ae_transfer(client); + } + 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x02; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfd; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val |= 0x01; + err = sensor_write(client, 0x3022, val); + } + } else { + err = sensor_read(client, 0x3022, &val); + if (err == 0) { + val &= 0xfe; + err = sensor_write(client, 0x3022, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} + +/* +AF call back +*/ +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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/ov2659.c b/drivers/media/video/ov2659.c index 9101c7a8eb2a..edd3d9f84a16 100755 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -1,3372 +1,1130 @@ + +#include "generic_sensor.h" /* -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_OV2659 -#define SENSOR_V4L2_IDENT V4L2_IDENT_OV2659 -#define SENSOR_ID 0x2656 -#define SENSOR_MIN_WIDTH 800 -#define SENSOR_MIN_HEIGHT 600 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT sensor_init_height -#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p -#define SENSOR_INIT_PIXFMT sensor_init_pixelcode -#define SENSOR_BUS_PARAM sensor_init_busparam - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 350000 /* 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 COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -struct reginfo -{ - u16 reg; - u8 val; -}; -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_OV2659_USER_DEFINED_SERIES -#include "ov2659_user_series.c" -#else -/* init 800*600 SVGA */ -static struct reginfo sensor_init_data[] = -{ - {0x3000, 0x0f}, - {0x3001, 0xff}, - {0x3002, 0xff}, - //{0x0100, 0x01}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array - {0x3633, 0x3d}, - {0x3620, 0x02}, - {0x3631, 0x11}, - {0x3612, 0x04}, - {0x3630, 0x20}, - {0x4702, 0x02}, - {0x370c, 0x34}, - {0x3004, 0x10}, - {0x3005, 0x18}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x06}, - {0x3805, 0x5f}, - {0x3806, 0x04}, - {0x3807, 0xb7}, - {0x3808, 0x03}, - {0x3809, 0x20}, - {0x380a, 0x02}, - {0x380b, 0x58}, - {0x380c, 0x05}, - {0x380d, 0x14}, - {0x380e, 0x02}, - {0x380f, 0x68}, - {0x3811, 0x08}, - {0x3813, 0x02}, - {0x3814, 0x31}, - {0x3815, 0x31}, - {0x3a02, 0x02}, - {0x3a03, 0x68}, - {0x3a08, 0x00}, - {0x3a09, 0x5c}, - {0x3a0a, 0x00}, - {0x3a0b, 0x4d}, - {0x3a0d, 0x08}, - {0x3a0e, 0x06}, - {0x3a14, 0x02}, - {0x3a15, 0x28}, - {0x4708, 0x01}, - {0x3623, 0x00}, - {0x3634, 0x76}, - {0x3701, 0x44}, - {0x3702, 0x18}, - {0x3703, 0x24}, - {0x3704, 0x24}, - {0x3705, 0x0c}, - {0x3820, 0x81}, - {0x3821, 0x01}, - {0x370a, 0x52}, - {0x4608, 0x00}, - {0x4609, 0x80}, - {0x4300, 0x32}, - {0x5086, 0x02}, - {0x5000, 0xfb}, - {0x5001, 0x1f}, - {0x5002, 0x00}, - {0x5025, 0x0e}, - {0x5026, 0x18}, - {0x5027, 0x34}, - {0x5028, 0x4c}, - {0x5029, 0x62}, - {0x502a, 0x74}, - {0x502b, 0x85}, - {0x502c, 0x92}, - {0x502d, 0x9e}, - {0x502e, 0xb2}, - {0x502f, 0xc0}, - {0x5030, 0xcc}, - {0x5031, 0xe0}, - {0x5032, 0xee}, - {0x5033, 0xf6}, - {0x5034, 0x11}, - {0x5070, 0x1c}, - {0x5071, 0x5b}, - {0x5072, 0x05}, - {0x5073, 0x20}, - {0x5074, 0x94}, - {0x5075, 0xb4}, - {0x5076, 0xb4}, - {0x5077, 0xaf}, - {0x5078, 0x05}, - {0x5079, 0x98}, - {0x507a, 0x21}, - {0x5035, 0x6a}, - {0x5036, 0x11}, - {0x5037, 0x92}, - {0x5038, 0x21}, - - {0x5039, 0xe1}, - {0x503a, 0x01}, - {0x503c, 0x05}, - {0x503d, 0x08}, - {0x503e, 0x08}, - {0x503f, 0x64}, - {0x5040, 0x58}, - {0x5041, 0x2a}, - {0x5042, 0xc5}, - {0x5043, 0x2e}, - {0x5044, 0x3a}, - {0x5045, 0x3c}, - {0x5046, 0x44}, - {0x5047, 0xf8}, - {0x5048, 0x08}, - {0x5049, 0x70}, - {0x504a, 0xf0}, - {0x504b, 0xf0}, - {0x500c, 0x03}, - {0x500d, 0x20}, - {0x500e, 0x02}, - {0x500f, 0x5c}, - {0x5010, 0x48}, - {0x5011, 0x00}, - {0x5012, 0x66}, - {0x5013, 0x03}, - {0x5014, 0x30}, - {0x5015, 0x02}, - {0x5016, 0x7c}, - {0x5017, 0x40}, - {0x5018, 0x00}, - {0x5019, 0x66}, - {0x501a, 0x03}, - {0x501b, 0x10}, - {0x501c, 0x02}, - {0x501d, 0x7c}, - {0x501e, 0x3a}, - {0x501f, 0x00}, - {0x5020, 0x66}, - {0x506e, 0x44}, - {0x5064, 0x08}, - {0x5065, 0x10}, - {0x5066, 0x12}, - {0x5067, 0x02}, - {0x506c, 0x08}, - {0x506d, 0x10}, - {0x506f, 0xa6}, - {0x5068, 0x08}, - - - {0x5069, 0x10}, - {0x506a, 0x04}, - {0x506b, 0x12}, - {0x507e, 0x40}, - {0x507f, 0x20}, - {0x507b, 0x02}, - {0x507a, 0x01}, - {0x5084, 0x0c}, - {0x5085, 0x3e}, - {0x5005, 0x80}, - {0x3a0f, 0x30}, - {0x3a10, 0x28}, - {0x3a1b, 0x32}, - {0x3a1e, 0x26}, - {0x3a11, 0x60}, - {0x3a1f, 0x14}, - {0x5060, 0x69}, - {0x5061, 0x7d}, - {0x5062, 0x7d}, - {0x5063, 0x69}, - {0x3004, 0x20}, - {0x0100, 0x01}, - - {0x0000, 0x00} -}; - -/* 1280x720 */ -static struct reginfo sensor_720p[]= -{ - {0x0103, 0x01 }, - {0x3000, 0x0f }, - {0x3001, 0xff }, - {0x3002, 0xff }, - //{0x0100, 0x01 }, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array - {0x3633, 0x3d }, - {0x3620, 0x02 }, - {0x3631, 0x11 }, - {0x3612, 0x04 }, - {0x3630, 0x20 }, - {0x4702, 0x02 }, - {0x370c, 0x34 }, - {0x3004, 0x10 }, - {0x3005, 0x24 }, - {0x3800, 0x00 }, - {0x3801, 0xa0 }, - {0x3802, 0x00 }, - {0x3803, 0xf0 }, - {0x3804, 0x05 }, - {0x3805, 0xbf }, - {0x3806, 0x03 }, - {0x3807, 0xcb }, - {0x3808, 0x05 }, - {0x3809, 0x00 }, - {0x380a, 0x02 }, - {0x380b, 0xd0 }, - {0x380c, 0x06 }, - {0x380d, 0x4c }, - {0x380e, 0x02 }, - {0x380f, 0xe8 }, - {0x3811, 0x10 }, - {0x3813, 0x06 }, - {0x3814, 0x11 }, - {0x3815, 0x11 }, - {0x3a02, 0x02 }, - {0x3a03, 0xe8 }, - {0x3a08, 0x00 }, - {0x3a09, 0x6f }, - {0x3a0a, 0x00 }, - {0x3a0b, 0x5d }, - {0x3a0d, 0x08 }, - {0x3a0e, 0x06 }, - {0x3a14, 0x02 }, - {0x3a15, 0x9a }, - {0x4708, 0x01 }, - {0x3623, 0x02 }, - {0x3634, 0x44 }, - {0x3701, 0x41 }, - {0x3702, 0x30 }, - {0x3703, 0x48 }, - {0x3704, 0x48 }, - {0x3705, 0x18 }, - {0x3820, 0x80 }, - {0x3821, 0x00 }, - {0x370a, 0x12 }, - {0x4608, 0x00 }, - {0x4609, 0x80 }, - {0x4300, 0x32 }, - {0x5086, 0x02 }, - {0x5000, 0xfb }, - {0x5001, 0x1f }, - {0x5002, 0x00 }, - {0x5025, 0x0e }, - {0x5026, 0x18 }, - {0x5027, 0x34 }, - {0x5028, 0x4c }, - {0x5029, 0x62 }, - {0x502a, 0x74 }, - {0x502b, 0x85 }, - {0x502c, 0x92 }, - {0x502d, 0x9e }, - {0x502e, 0xb2 }, - {0x502f, 0xc0 }, - {0x5030, 0xcc }, - {0x5031, 0xe0 }, - {0x5032, 0xee }, - {0x5033, 0xf6 }, - {0x5034, 0x11 }, - {0x5070, 0x1c }, - {0x5071, 0x5b }, - {0x5072, 0x05 }, - {0x5073, 0x20 }, - {0x5074, 0x94 }, - {0x5075, 0xb4 }, - {0x5076, 0xb4 }, - {0x5077, 0xaf }, - {0x5078, 0x05 }, - {0x5079, 0x98 }, - {0x507a, 0x21 }, - {0x5035, 0x6a }, - {0x5036, 0x11 }, - {0x5037, 0x92 }, - {0x5038, 0x21 }, - {0x5039, 0xe1 }, - {0x503a, 0x01 }, - {0x503c, 0x05 }, - {0x503d, 0x08 }, - {0x503e, 0x08 }, - {0x503f, 0x64 }, - {0x5040, 0x58 }, - {0x5041, 0x2a }, - {0x5042, 0xc5 }, - {0x5043, 0x2e }, - {0x5044, 0x3a }, - {0x5045, 0x3c }, - {0x5046, 0x44 }, - {0x5047, 0xf8 }, - {0x5048, 0x08 }, - {0x5049, 0x70 }, - {0x504a, 0xf0 }, - {0x504b, 0xf0 }, - {0x500c, 0x03 }, - {0x500d, 0x20 }, - {0x500e, 0x02 }, - {0x500f, 0x5c }, - {0x5010, 0x48 }, - {0x5011, 0x00 }, - {0x5012, 0x66 }, - {0x5013, 0x03 }, - {0x5014, 0x30 }, - {0x5015, 0x02 }, - {0x5016, 0x7c }, - {0x5017, 0x40 }, - {0x5018, 0x00 }, - {0x5019, 0x66 }, - {0x501a, 0x03 }, - {0x501b, 0x10 }, - {0x501c, 0x02 }, - {0x501d, 0x7c }, - {0x501e, 0x3a }, - {0x501f, 0x00 }, - {0x5020, 0x66 }, - {0x506e, 0x44 }, - {0x5064, 0x08 }, - {0x5065, 0x10 }, - {0x5066, 0x12 }, - {0x5067, 0x02 }, - {0x506c, 0x08 }, - {0x506d, 0x10 }, - {0x506f, 0xa6 }, - {0x5068, 0x08 }, - {0x5069, 0x10 }, - {0x506a, 0x04 }, - {0x506b, 0x12 }, - {0x507e, 0x40 }, - {0x507f, 0x20 }, - {0x507b, 0x02 }, - {0x507a, 0x01 }, - {0x5084, 0x0c }, - {0x5085, 0x3e }, - {0x5005, 0x80 }, - {0x3a0f, 0x30 }, - {0x3a10, 0x28 }, - {0x3a1b, 0x32 }, - {0x3a1e, 0x26 }, - {0x3a11, 0x60 }, - {0x3a1f, 0x14 }, - {0x5060, 0x69 }, - {0x5061, 0x7d }, - {0x5062, 0x7d }, - {0x5063, 0x69 }, - {0x0100, 0x01 }, - {0x0000 ,0x00} - -}; - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ -#if 0 - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x06}, - {0x3805, 0x5f}, - {0x3806, 0x04}, - {0x3807, 0xbb}, - {0x3808, 0x06}, - {0x3809, 0x40}, - {0x380a, 0x04}, - {0x380b, 0xb0}, - {0x380c, 0x07}, - {0x380d, 0x9f}, - {0x380e, 0x04}, - {0x380f, 0xd0}, - {0x3811, 0x10}, - {0x3813, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3a02, 0x04}, - {0x3a03, 0xd0}, - {0x3a08, 0x00}, - {0x3a09, 0xb8}, - {0x3a0a, 0x00}, - {0x3a0b, 0x9a}, - {0x3a0d, 0x08}, - {0x3a0e, 0x06}, - {0x3a14, 0x04}, - {0x3a15, 0x50}, - {0x3623, 0x00}, - {0x3634, 0x44}, - {0x3701, 0x44}, - {0x3702, 0x30}, - {0x3703, 0x48}, - {0x3704, 0x48}, - {0x3705, 0x18}, - {0x3820, 0x80}, - {0x3821, 0x00}, - {0x370a, 0x12}, - {0x4608, 0x00}, - {0x4609, 0x80}, - {0x5002, 0x00}, - {0x3005, 0x24}, - {0x3004, 0x20}, -#else - //{0x3a00,OV2659ReadReg(0x3a00)&0xfb}, - {0x3503,0x03}, - //{0x3406,OV2659ReadReg(0x3406)|0x01}, - - {0x506e,0x44}, - {0x5064,0x08}, - {0x5065,0x10}, - {0x5066,0x18}, // zenghaihui 20110920 16 - {0x5067,0x10}, - {0x506c,0x08}, - {0x506d,0x10}, - {0x506f,0xa6}, - {0x5068,0x08}, - {0x5069,0x10}, - {0x506a,0x08}, - {0x506b,0x28}, - {0x5084,0x14},//0c - {0x5085,0x3c},//34 - {0x5005,0x80}, - - - - {0x5066, 0x3c}, - {0x5067, 0x1a}, - {0x506a, 0x0e}, - {0x506b, 0x2e}, - - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x06}, - {0x3805, 0x5f}, - {0x3806, 0x04}, - {0x3807, 0xbb}, - {0x3808, 0x06}, - {0x3809, 0x40}, - {0x380a, 0x04}, - {0x380b, 0xb0}, - {0x3811, 0x10}, - {0x3813, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - - {0x3623, 0x00}, - {0x3634, 0x44}, - {0x3701, 0x44}, - {0x3208, 0xa2}, - {0x3705, 0x18}, - {0x3820, 0x80}, - {0x3821, 0x00}, - - {0x3003, 0x80},//10fps - {0x3004, 0x20}, //10 - {0x3005, 0x18}, - {0x3006, 0x0d}, - - {0x380c, 0x07}, - {0x380d, 0x9f}, - {0x380e, 0x04}, - {0x380f, 0xd0}, - - {0x370a, 0x12}, - {0x4608, 0x00}, - {0x4609, 0x80}, - {0x5002, 0x00}, - - {0x3a08, 0x00}, - {0x3a09, 0x3e},//7b - {0x3a0e, 0x13},//0a - - {0x3a0a, 0x00}, - {0x3a0b, 0x3e},//7b - {0x3a0d, 0x13},//0a - - {0x4003, 0x88}, -#endif - {0x0000, 0x00} -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ - {0x0, 0x0} -}; -/* 1024X768 SXGA */ -static struct reginfo sensor_xga[] = -{ - {0x0, 0x0} -}; -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0x0100, 0x00}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x00}, - {0x3804, 0x06}, - {0x3805, 0x5f}, - {0x3806, 0x04}, - {0x3807, 0xb7}, - {0x3808, 0x03}, - {0x3809, 0x20}, - {0x380a, 0x02}, - {0x380b, 0x58}, - {0x380c, 0x05}, - {0x380d, 0x14}, - {0x380e, 0x02}, - {0x380f, 0x68}, - {0x3811, 0x08}, - {0x3813, 0x02}, - {0x3814, 0x31}, - {0x3815, 0x31}, - {0x3a02, 0x02}, - {0x3a03, 0x68}, - {0x3a08, 0x00}, - {0x3a09, 0x5c}, - {0x3a0a, 0x00}, - {0x3a0b, 0x4d}, - {0x3a0d, 0x08}, - {0x3a0e, 0x06}, - {0x3a14, 0x02}, - {0x3a15, 0x28}, - {0x3623, 0x00}, - {0x3634, 0x76}, - {0x3701, 0x44}, - {0x3702, 0x18}, - {0x3703, 0x24}, - {0x3704, 0x24}, - {0x3705, 0x0c}, - {0x3820, 0x81}, - {0x3821, 0x01}, - {0x370a, 0x52}, - {0x4608, 0x00}, - {0x4609, 0x80}, - {0x5002, 0x10}, - {0x3005, 0x18}, - {0x3004, 0x20}, - {0x3503,0x00}, - {0x0100, 0x01}, //software wake - {0x0000, 0x00} -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - {0x0, 0x0} -}; - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0x0, 0x0} -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - {0x0, 0x0} -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - {0x0, 0x0} -}; -#endif -#if 0 -/* 160X120 QQVGA*/ -static struct reginfo ov2655_qqvga[] = -{ - - {0x300E, 0x34}, - {0x3011, 0x01}, - {0x3012, 0x10}, - {0x302a, 0x02}, - {0x302b, 0xE6}, - {0x306f, 0x14}, - {0x3362, 0x90}, - - {0x3070, 0x5d}, - {0x3072, 0x5d}, - {0x301c, 0x07}, - {0x301d, 0x07}, - - {0x3020, 0x01}, - {0x3021, 0x18}, - {0x3022, 0x00}, - {0x3023, 0x06}, - {0x3024, 0x06}, - {0x3025, 0x58}, - {0x3026, 0x02}, - {0x3027, 0x61}, - {0x3088, 0x00}, - {0x3089, 0xa0}, - {0x308a, 0x00}, - {0x308b, 0x78}, - {0x3316, 0x64}, - {0x3317, 0x25}, - {0x3318, 0x80}, - {0x3319, 0x08}, - {0x331a, 0x0a}, - {0x331b, 0x07}, - {0x331c, 0x80}, - {0x331d, 0x38}, - {0x3100, 0x00}, - {0x3302, 0x11}, - - {0x0, 0x0}, -}; - - - -static struct reginfo ov2655_Sharpness_auto[] = -{ - {0x3306, 0x00}, -}; - -static struct reginfo ov2655_Sharpness1[] = -{ - {0x3306, 0x08}, - {0x3371, 0x00}, -}; - -static struct reginfo ov2655_Sharpness2[][3] = -{ - //Sharpness 2 - {0x3306, 0x08}, - {0x3371, 0x01}, -}; - -static struct reginfo ov2655_Sharpness3[] = -{ - //default - {0x3306, 0x08}, - {0x332d, 0x02}, -}; -static struct reginfo ov2655_Sharpness4[]= -{ - //Sharpness 4 - {0x3306, 0x08}, - {0x332d, 0x03}, -}; - -static struct reginfo ov2655_Sharpness5[] = -{ - //Sharpness 5 - {0x3306, 0x08}, - {0x332d, 0x04}, -}; -#endif - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0x4300, 0x30}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x4300, 0x32}, - {0x0000, 0x00} -}; - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x3406, 0x00}, //AWB auto, bit[1]:0,auto - {0x0000, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x3406, 0x01}, - {0x3400, 0x07}, - {0x3401, 0x08}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x05}, - {0x3405, 0x00}, - {0x0000, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - //Sunny - {0x3406, 0x01}, - {0x3400, 0x07}, - {0x3401, 0x02}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x05}, - {0x3405, 0x15}, - {0x0000, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - //Office - {0x3406, 0x01}, - {0x3400, 0x06}, - {0x3401, 0x2a}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x07}, - {0x3405, 0x24}, - {0x0000, 0x00} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - //Home - {0x3406, 0x01}, - {0x3400, 0x04}, - {0x3401, 0x58}, - {0x3402, 0x04}, - {0x3403, 0x00}, - {0x3404, 0x07}, - {0x3405, 0x24}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - // Brightness -2 - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness1[]= -{ - // Brightness -1 - - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - // Brightness 0 - - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness3[]= -{ - // Brightness +1 - - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness4[]= -{ - // Brightness +2 - - {0x0000, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - // Brightness +3 - - {0x0000, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x507b, 0x00}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0x507b, 0x20}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x507b, 0x18}, - {0x507e, 0x40}, - {0x507f, 0xa0}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x507b, 0x40}, //bit[6] negative - {0x0000, 0x00} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x507b, 0x18}, - {0x507e, 0xa0}, - {0x507f, 0x40}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x507b, 0x18}, - {0x507e, 0x60}, - {0x507f, 0x60}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure1[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure2[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure4[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure5[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Exposure6[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast2[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - {0x0000, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0x0000, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0x0000, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - {0x3a00, 0x78}, - {0x0000, 0x00} -}; - -static struct reginfo sensor_SceneNight[] = -{ - {0x3003, 0x80}, - {0x3004, 0x20}, - {0x3005, 0x18}, - {0x3006, 0x0d}, - {0x3a00, 0x7c}, - {0x3a02 ,0x07}, - {0x3a03 ,0x38}, - {0x3a14 ,0x07}, - {0x3a15 ,0x38}, - {0x0000, 0x00} -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0x0, 0x0}, -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0x0, 0x0}, -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0x0, 0x0}, -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -#endif -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor_parameter -{ - unsigned int PreviewDummyPixels; - unsigned int CaptureDummyPixels; - unsigned int preview_exposure; - unsigned short int preview_line_width; - unsigned short int preview_gain; - - unsigned short int PreviewPclk; - unsigned short int CapturePclk; - char awb[6]; -}; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - struct sensor_parameter parameter; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u16 reg, u8 val) -{ - int err,cnt; - u8 buf[3]; - struct i2c_msg msg[1]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - buf[2] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[2]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; -} -#endif - -static int sensor_parameter_record(struct i2c_client *client) -{ - u8 ret_l,ret_m,ret_h; - int tp_l,tp_m,tp_h; - struct sensor *sensor = to_sensor(client); - - sensor_read(client,0x3a00, &ret_l); - sensor_write(client,0x3a00, ret_l&0xfb); - - sensor_write(client,0x3503,0x07); //stop AE/AG - - sensor_read(client,0x3500,&ret_h); - sensor_read(client,0x3501, &ret_m); - sensor_read(client,0x3502, &ret_l); - tp_l = ret_l; - tp_m = ret_m; - tp_h = ret_h; - sensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); - - //Read back AGC Gain for preview - sensor_read(client,0x350b, &ret_l); - sensor->parameter.preview_gain = ret_l; - - sensor->parameter.CapturePclk = 24000; - sensor->parameter.PreviewPclk = 24000; - sensor->parameter.PreviewDummyPixels = 0; - sensor->parameter.CaptureDummyPixels = 0; - SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n", - SENSOR_NAME_STRING(), ret_l,sensor->parameter.preview_exposure,tp_h, tp_m, tp_l); - return 0; -} -#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode -#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode -#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode -#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode - -/* SENSOR EXPOSURE LINE LIMITATION */ -#define OV2659_FULL_EXPOSURE_LIMITATION (1236) -#define OV2659_PV_EXPOSURE_LIMITATION (618) - -// SENSOR UXGA SIZE -#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600) -#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200) - -#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16) -#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12) - -static void OV2659SetDummy(struct i2c_client *client,unsigned int dummy_pixels, unsigned int dummy_lines) -{ - unsigned char val; - unsigned int temp_reg1, temp_reg2; - unsigned int temp_reg; - - if (dummy_pixels > 0) - { - sensor_read(client,0x380D,&val); // HTS[b7~b0] - temp_reg1 = val; - sensor_read(client,0x380C,&val); // HTS[b15~b8] - temp_reg2 = val; - temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); - - temp_reg += dummy_pixels; - - sensor_write(client,0x380D,(temp_reg&0xFF)); //HTS[7:0] - sensor_write(client,0x380C,((temp_reg&0xFF00)>>8)); //HTS[15:8] - } - - if (dummy_lines > 0) - { - sensor_read(client,0x380F,&val); // VTS[b7~b0] - temp_reg1 = val; - sensor_read(client,0x380E,&val); // VTS[b15~b8] - temp_reg2 = val; - temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); - - temp_reg += dummy_lines; - - sensor_write(client,0x380F,(temp_reg&0xFF)); //VTS[7:0] - sensor_write(client,0x380E,((temp_reg&0xFF00)>>8)); //VTS[15:8] - } -} /* OV2659_set_dummy */ -static void OV2659WriteShutter(struct i2c_client *client,bool is_preview, unsigned int shutter) -{ - unsigned int extra_exposure_lines = 0; - - if (shutter < 1) - { - shutter = 1; - } - - if (is_preview) - { - if (shutter <= OV2659_PV_EXPOSURE_LIMITATION) - { - extra_exposure_lines = 0; - } - else - { - extra_exposure_lines=shutter - OV2659_PV_EXPOSURE_LIMITATION; - } - - } - else - { - if (shutter <= OV2659_FULL_EXPOSURE_LIMITATION) - { - extra_exposure_lines = 0; - } - else - { - extra_exposure_lines = shutter - OV2659_FULL_EXPOSURE_LIMITATION; - } - - } - - //AEC PK EXPOSURE - shutter*=16; - sensor_write(client,0x3502, (shutter & 0x00FF)); //AEC[7:0] - sensor_write(client,0x3501, ((shutter & 0x0FF00) >>8)); //AEC[15:8] - sensor_write(client,0x3500, ((shutter & 0xFF0000) >> 16)); - - if(extra_exposure_lines>0) - { - // set extra exposure line [aec add vts] - sensor_write(client,0x3507, extra_exposure_lines & 0xFF); // EXVTS[b7~b0] - sensor_write(client,0x3506, (extra_exposure_lines & 0xFF00) >> 8); // EXVTS[b15~b8] - } - else - { - // set extra exposure line [aec add vts] - sensor_write(client,0x3507, 0x00); // EXVTS[b7~b0] - sensor_write(client,0x3506, 0x00); // EXVTS[b15~b8] - } - -} /* OV2659_write_shutter */ -static int sensor_ae_transfer(struct i2c_client *client) -{ - unsigned int prev_line_len,cap_line_len,shutter; - struct sensor *sensor = to_sensor(client); - - mdelay(100); - shutter = sensor->parameter.preview_exposure; - - OV2659SetDummy(client,600,0); - - prev_line_len = OV2659_PV_PERIOD_PIXEL_NUMS + sensor->parameter.PreviewDummyPixels; - cap_line_len = OV2659_FULL_PERIOD_PIXEL_NUMS + sensor->parameter.CaptureDummyPixels; - shutter = (shutter * sensor->parameter.CapturePclk) / sensor->parameter.PreviewPclk; - shutter = (shutter * prev_line_len) / cap_line_len; - shutter*=2; - - OV2659WriteShutter(client,0,shutter); - - - return 0; -} - - -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} - -static s32 sensor_init_width = 800; -static s32 sensor_init_height = 600; -static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); -static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; -static struct reginfo* sensor_init_data_p = sensor_init_data; -static struct reginfo* sensor_init_winseq_p = sensor_svga; -static struct reginfo* sensor_init_winseq_board = NULL; -static struct reginfo* sensor_init_data_board = NULL; -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0,i = 0,j=0; - //if val ==1,mean that sensor need to be reinit - struct rk29camera_platform_data* tmp_plat_data =sensor->sensor_io_request; - - sensor_init_data_p = sensor_init_data; - sensor_init_winseq_p = sensor_svga; - sensor_init_width = 800; - sensor_init_height = 600; - - if (tmp_plat_data != NULL) { - for(i = 0;i < RK_CAM_NUM;i++){ - if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && - (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) { - break; - } - - } - } - if(tmp_plat_data &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ - //user has defined the init data - //init reg - int tmp_init_data_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data_size; - if(tmp_init_data_size > 2){//init data is valid - if((sizeof(struct reginfo) != sizeof(struct reginfo_t))){ - if(sensor_init_data_board) { - vfree(sensor_init_data_board); - sensor_init_data_board = NULL; - } - sensor_init_data_board = (struct reginfo*)vmalloc(tmp_init_data_size); - if(!sensor_init_data_board) - SENSOR_TR("%s :vmalloc init data erro !",__FUNCTION__); - for(j = 0;j< tmp_init_data_size;j++) { - sensor_init_data_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; - sensor_init_data_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; - } - sensor_init_data_p = sensor_init_data_board; - } else{ - sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); - } - } - //init winseq - int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; - if(tmp_winseq_size > 2){ - if(sizeof(struct reginfo) != sizeof(struct reginfo_t)){ - if(sensor_init_winseq_board) { - vfree(sensor_init_winseq_board); - sensor_init_winseq_board = NULL; - } - sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); - if(!sensor_init_winseq_board) - SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); - for(j = 0;j< tmp_winseq_size;j++){ - sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; - sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; - } - sensor_init_winseq_p = sensor_init_winseq_board; - } else{ - sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); - } - } - //init width,height,bus,pixelcode - if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) - sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; - if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) - sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; - if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) - sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; - if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) - sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; - } - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - - ret = sensor_write(client, 0x0103, 0x01); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x300a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x300b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data_p); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - msleep(800); - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - u8 reg_val; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { - sensor_task_lock(client, 1); - sensor_read(client,0x3000,®_val); - sensor_write(client, 0x3000, reg_val&0xfc); - sensor_write(client, 0x3001, 0x00); - sensor_read(client,0x3002,®_val); - sensor_write(client, 0x3002, reg_val&0x1f); - sensor_task_lock(client, 0); - } - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(10); - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg) - { - winseqe_set_addr = sensor_720p; - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) - { - winseqe_set_addr = sensor_xga; - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - sensor_parameter_record(client); - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - sensor_ae_transfer(client); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - msleep(600); - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - msleep(600); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg) - { - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) - { - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) - { - set_w = 1600; - set_h = 1200; - } - else - { /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_mirror(struct i2c_client *client, int on) -{ - char val; - int err = 0; - - if (on) { - err = sensor_read(client, 0x3821, &val); - if (err == 0) { - val |= 0x06; - err = sensor_write(client, 0x3821, val); - } - } else { - err = sensor_read(client, 0x3821, &val); - if (err == 0) { - val &= 0xf9; - err = sensor_write(client, 0x3821, val); - } - } - - return err; -} -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_mirror(client,value) != 0) - SENSOR_TR("%s(%d): sensor_mirror failed, value:0x%x",__FUNCTION__, __LINE__,value); - - SENSOR_DG("%s(%d): sensor_mirror success, value:0x%x",__FUNCTION__, __LINE__,value); - return 0; - } - SENSOR_TR("\n %s..%s value = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_flip(struct i2c_client *client, int on) -{ - char val; - int err = 0; - - if (on) { - err = sensor_read(client, 0x3820, &val); - if (err == 0) { - val |= 0x06; - err = sensor_write(client, 0x3820, val); - } - } else { - err = sensor_read(client, 0x3820, &val); - if (err == 0) { - val &= 0xf9; - err = sensor_write(client, 0x3820, val); - } - } - - return err; -} -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_flip(client,value) != 0) - SENSOR_TR("%s(%d): sensor_flip failed, value:0x%x",__FUNCTION__, __LINE__,value); - - SENSOR_DG("%s(%d): sensor_flip success, value:0x%x",__FUNCTION__, __LINE__,value); - return 0; - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) - { - value = digitalzoom_total - digitalzoom_cur; - } - - if ((value < 0) && ((digitalzoom_cur + value) < 0)) - { - value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - SENSOR_TR("power down %s failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - /* soft reset */ - ret = sensor_write(client, 0x0103, 0x01); - if (ret != 0) { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x300a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x300b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; -#if CONFIG_SENSOR_Flash - int i; -#endif - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - int j = 0; - for(j = 0;j < RK_CAM_NUM;j++){ - if (sensor->sensor_io_request->gpio_res[j].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; - break; - } - } - if(j == RK_CAM_NUM){ - SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } - - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +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_SENSOR_OV2659 +#define SENSOR_V4L2_IDENT V4L2_IDENT_OV2659 +#define SENSOR_ID 0x2656 +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0x3000, 0x0f}, + {0x3001, 0xff}, + {0x3002, 0xff}, + //{0x0100, 0x01}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array + {0x3633, 0x3d}, + {0x3620, 0x02}, + {0x3631, 0x11}, + {0x3612, 0x04}, + {0x3630, 0x20}, + {0x4702, 0x02}, + {0x370c, 0x34}, + {0x3004, 0x10}, + {0x3005, 0x18}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xb7}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x05}, + {0x380d, 0x14}, + {0x380e, 0x02}, + {0x380f, 0x68}, + {0x3811, 0x08}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3a02, 0x02}, + {0x3a03, 0x68}, + {0x3a08, 0x00}, + {0x3a09, 0x5c}, + {0x3a0a, 0x00}, + {0x3a0b, 0x4d}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a14, 0x02}, + {0x3a15, 0x28}, + {0x4708, 0x01}, + {0x3623, 0x00}, + {0x3634, 0x76}, + {0x3701, 0x44}, + {0x3702, 0x18}, + {0x3703, 0x24}, + {0x3704, 0x24}, + {0x3705, 0x0c}, + {0x3820, 0x81}, + {0x3821, 0x01}, + {0x370a, 0x52}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x4300, 0x32}, + {0x5086, 0x02}, + {0x5000, 0xfb}, + {0x5001, 0x1f}, + {0x5002, 0x00}, + {0x5025, 0x0e}, + {0x5026, 0x18}, + {0x5027, 0x34}, + {0x5028, 0x4c}, + {0x5029, 0x62}, + {0x502a, 0x74}, + {0x502b, 0x85}, + {0x502c, 0x92}, + {0x502d, 0x9e}, + {0x502e, 0xb2}, + {0x502f, 0xc0}, + {0x5030, 0xcc}, + {0x5031, 0xe0}, + {0x5032, 0xee}, + {0x5033, 0xf6}, + {0x5034, 0x11}, + {0x5070, 0x1c}, + {0x5071, 0x5b}, + {0x5072, 0x05}, + {0x5073, 0x20}, + {0x5074, 0x94}, + {0x5075, 0xb4}, + {0x5076, 0xb4}, + {0x5077, 0xaf}, + {0x5078, 0x05}, + {0x5079, 0x98}, + {0x507a, 0x21}, + {0x5035, 0x6a}, + {0x5036, 0x11}, + {0x5037, 0x92}, + {0x5038, 0x21}, + + {0x5039, 0xe1}, + {0x503a, 0x01}, + {0x503c, 0x05}, + {0x503d, 0x08}, + {0x503e, 0x08}, + {0x503f, 0x64}, + {0x5040, 0x58}, + {0x5041, 0x2a}, + {0x5042, 0xc5}, + {0x5043, 0x2e}, + {0x5044, 0x3a}, + {0x5045, 0x3c}, + {0x5046, 0x44}, + {0x5047, 0xf8}, + {0x5048, 0x08}, + {0x5049, 0x70}, + {0x504a, 0xf0}, + {0x504b, 0xf0}, + {0x500c, 0x03}, + {0x500d, 0x20}, + {0x500e, 0x02}, + {0x500f, 0x5c}, + {0x5010, 0x48}, + {0x5011, 0x00}, + {0x5012, 0x66}, + {0x5013, 0x03}, + {0x5014, 0x30}, + {0x5015, 0x02}, + {0x5016, 0x7c}, + {0x5017, 0x40}, + {0x5018, 0x00}, + {0x5019, 0x66}, + {0x501a, 0x03}, + {0x501b, 0x10}, + {0x501c, 0x02}, + {0x501d, 0x7c}, + {0x501e, 0x3a}, + {0x501f, 0x00}, + {0x5020, 0x66}, + {0x506e, 0x44}, + {0x5064, 0x08}, + {0x5065, 0x10}, + {0x5066, 0x12}, + {0x5067, 0x02}, + {0x506c, 0x08}, + {0x506d, 0x10}, + {0x506f, 0xa6}, + {0x5068, 0x08}, + + + {0x5069, 0x10}, + {0x506a, 0x04}, + {0x506b, 0x12}, + {0x507e, 0x40}, + {0x507f, 0x20}, + {0x507b, 0x02}, + {0x507a, 0x01}, + {0x5084, 0x0c}, + {0x5085, 0x3e}, + {0x5005, 0x80}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x32}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x5060, 0x69}, + {0x5061, 0x7d}, + {0x5062, 0x7d}, + {0x5063, 0x69}, + {0x3004, 0x20}, + {0x0100, 0x01}, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + + {0x3503,0x03}, + {0x506e,0x44}, + {0x5064,0x08}, + {0x5065,0x10}, + {0x5066,0x18}, // zenghaihui 20110920 16 + {0x5067,0x10}, + {0x506c,0x08}, + {0x506d,0x10}, + {0x506f,0xa6}, + {0x5068,0x08}, + {0x5069,0x10}, + {0x506a,0x08}, + {0x506b,0x28}, + {0x5084,0x14},//0c + {0x5085,0x3c},//34 + {0x5005,0x80}, + + + + {0x5066, 0x3c}, + {0x5067, 0x1a}, + {0x506a, 0x0e}, + {0x506b, 0x2e}, + + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xbb}, + {0x3808, 0x06}, + {0x3809, 0x40}, + {0x380a, 0x04}, + {0x380b, 0xb0}, + {0x3811, 0x10}, + {0x3813, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + + {0x3623, 0x00}, + {0x3634, 0x44}, + {0x3701, 0x44}, + {0x3208, 0xa2}, + {0x3705, 0x18}, + {0x3820, 0x80}, + {0x3821, 0x00}, + + {0x3003, 0x80},//10fps + {0x3004, 0x20}, //10 + {0x3005, 0x18}, + {0x3006, 0x0d}, + + {0x380c, 0x07}, + {0x380d, 0x9f}, + {0x380e, 0x04}, + {0x380f, 0xd0}, + + {0x370a, 0x12}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x5002, 0x00}, + + {0x3a08, 0x00}, + {0x3a09, 0x3e},//7b + {0x3a0e, 0x13},//0a + + {0x3a0a, 0x00}, + {0x3a0b, 0x3e},//7b + {0x3a0d, 0x13},//0a + + {0x4003, 0x88}, + 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[] = +{ + {0x0100, 0x00}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xb7}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x05}, + {0x380d, 0x14}, + {0x380e, 0x02}, + {0x380f, 0x68}, + {0x3811, 0x08}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3a02, 0x02}, + {0x3a03, 0x68}, + {0x3a08, 0x00}, + {0x3a09, 0x5c}, + {0x3a0a, 0x00}, + {0x3a0b, 0x4d}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a14, 0x02}, + {0x3a15, 0x28}, + {0x3623, 0x00}, + {0x3634, 0x76}, + {0x3701, 0x44}, + {0x3702, 0x18}, + {0x3703, 0x24}, + {0x3704, 0x24}, + {0x3705, 0x0c}, + //{0x3820, 0x81}, + //{0x3821, 0x01}, + {0x370a, 0x52}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x5002, 0x10}, + {0x3005, 0x18}, + {0x3004, 0x20}, + {0x3503,0x00}, + {0x0100, 0x01}, //software wake + + 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[]={ + SensorRegVal(0x0103,0x01), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x300a,0), + SensorRegVal(0x300b,0), + 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[]= +{ + {0x3406, 0x00}, //AWB auto, bit[1]:0,auto + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x3406, 0x01}, + {0x3400, 0x07}, + {0x3401, 0x08}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x05}, + {0x3405, 0x00}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x3406, 0x01}, + {0x3400, 0x07}, + {0x3401, 0x02}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x05}, + {0x3405, 0x15}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x3406, 0x01}, + {0x3400, 0x06}, + {0x3401, 0x2a}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x07}, + {0x3405, 0x24}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x3406, 0x01}, + {0x3400, 0x04}, + {0x3401, 0x58}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x07}, + {0x3405, 0x24}, + 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[] = +{ + {0x507b, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x507b, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x507b, 0x18}, + {0x507e, 0x40}, + {0x507f, 0xa0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x507b, 0x40}, //bit[6] negative + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x507b, 0x18}, + {0x507e, 0xa0}, + {0x507f, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x507b, 0x18}, + {0x507e, 0x60}, + {0x507f, 0x60}, + 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[] = +{ + {0x3a00, 0x78}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0x3003, 0x80}, + {0x3004, 0x20}, + {0x3005, 0x18}, + {0x3006, 0x0d}, + {0x3a00, 0x7c}, + {0x3a02 ,0x07}, + {0x3a03 ,0x38}, + {0x3a14 ,0x07}, + {0x3a15 ,0x38}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//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}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +static int sensor_parameter_record(struct i2c_client *client) +{ + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + + sensor_read(client,0x3a00, &ret_l); + sensor_write(client,0x3a00, ret_l&0xfb); + + sensor_write(client,0x3503,0x07); //stop AE/AG + + sensor_read(client,0x3500,&ret_h); + sensor_read(client,0x3501, &ret_m); + sensor_read(client,0x3502, &ret_l); + tp_l = ret_l; + tp_m = ret_m; + tp_h = ret_h; + spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x350b, &ret_l); + spsensor->parameter.preview_gain = ret_l; + + spsensor->parameter.CapturePclk = 24000; + spsensor->parameter.PreviewPclk = 24000; + spsensor->parameter.PreviewDummyPixels = 0; + spsensor->parameter.CaptureDummyPixels = 0; + SENSOR_DG("Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x", + ret_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l); + return 0; +} +#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode +#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode +#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode +#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode + +/* SENSOR EXPOSURE LINE LIMITATION */ +#define OV2659_FULL_EXPOSURE_LIMITATION (1236) +#define OV2659_PV_EXPOSURE_LIMITATION (618) + +// SENSOR UXGA SIZE +#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600) +#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200) + +#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16) +#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12) +static void OV2659SetDummy(struct i2c_client *client,unsigned int dummy_pixels, unsigned int dummy_lines) +{ + unsigned char val; + unsigned int temp_reg1, temp_reg2; + unsigned int temp_reg; + + if (dummy_pixels > 0) + { + sensor_read(client,0x380D,&val); // HTS[b7~b0] + temp_reg1 = val; + sensor_read(client,0x380C,&val); // HTS[b15~b8] + temp_reg2 = val; + temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); + + temp_reg += dummy_pixels; + + sensor_write(client,0x380D,(temp_reg&0xFF)); //HTS[7:0] + sensor_write(client,0x380C,((temp_reg&0xFF00)>>8)); //HTS[15:8] + } + + if (dummy_lines > 0) + { + sensor_read(client,0x380F,&val); // VTS[b7~b0] + temp_reg1 = val; + sensor_read(client,0x380E,&val); // VTS[b15~b8] + temp_reg2 = val; + temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); + + temp_reg += dummy_lines; + + sensor_write(client,0x380F,(temp_reg&0xFF)); //VTS[7:0] + sensor_write(client,0x380E,((temp_reg&0xFF00)>>8)); //VTS[15:8] + } +} /* OV2659_set_dummy */ + +static void OV2659WriteShutter(struct i2c_client *client,bool is_preview, unsigned int shutter) +{ + unsigned int extra_exposure_lines = 0; + + if (shutter < 1) + { + shutter = 1; + } + + if (is_preview) + { + if (shutter <= OV2659_PV_EXPOSURE_LIMITATION) + { + extra_exposure_lines = 0; + } + else + { + extra_exposure_lines=shutter - OV2659_PV_EXPOSURE_LIMITATION; + } + + } + else + { + if (shutter <= OV2659_FULL_EXPOSURE_LIMITATION) + { + extra_exposure_lines = 0; + } + else + { + extra_exposure_lines = shutter - OV2659_FULL_EXPOSURE_LIMITATION; + } + + } + + //AEC PK EXPOSURE + shutter*=16; + sensor_write(client,0x3502, (shutter & 0x00FF)); //AEC[7:0] + sensor_write(client,0x3501, ((shutter & 0x0FF00) >>8)); //AEC[15:8] + sensor_write(client,0x3500, ((shutter & 0xFF0000) >> 16)); + + if(extra_exposure_lines>0) + { + // set extra exposure line [aec add vts] + sensor_write(client,0x3507, extra_exposure_lines & 0xFF); // EXVTS[b7~b0] + sensor_write(client,0x3506, (extra_exposure_lines & 0xFF00) >> 8); // EXVTS[b15~b8] + } + else + { + // set extra exposure line [aec add vts] + sensor_write(client,0x3507, 0x00); // EXVTS[b7~b0] + sensor_write(client,0x3506, 0x00); // EXVTS[b15~b8] + } + +} /* OV2659_write_shutter */ +static int sensor_ae_transfer(struct i2c_client *client) +{ + unsigned int prev_line_len,cap_line_len,shutter; + struct generic_sensor *sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + + mdelay(100); + shutter = spsensor->parameter.preview_exposure; + + OV2659SetDummy(client,600,0); + + prev_line_len = OV2659_PV_PERIOD_PIXEL_NUMS + spsensor->parameter.PreviewDummyPixels; + cap_line_len = OV2659_FULL_PERIOD_PIXEL_NUMS + spsensor->parameter.CaptureDummyPixels; + shutter = (shutter * spsensor->parameter.CapturePclk) / spsensor->parameter.PreviewPclk; + shutter = (shutter * prev_line_len) / cap_line_len; + shutter*=2; + + OV2659WriteShutter(client,0,shutter); + + + return 0; +} +/* +********************************************************** +* 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) +{ + u8 reg_val; + + SENSOR_DG("%s",__FUNCTION__); + + sensor_read(client,0x3000,®_val); + sensor_write(client, 0x3000, reg_val|0x03); + sensor_write(client, 0x3001, 0xff); + sensor_read(client,0x3002,®_val); + sensor_write(client, 0x3002, reg_val|0xe0); + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + u8 reg_val; + struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_read(client,0x3000,®_val); + sensor_write(client, 0x3000, reg_val&0xfc); + sensor_write(client, 0x3001, 0x00); + sensor_read(client,0x3002,®_val); + sensor_write(client, 0x3002, reg_val&0x1f); + } + + 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) +{ + if (capture) { + sensor_parameter_record(client); + } + + return 0; +} +/* +* 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) +{ + if (capture) { + sensor_ae_transfer(client); + } + 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) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + char val; + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + if (mirror) { + err = sensor_read(client, 0x3821, &val); + if (err == 0) { + val |= 0x06; + err = sensor_write(client, 0x3821, val); + } + } else { + err = sensor_read(client, 0x3821, &val); + if (err == 0) { + val &= 0xf9; + err = sensor_write(client, 0x3821, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + char val; + int err = 0; + + SENSOR_DG("flip: %d",flip); + if (flip) { + err = sensor_read(client, 0x3820, &val); + if (err == 0) { + val |= 0x06; + err = sensor_write(client, 0x3820, val); + } + } else { + err = sensor_read(client, 0x3820, &val); + if (err == 0) { + val &= 0xf9; + err = sensor_write(client, 0x3820, val); + } + } + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/ov2659_old.c b/drivers/media/video/ov2659_old.c new file mode 100755 index 000000000000..9101c7a8eb2a --- /dev/null +++ b/drivers/media/video/ov2659_old.c @@ -0,0 +1,3372 @@ +/* +o* Driver for MT9M001 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_OV2659 +#define SENSOR_V4L2_IDENT V4L2_IDENT_OV2659 +#define SENSOR_ID 0x2656 +#define SENSOR_MIN_WIDTH 800 +#define SENSOR_MIN_HEIGHT 600 +#define SENSOR_MAX_WIDTH 1600 +#define SENSOR_MAX_HEIGHT 1200 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 350000 /* 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 COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +struct reginfo +{ + u16 reg; + u8 val; +}; +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_OV2659_USER_DEFINED_SERIES +#include "ov2659_user_series.c" +#else +/* init 800*600 SVGA */ +static struct reginfo sensor_init_data[] = +{ + {0x3000, 0x0f}, + {0x3001, 0xff}, + {0x3002, 0xff}, + //{0x0100, 0x01}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array + {0x3633, 0x3d}, + {0x3620, 0x02}, + {0x3631, 0x11}, + {0x3612, 0x04}, + {0x3630, 0x20}, + {0x4702, 0x02}, + {0x370c, 0x34}, + {0x3004, 0x10}, + {0x3005, 0x18}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xb7}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x05}, + {0x380d, 0x14}, + {0x380e, 0x02}, + {0x380f, 0x68}, + {0x3811, 0x08}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3a02, 0x02}, + {0x3a03, 0x68}, + {0x3a08, 0x00}, + {0x3a09, 0x5c}, + {0x3a0a, 0x00}, + {0x3a0b, 0x4d}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a14, 0x02}, + {0x3a15, 0x28}, + {0x4708, 0x01}, + {0x3623, 0x00}, + {0x3634, 0x76}, + {0x3701, 0x44}, + {0x3702, 0x18}, + {0x3703, 0x24}, + {0x3704, 0x24}, + {0x3705, 0x0c}, + {0x3820, 0x81}, + {0x3821, 0x01}, + {0x370a, 0x52}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x4300, 0x32}, + {0x5086, 0x02}, + {0x5000, 0xfb}, + {0x5001, 0x1f}, + {0x5002, 0x00}, + {0x5025, 0x0e}, + {0x5026, 0x18}, + {0x5027, 0x34}, + {0x5028, 0x4c}, + {0x5029, 0x62}, + {0x502a, 0x74}, + {0x502b, 0x85}, + {0x502c, 0x92}, + {0x502d, 0x9e}, + {0x502e, 0xb2}, + {0x502f, 0xc0}, + {0x5030, 0xcc}, + {0x5031, 0xe0}, + {0x5032, 0xee}, + {0x5033, 0xf6}, + {0x5034, 0x11}, + {0x5070, 0x1c}, + {0x5071, 0x5b}, + {0x5072, 0x05}, + {0x5073, 0x20}, + {0x5074, 0x94}, + {0x5075, 0xb4}, + {0x5076, 0xb4}, + {0x5077, 0xaf}, + {0x5078, 0x05}, + {0x5079, 0x98}, + {0x507a, 0x21}, + {0x5035, 0x6a}, + {0x5036, 0x11}, + {0x5037, 0x92}, + {0x5038, 0x21}, + + {0x5039, 0xe1}, + {0x503a, 0x01}, + {0x503c, 0x05}, + {0x503d, 0x08}, + {0x503e, 0x08}, + {0x503f, 0x64}, + {0x5040, 0x58}, + {0x5041, 0x2a}, + {0x5042, 0xc5}, + {0x5043, 0x2e}, + {0x5044, 0x3a}, + {0x5045, 0x3c}, + {0x5046, 0x44}, + {0x5047, 0xf8}, + {0x5048, 0x08}, + {0x5049, 0x70}, + {0x504a, 0xf0}, + {0x504b, 0xf0}, + {0x500c, 0x03}, + {0x500d, 0x20}, + {0x500e, 0x02}, + {0x500f, 0x5c}, + {0x5010, 0x48}, + {0x5011, 0x00}, + {0x5012, 0x66}, + {0x5013, 0x03}, + {0x5014, 0x30}, + {0x5015, 0x02}, + {0x5016, 0x7c}, + {0x5017, 0x40}, + {0x5018, 0x00}, + {0x5019, 0x66}, + {0x501a, 0x03}, + {0x501b, 0x10}, + {0x501c, 0x02}, + {0x501d, 0x7c}, + {0x501e, 0x3a}, + {0x501f, 0x00}, + {0x5020, 0x66}, + {0x506e, 0x44}, + {0x5064, 0x08}, + {0x5065, 0x10}, + {0x5066, 0x12}, + {0x5067, 0x02}, + {0x506c, 0x08}, + {0x506d, 0x10}, + {0x506f, 0xa6}, + {0x5068, 0x08}, + + + {0x5069, 0x10}, + {0x506a, 0x04}, + {0x506b, 0x12}, + {0x507e, 0x40}, + {0x507f, 0x20}, + {0x507b, 0x02}, + {0x507a, 0x01}, + {0x5084, 0x0c}, + {0x5085, 0x3e}, + {0x5005, 0x80}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x32}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x5060, 0x69}, + {0x5061, 0x7d}, + {0x5062, 0x7d}, + {0x5063, 0x69}, + {0x3004, 0x20}, + {0x0100, 0x01}, + + {0x0000, 0x00} +}; + +/* 1280x720 */ +static struct reginfo sensor_720p[]= +{ + {0x0103, 0x01 }, + {0x3000, 0x0f }, + {0x3001, 0xff }, + {0x3002, 0xff }, + //{0x0100, 0x01 }, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array + {0x3633, 0x3d }, + {0x3620, 0x02 }, + {0x3631, 0x11 }, + {0x3612, 0x04 }, + {0x3630, 0x20 }, + {0x4702, 0x02 }, + {0x370c, 0x34 }, + {0x3004, 0x10 }, + {0x3005, 0x24 }, + {0x3800, 0x00 }, + {0x3801, 0xa0 }, + {0x3802, 0x00 }, + {0x3803, 0xf0 }, + {0x3804, 0x05 }, + {0x3805, 0xbf }, + {0x3806, 0x03 }, + {0x3807, 0xcb }, + {0x3808, 0x05 }, + {0x3809, 0x00 }, + {0x380a, 0x02 }, + {0x380b, 0xd0 }, + {0x380c, 0x06 }, + {0x380d, 0x4c }, + {0x380e, 0x02 }, + {0x380f, 0xe8 }, + {0x3811, 0x10 }, + {0x3813, 0x06 }, + {0x3814, 0x11 }, + {0x3815, 0x11 }, + {0x3a02, 0x02 }, + {0x3a03, 0xe8 }, + {0x3a08, 0x00 }, + {0x3a09, 0x6f }, + {0x3a0a, 0x00 }, + {0x3a0b, 0x5d }, + {0x3a0d, 0x08 }, + {0x3a0e, 0x06 }, + {0x3a14, 0x02 }, + {0x3a15, 0x9a }, + {0x4708, 0x01 }, + {0x3623, 0x02 }, + {0x3634, 0x44 }, + {0x3701, 0x41 }, + {0x3702, 0x30 }, + {0x3703, 0x48 }, + {0x3704, 0x48 }, + {0x3705, 0x18 }, + {0x3820, 0x80 }, + {0x3821, 0x00 }, + {0x370a, 0x12 }, + {0x4608, 0x00 }, + {0x4609, 0x80 }, + {0x4300, 0x32 }, + {0x5086, 0x02 }, + {0x5000, 0xfb }, + {0x5001, 0x1f }, + {0x5002, 0x00 }, + {0x5025, 0x0e }, + {0x5026, 0x18 }, + {0x5027, 0x34 }, + {0x5028, 0x4c }, + {0x5029, 0x62 }, + {0x502a, 0x74 }, + {0x502b, 0x85 }, + {0x502c, 0x92 }, + {0x502d, 0x9e }, + {0x502e, 0xb2 }, + {0x502f, 0xc0 }, + {0x5030, 0xcc }, + {0x5031, 0xe0 }, + {0x5032, 0xee }, + {0x5033, 0xf6 }, + {0x5034, 0x11 }, + {0x5070, 0x1c }, + {0x5071, 0x5b }, + {0x5072, 0x05 }, + {0x5073, 0x20 }, + {0x5074, 0x94 }, + {0x5075, 0xb4 }, + {0x5076, 0xb4 }, + {0x5077, 0xaf }, + {0x5078, 0x05 }, + {0x5079, 0x98 }, + {0x507a, 0x21 }, + {0x5035, 0x6a }, + {0x5036, 0x11 }, + {0x5037, 0x92 }, + {0x5038, 0x21 }, + {0x5039, 0xe1 }, + {0x503a, 0x01 }, + {0x503c, 0x05 }, + {0x503d, 0x08 }, + {0x503e, 0x08 }, + {0x503f, 0x64 }, + {0x5040, 0x58 }, + {0x5041, 0x2a }, + {0x5042, 0xc5 }, + {0x5043, 0x2e }, + {0x5044, 0x3a }, + {0x5045, 0x3c }, + {0x5046, 0x44 }, + {0x5047, 0xf8 }, + {0x5048, 0x08 }, + {0x5049, 0x70 }, + {0x504a, 0xf0 }, + {0x504b, 0xf0 }, + {0x500c, 0x03 }, + {0x500d, 0x20 }, + {0x500e, 0x02 }, + {0x500f, 0x5c }, + {0x5010, 0x48 }, + {0x5011, 0x00 }, + {0x5012, 0x66 }, + {0x5013, 0x03 }, + {0x5014, 0x30 }, + {0x5015, 0x02 }, + {0x5016, 0x7c }, + {0x5017, 0x40 }, + {0x5018, 0x00 }, + {0x5019, 0x66 }, + {0x501a, 0x03 }, + {0x501b, 0x10 }, + {0x501c, 0x02 }, + {0x501d, 0x7c }, + {0x501e, 0x3a }, + {0x501f, 0x00 }, + {0x5020, 0x66 }, + {0x506e, 0x44 }, + {0x5064, 0x08 }, + {0x5065, 0x10 }, + {0x5066, 0x12 }, + {0x5067, 0x02 }, + {0x506c, 0x08 }, + {0x506d, 0x10 }, + {0x506f, 0xa6 }, + {0x5068, 0x08 }, + {0x5069, 0x10 }, + {0x506a, 0x04 }, + {0x506b, 0x12 }, + {0x507e, 0x40 }, + {0x507f, 0x20 }, + {0x507b, 0x02 }, + {0x507a, 0x01 }, + {0x5084, 0x0c }, + {0x5085, 0x3e }, + {0x5005, 0x80 }, + {0x3a0f, 0x30 }, + {0x3a10, 0x28 }, + {0x3a1b, 0x32 }, + {0x3a1e, 0x26 }, + {0x3a11, 0x60 }, + {0x3a1f, 0x14 }, + {0x5060, 0x69 }, + {0x5061, 0x7d }, + {0x5062, 0x7d }, + {0x5063, 0x69 }, + {0x0100, 0x01 }, + {0x0000 ,0x00} + +}; + +/* 1600X1200 UXGA */ +static struct reginfo sensor_uxga[] = +{ +#if 0 + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xbb}, + {0x3808, 0x06}, + {0x3809, 0x40}, + {0x380a, 0x04}, + {0x380b, 0xb0}, + {0x380c, 0x07}, + {0x380d, 0x9f}, + {0x380e, 0x04}, + {0x380f, 0xd0}, + {0x3811, 0x10}, + {0x3813, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3a02, 0x04}, + {0x3a03, 0xd0}, + {0x3a08, 0x00}, + {0x3a09, 0xb8}, + {0x3a0a, 0x00}, + {0x3a0b, 0x9a}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a14, 0x04}, + {0x3a15, 0x50}, + {0x3623, 0x00}, + {0x3634, 0x44}, + {0x3701, 0x44}, + {0x3702, 0x30}, + {0x3703, 0x48}, + {0x3704, 0x48}, + {0x3705, 0x18}, + {0x3820, 0x80}, + {0x3821, 0x00}, + {0x370a, 0x12}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x5002, 0x00}, + {0x3005, 0x24}, + {0x3004, 0x20}, +#else + //{0x3a00,OV2659ReadReg(0x3a00)&0xfb}, + {0x3503,0x03}, + //{0x3406,OV2659ReadReg(0x3406)|0x01}, + + {0x506e,0x44}, + {0x5064,0x08}, + {0x5065,0x10}, + {0x5066,0x18}, // zenghaihui 20110920 16 + {0x5067,0x10}, + {0x506c,0x08}, + {0x506d,0x10}, + {0x506f,0xa6}, + {0x5068,0x08}, + {0x5069,0x10}, + {0x506a,0x08}, + {0x506b,0x28}, + {0x5084,0x14},//0c + {0x5085,0x3c},//34 + {0x5005,0x80}, + + + + {0x5066, 0x3c}, + {0x5067, 0x1a}, + {0x506a, 0x0e}, + {0x506b, 0x2e}, + + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xbb}, + {0x3808, 0x06}, + {0x3809, 0x40}, + {0x380a, 0x04}, + {0x380b, 0xb0}, + {0x3811, 0x10}, + {0x3813, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + + {0x3623, 0x00}, + {0x3634, 0x44}, + {0x3701, 0x44}, + {0x3208, 0xa2}, + {0x3705, 0x18}, + {0x3820, 0x80}, + {0x3821, 0x00}, + + {0x3003, 0x80},//10fps + {0x3004, 0x20}, //10 + {0x3005, 0x18}, + {0x3006, 0x0d}, + + {0x380c, 0x07}, + {0x380d, 0x9f}, + {0x380e, 0x04}, + {0x380f, 0xd0}, + + {0x370a, 0x12}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x5002, 0x00}, + + {0x3a08, 0x00}, + {0x3a09, 0x3e},//7b + {0x3a0e, 0x13},//0a + + {0x3a0a, 0x00}, + {0x3a0b, 0x3e},//7b + {0x3a0d, 0x13},//0a + + {0x4003, 0x88}, +#endif + {0x0000, 0x00} +}; + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ + {0x0, 0x0} +}; +/* 1024X768 SXGA */ +static struct reginfo sensor_xga[] = +{ + {0x0, 0x0} +}; +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0x0100, 0x00}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x06}, + {0x3805, 0x5f}, + {0x3806, 0x04}, + {0x3807, 0xb7}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x05}, + {0x380d, 0x14}, + {0x380e, 0x02}, + {0x380f, 0x68}, + {0x3811, 0x08}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3a02, 0x02}, + {0x3a03, 0x68}, + {0x3a08, 0x00}, + {0x3a09, 0x5c}, + {0x3a0a, 0x00}, + {0x3a0b, 0x4d}, + {0x3a0d, 0x08}, + {0x3a0e, 0x06}, + {0x3a14, 0x02}, + {0x3a15, 0x28}, + {0x3623, 0x00}, + {0x3634, 0x76}, + {0x3701, 0x44}, + {0x3702, 0x18}, + {0x3703, 0x24}, + {0x3704, 0x24}, + {0x3705, 0x0c}, + {0x3820, 0x81}, + {0x3821, 0x01}, + {0x370a, 0x52}, + {0x4608, 0x00}, + {0x4609, 0x80}, + {0x5002, 0x10}, + {0x3005, 0x18}, + {0x3004, 0x20}, + {0x3503,0x00}, + {0x0100, 0x01}, //software wake + {0x0000, 0x00} +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + {0x0, 0x0} +}; + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0x0, 0x0} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + {0x0, 0x0} +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + {0x0, 0x0} +}; +#endif +#if 0 +/* 160X120 QQVGA*/ +static struct reginfo ov2655_qqvga[] = +{ + + {0x300E, 0x34}, + {0x3011, 0x01}, + {0x3012, 0x10}, + {0x302a, 0x02}, + {0x302b, 0xE6}, + {0x306f, 0x14}, + {0x3362, 0x90}, + + {0x3070, 0x5d}, + {0x3072, 0x5d}, + {0x301c, 0x07}, + {0x301d, 0x07}, + + {0x3020, 0x01}, + {0x3021, 0x18}, + {0x3022, 0x00}, + {0x3023, 0x06}, + {0x3024, 0x06}, + {0x3025, 0x58}, + {0x3026, 0x02}, + {0x3027, 0x61}, + {0x3088, 0x00}, + {0x3089, 0xa0}, + {0x308a, 0x00}, + {0x308b, 0x78}, + {0x3316, 0x64}, + {0x3317, 0x25}, + {0x3318, 0x80}, + {0x3319, 0x08}, + {0x331a, 0x0a}, + {0x331b, 0x07}, + {0x331c, 0x80}, + {0x331d, 0x38}, + {0x3100, 0x00}, + {0x3302, 0x11}, + + {0x0, 0x0}, +}; + + + +static struct reginfo ov2655_Sharpness_auto[] = +{ + {0x3306, 0x00}, +}; + +static struct reginfo ov2655_Sharpness1[] = +{ + {0x3306, 0x08}, + {0x3371, 0x00}, +}; + +static struct reginfo ov2655_Sharpness2[][3] = +{ + //Sharpness 2 + {0x3306, 0x08}, + {0x3371, 0x01}, +}; + +static struct reginfo ov2655_Sharpness3[] = +{ + //default + {0x3306, 0x08}, + {0x332d, 0x02}, +}; +static struct reginfo ov2655_Sharpness4[]= +{ + //Sharpness 4 + {0x3306, 0x08}, + {0x332d, 0x03}, +}; + +static struct reginfo ov2655_Sharpness5[] = +{ + //Sharpness 5 + {0x3306, 0x08}, + {0x332d, 0x04}, +}; +#endif + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0x4300, 0x30}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x4300, 0x32}, + {0x0000, 0x00} +}; + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x3406, 0x00}, //AWB auto, bit[1]:0,auto + {0x0000, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x3406, 0x01}, + {0x3400, 0x07}, + {0x3401, 0x08}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x05}, + {0x3405, 0x00}, + {0x0000, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + //Sunny + {0x3406, 0x01}, + {0x3400, 0x07}, + {0x3401, 0x02}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x05}, + {0x3405, 0x15}, + {0x0000, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x3406, 0x01}, + {0x3400, 0x06}, + {0x3401, 0x2a}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x07}, + {0x3405, 0x24}, + {0x0000, 0x00} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x3406, 0x01}, + {0x3400, 0x04}, + {0x3401, 0x58}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x07}, + {0x3405, 0x24}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + // Brightness -2 + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness1[]= +{ + // Brightness -1 + + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + // Brightness 0 + + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness3[]= +{ + // Brightness +1 + + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness4[]= +{ + // Brightness +2 + + {0x0000, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + // Brightness +3 + + {0x0000, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x507b, 0x00}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0x507b, 0x20}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x507b, 0x18}, + {0x507e, 0x40}, + {0x507f, 0xa0}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x507b, 0x40}, //bit[6] negative + {0x0000, 0x00} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x507b, 0x18}, + {0x507e, 0xa0}, + {0x507f, 0x40}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x507b, 0x18}, + {0x507e, 0x60}, + {0x507f, 0x60}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure1[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure2[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure4[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure5[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Exposure6[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0x0000, 0x00} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast2[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + {0x0000, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + {0x0000, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0x0000, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0x0000, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0x0000, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + {0x3a00, 0x78}, + {0x0000, 0x00} +}; + +static struct reginfo sensor_SceneNight[] = +{ + {0x3003, 0x80}, + {0x3004, 0x20}, + {0x3005, 0x18}, + {0x3006, 0x0d}, + {0x3a00, 0x7c}, + {0x3a02 ,0x07}, + {0x3a03 ,0x38}, + {0x3a14 ,0x07}, + {0x3a15 ,0x38}, + {0x0000, 0x00} +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0x0, 0x0}, +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0x0, 0x0}, +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0x0, 0x0}, +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + struct sensor_parameter parameter; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u16 reg, u8 val) +{ + int err,cnt; + u8 buf[3]; + struct i2c_msg msg[1]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + buf[2] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[2]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != 0) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif + +static int sensor_parameter_record(struct i2c_client *client) +{ + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + struct sensor *sensor = to_sensor(client); + + sensor_read(client,0x3a00, &ret_l); + sensor_write(client,0x3a00, ret_l&0xfb); + + sensor_write(client,0x3503,0x07); //stop AE/AG + + sensor_read(client,0x3500,&ret_h); + sensor_read(client,0x3501, &ret_m); + sensor_read(client,0x3502, &ret_l); + tp_l = ret_l; + tp_m = ret_m; + tp_h = ret_h; + sensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x350b, &ret_l); + sensor->parameter.preview_gain = ret_l; + + sensor->parameter.CapturePclk = 24000; + sensor->parameter.PreviewPclk = 24000; + sensor->parameter.PreviewDummyPixels = 0; + sensor->parameter.CaptureDummyPixels = 0; + SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n", + SENSOR_NAME_STRING(), ret_l,sensor->parameter.preview_exposure,tp_h, tp_m, tp_l); + return 0; +} +#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode +#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode +#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode +#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode + +/* SENSOR EXPOSURE LINE LIMITATION */ +#define OV2659_FULL_EXPOSURE_LIMITATION (1236) +#define OV2659_PV_EXPOSURE_LIMITATION (618) + +// SENSOR UXGA SIZE +#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600) +#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200) + +#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16) +#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12) + +static void OV2659SetDummy(struct i2c_client *client,unsigned int dummy_pixels, unsigned int dummy_lines) +{ + unsigned char val; + unsigned int temp_reg1, temp_reg2; + unsigned int temp_reg; + + if (dummy_pixels > 0) + { + sensor_read(client,0x380D,&val); // HTS[b7~b0] + temp_reg1 = val; + sensor_read(client,0x380C,&val); // HTS[b15~b8] + temp_reg2 = val; + temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); + + temp_reg += dummy_pixels; + + sensor_write(client,0x380D,(temp_reg&0xFF)); //HTS[7:0] + sensor_write(client,0x380C,((temp_reg&0xFF00)>>8)); //HTS[15:8] + } + + if (dummy_lines > 0) + { + sensor_read(client,0x380F,&val); // VTS[b7~b0] + temp_reg1 = val; + sensor_read(client,0x380E,&val); // VTS[b15~b8] + temp_reg2 = val; + temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8); + + temp_reg += dummy_lines; + + sensor_write(client,0x380F,(temp_reg&0xFF)); //VTS[7:0] + sensor_write(client,0x380E,((temp_reg&0xFF00)>>8)); //VTS[15:8] + } +} /* OV2659_set_dummy */ +static void OV2659WriteShutter(struct i2c_client *client,bool is_preview, unsigned int shutter) +{ + unsigned int extra_exposure_lines = 0; + + if (shutter < 1) + { + shutter = 1; + } + + if (is_preview) + { + if (shutter <= OV2659_PV_EXPOSURE_LIMITATION) + { + extra_exposure_lines = 0; + } + else + { + extra_exposure_lines=shutter - OV2659_PV_EXPOSURE_LIMITATION; + } + + } + else + { + if (shutter <= OV2659_FULL_EXPOSURE_LIMITATION) + { + extra_exposure_lines = 0; + } + else + { + extra_exposure_lines = shutter - OV2659_FULL_EXPOSURE_LIMITATION; + } + + } + + //AEC PK EXPOSURE + shutter*=16; + sensor_write(client,0x3502, (shutter & 0x00FF)); //AEC[7:0] + sensor_write(client,0x3501, ((shutter & 0x0FF00) >>8)); //AEC[15:8] + sensor_write(client,0x3500, ((shutter & 0xFF0000) >> 16)); + + if(extra_exposure_lines>0) + { + // set extra exposure line [aec add vts] + sensor_write(client,0x3507, extra_exposure_lines & 0xFF); // EXVTS[b7~b0] + sensor_write(client,0x3506, (extra_exposure_lines & 0xFF00) >> 8); // EXVTS[b15~b8] + } + else + { + // set extra exposure line [aec add vts] + sensor_write(client,0x3507, 0x00); // EXVTS[b7~b0] + sensor_write(client,0x3506, 0x00); // EXVTS[b15~b8] + } + +} /* OV2659_write_shutter */ +static int sensor_ae_transfer(struct i2c_client *client) +{ + unsigned int prev_line_len,cap_line_len,shutter; + struct sensor *sensor = to_sensor(client); + + mdelay(100); + shutter = sensor->parameter.preview_exposure; + + OV2659SetDummy(client,600,0); + + prev_line_len = OV2659_PV_PERIOD_PIXEL_NUMS + sensor->parameter.PreviewDummyPixels; + cap_line_len = OV2659_FULL_PERIOD_PIXEL_NUMS + sensor->parameter.CaptureDummyPixels; + shutter = (shutter * sensor->parameter.CapturePclk) / sensor->parameter.PreviewPclk; + shutter = (shutter * prev_line_len) / cap_line_len; + shutter*=2; + + OV2659WriteShutter(client,0,shutter); + + + return 0; +} + + +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} + +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = sensor_init_data; +static struct reginfo* sensor_init_winseq_p = sensor_svga; +static struct reginfo* sensor_init_winseq_board = NULL; +static struct reginfo* sensor_init_data_board = NULL; +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret,pid = 0,i = 0,j=0; + //if val ==1,mean that sensor need to be reinit + struct rk29camera_platform_data* tmp_plat_data =sensor->sensor_io_request; + + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + + if (tmp_plat_data != NULL) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) { + break; + } + + } + } + if(tmp_plat_data &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + int tmp_init_data_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data_size; + if(tmp_init_data_size > 2){//init data is valid + if((sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + if(sensor_init_data_board) { + vfree(sensor_init_data_board); + sensor_init_data_board = NULL; + } + sensor_init_data_board = (struct reginfo*)vmalloc(tmp_init_data_size); + if(!sensor_init_data_board) + SENSOR_TR("%s :vmalloc init data erro !",__FUNCTION__); + for(j = 0;j< tmp_init_data_size;j++) { + sensor_init_data_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data_board; + } else{ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + } + //init winseq + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(tmp_winseq_size > 2){ + if(sizeof(struct reginfo) != sizeof(struct reginfo_t)){ + if(sensor_init_winseq_board) { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } else{ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + + ret = sensor_write(client, 0x0103, 0x01); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + mdelay(5); //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x300a, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x300b, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data_p); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + msleep(800); + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_task_lock(client, 1); + sensor_read(client,0x3000,®_val); + sensor_write(client, 0x3000, reg_val&0xfc); + sensor_write(client, 0x3001, 0x00); + sensor_read(client,0x3002,®_val); + sensor_write(client, 0x3002, reg_val&0x1f); + sensor_task_lock(client, 0); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(10); + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg) + { + winseqe_set_addr = sensor_720p; + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) + { + winseqe_set_addr = sensor_xga; + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + winseqe_set_addr = sensor_uxga; + set_w = 1600; + set_h = 1200; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + sensor_parameter_record(client); + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + sensor_ae_transfer(client); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + msleep(600); + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg) + { + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg) + { + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg) + { + set_w = 1600; + set_h = 1200; + } + else + { /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_mirror(struct i2c_client *client, int on) +{ + char val; + int err = 0; + + if (on) { + err = sensor_read(client, 0x3821, &val); + if (err == 0) { + val |= 0x06; + err = sensor_write(client, 0x3821, val); + } + } else { + err = sensor_read(client, 0x3821, &val); + if (err == 0) { + val &= 0xf9; + err = sensor_write(client, 0x3821, val); + } + } + + return err; +} +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_mirror(client,value) != 0) + SENSOR_TR("%s(%d): sensor_mirror failed, value:0x%x",__FUNCTION__, __LINE__,value); + + SENSOR_DG("%s(%d): sensor_mirror success, value:0x%x",__FUNCTION__, __LINE__,value); + return 0; + } + SENSOR_TR("\n %s..%s value = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_flip(struct i2c_client *client, int on) +{ + char val; + int err = 0; + + if (on) { + err = sensor_read(client, 0x3820, &val); + if (err == 0) { + val |= 0x06; + err = sensor_write(client, 0x3820, val); + } + } else { + err = sensor_read(client, 0x3820, &val); + if (err == 0) { + val &= 0xf9; + err = sensor_write(client, 0x3820, val); + } + } + + return err; +} +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_flip(client,value) != 0) + SENSOR_TR("%s(%d): sensor_flip failed, value:0x%x",__FUNCTION__, __LINE__,value); + + SENSOR_DG("%s(%d): sensor_flip success, value:0x%x",__FUNCTION__, __LINE__,value); + return 0; + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) + { + value = digitalzoom_total - digitalzoom_cur; + } + + if ((value < 0) && ((digitalzoom_cur + value) < 0)) + { + value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret,pid = 0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + SENSOR_TR("power down %s failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + /* soft reset */ + ret = sensor_write(client, 0x0103, 0x01); + if (ret != 0) { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + mdelay(5); //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x300a, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x300b, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + + return ret; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } + + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/ov5640.c b/drivers/media/video/ov5640.c index 25b0dc1e5d34..4728bc5b461c 100755 --- a/drivers/media/video/ov5640.c +++ b/drivers/media/video/ov5640.c @@ -1,4199 +1,1511 @@ + #include "generic_sensor.h" + /* - * Driver for OV5640 CMOS Image Sensor from OmniVision - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ov5640.h" - -static int debug; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_OV5640 -#define SENSOR_V4L2_IDENT V4L2_IDENT_OV5640 -#define SENSOR_ID 0x5640 -#define SENSOR_MIN_WIDTH 176 -#define SENSOR_MIN_HEIGHT 144 -#define SENSOR_MAX_WIDTH 2592 -#define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#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_Exposure 0 -#define CONFIG_SENSOR_Flash 1 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 -#ifdef CONFIG_OV5640_AUTOFOCUS -#define CONFIG_SENSOR_Focus 1 -#define CONFIG_SENSOR_FocusCenterInCapture 0 -#define CONFIG_SENSOR_FocusContinues 0 -#include "ov5640_af_firmware.c" -#else -#define CONFIG_SENSOR_Focus 0 -#endif - -#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define CONFIG_SENSOR_WRITE_REGS 0 -#define WRITE_REGS_NUM 3 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - -#if CONFIG_SENSOR_Focus -/*#define SENSOR_AF_MODE_INFINITY 0 -#define SENSOR_AF_MODE_MACRO 1 -#define SENSOR_AF_MODE_FIXED 2 -#define SENSOR_AF_MODE_AUTO 3 -#define SENSOR_AF_MODE_CONTINUOUS 4 -#define SENSOR_AF_MODE_CLOSE 5*/ -#define SENSOR_AF_MODE_AUTO 0 -#define SENSOR_AF_MODE_CLOSE 1 -#define SENSOR_AF_MODE_CONTINUOUS 2 -#endif - -#if CONFIG_SENSOR_Focus -/* ov5640 VCM Command and Status Registers */ -#define CMD_MAIN_Reg 0x3022 -//#define CMD_TAG_Reg 0x3023 -#define CMD_ACK_Reg 0x3023 -#define CMD_PARA0_Reg 0x3024 -#define CMD_PARA1_Reg 0x3025 -#define CMD_PARA2_Reg 0x3026 -#define CMD_PARA3_Reg 0x3027 -#define CMD_PARA4_Reg 0x3028 - -//#define STA_ZONE_Reg 0x3026 -#define STA_FOCUS_Reg 0x3029 - -/* ov5640 VCM Command */ - -#define ConstFocus_Cmd 0x04 -#define StepMode_Cmd 0x05 -#define PauseFocus_Cmd 0x06 -#define ReturnIdle_Cmd 0x08 -#define SetZone_Cmd 0x10 -#define UpdateZone_Cmd 0x12 -#define SetMotor_Cmd 0x20 -#define SingleFocus_Cmd 0x03 -#define GetFocusResult_Cmd 0x07 -#define ReleaseFocus_Cmd 0x08 -#define ZoneRelaunch_Cmd 0x12 -#define DefaultZoneConfig_Cmd 0x80 -#define TouchZoneConfig_Cmd 0x81 -#define CustomZoneConfig_Cmd 0x8f - - -/* ov5640 Focus State */ -//#define S_FIRWRE 0xFF /*Firmware is downloaded and not run*/ -#define S_STARTUP 0x7e /*Firmware is initializing*/ -#define S_ERROR 0x7f -#define S_IDLE 0x70 /*Idle state, focus is released; lens is located at the furthest position.*/ -#define S_FOCUSING 0x00 /*Auto Focus is running.*/ -#define S_FOCUSED 0x10 /*Auto Focus is completed.*/ - -#define S_CAPTURE 0x12 -#define S_STEP 0x20 - -/* ov5640 Zone State */ -#define Zone_Is_Focused(a, zone_val) (zone_val&(1<<(a-3))) -#define Zone_Get_ID(zone_val) (zone_val&0x03) - -#define Zone_CenterMode 0x01 -#define Zone_5xMode 0x02 -#define Zone_5PlusMode 0x03 -#define Zone_4fMode 0x04 - -#define ZoneSel_Auto 0x0b -#define ZoneSel_SemiAuto 0x0c -#define ZoneSel_Manual 0x0d -#define ZoneSel_Rotate 0x0e - -/* ov5640 Step Focus Commands */ -#define StepFocus_Near_Tag 0x01 -#define StepFocus_Far_Tag 0x02 -#define StepFocus_Furthest_Tag 0x03 -#define StepFocus_Nearest_Tag 0x04 -#define StepFocus_Spec_Tag 0x10 -#endif - -//flash off in fixed time to prevent from too hot , zyc -struct flash_timer{ - struct soc_camera_device *icd; - struct hrtimer timer; -}; -static enum hrtimer_restart flash_off_func(struct hrtimer *timer); - -static struct flash_timer flash_off_timer; -//for user defined if user want to customize the series , zyc -#ifdef CONFIG_OV5640_USER_DEFINED_SERIES -#include "ov5640_user_series.c" -#else - -/* init 800X600 SVGA */ -static struct reginfo sensor_init_data[] = -{ - {0x3103, 0x11}, - //{0x3008, 0x82}, - {0x3008, 0x42}, - {0x3103, 0x03}, - {0x3017, 0xff}, - {0x3018, 0xff}, - {0x3034, 0x1a}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x3037, 0x12}, - {0x3108, 0x01}, - {0x3630, 0x36}, - {0x3631, 0x0e}, - {0x3632, 0xe2}, - {0x3633, 0x12}, - {0x3621, 0xe0}, - {0x3704, 0xa0}, - {0x3703, 0x5a}, - {0x3715, 0x78}, - {0x3717, 0x01}, - {0x370b, 0x60}, - {0x3705, 0x1a}, - {0x3905, 0x02}, - {0x3906, 0x10}, - {0x3901, 0x0a}, - {0x3731, 0x12}, - {0x3600, 0x08}, - {0x3601, 0x33}, - {0x302d, 0x60}, - {0x3620, 0x52}, - {0x371b, 0x20}, - {0x471c, 0x50}, - {0x3a13, 0x43}, - {0x3a18, 0x00}, - {0x3a19, 0xf8}, - {0x3635, 0x13}, - {0x3636, 0x03}, - {0x3634, 0x40}, - {0x3622, 0x01}, - {0x3c01, 0x34}, - {0x3c04, 0x28}, - {0x3c05, 0x98}, - {0x3c06, 0x00}, - {0x3c07, 0x08}, - {0x3c08, 0x00}, - {0x3c09, 0x1c}, - {0x3c0a, 0x9c}, - {0x3c0b, 0x40}, - {0x3820, 0x41}, - {0x3821, 0x07}, - {0x3814, 0x31}, - {0x3815, 0x31}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, - {0x3803, 0x04}, - {0x3804, 0x0a}, - {0x3805, 0x3f}, - {0x3806, 0x07}, - {0x3807, 0x9b}, - {0x3808, 0x03}, - {0x3809, 0x20}, - {0x380a, 0x02}, - {0x380b, 0x58}, - {0x380c, 0x07}, - {0x380d, 0x68}, - {0x380e, 0x03}, - {0x380f, 0xd8}, - {0x3810, 0x00}, - {0x3811, 0x10}, - {0x3812, 0x00}, - {0x3813, 0x06}, - {0x3618, 0x00}, - {0x3612, 0x29}, - {0x3708, 0x64}, - {0x3709, 0x52}, - {0x370c, 0x03}, - {0x3a02, 0x03}, - {0x3a03, 0xd8}, - {0x3a08, 0x01}, - {0x3a09, 0x27}, - {0x3a0a, 0x00}, - {0x3a0b, 0xf6}, - {0x3a0e, 0x03}, - {0x3a0d, 0x04}, - {0x3a14, 0x03}, - {0x3a15, 0xd8}, - {0x4001, 0x02}, - {0x4004, 0x02}, - {0x3000, 0x00}, - {0x3002, 0x1c}, - {0x3004, 0xff}, - {0x3006, 0xc3}, - {0x300e, 0x58}, - {0x302e, 0x00}, - {0x4740, 0x20}, - {0x4300, 0x30}, - {0x501f, 0x00}, - {0x4713, 0x03}, - {0x4407, 0x04}, - {0x440e, 0x00}, - {0x460b, 0x35}, - {0x460c, 0x20}, - {0x4837, 0x22}, - {0x3824, 0x02}, - {0x5000, 0xa7}, - {0x5001, 0xa3}, - {0x5180, 0xff}, - {0x5181, 0xf2}, - {0x5182, 0x00}, - {0x5183, 0x14}, - {0x5184, 0x25}, - {0x5185, 0x24}, - {0x5186, 0x09}, - {0x5187, 0x09}, - {0x5188, 0x09}, - {0x5189, 0x75}, - {0x518a, 0x54}, - {0x518b, 0xe0}, - {0x518c, 0xb2}, - {0x518d, 0x42}, - {0x518e, 0x3d}, - {0x518f, 0x56}, - {0x5190, 0x46}, - {0x5191, 0xf8}, - {0x5192, 0x04}, - {0x5193, 0x70}, - {0x5194, 0xf0}, - {0x5195, 0xf0}, - {0x5196, 0x03}, - {0x5197, 0x01}, - {0x5198, 0x04}, - {0x5199, 0x12}, - {0x519a, 0x04}, - {0x519b, 0x00}, - {0x519c, 0x06}, - {0x519d, 0x82}, - {0x519e, 0x38}, - {0x5381, 0x1e}, - {0x5382, 0x5b}, - {0x5383, 0x08}, - {0x5384, 0x0a}, - {0x5385, 0x7e}, - {0x5386, 0x88}, - {0x5387, 0x7c}, - {0x5388, 0x6c}, - {0x5389, 0x10}, - {0x538a, 0x01}, - {0x538b, 0x98}, - {0x5300, 0x08}, - {0x5301, 0x30}, - {0x5302, 0x10}, - {0x5303, 0x00}, - {0x5304, 0x08}, - {0x5305, 0x30}, - {0x5306, 0x08}, - {0x5307, 0x16}, - {0x5309, 0x08}, - {0x530a, 0x30}, - {0x530b, 0x04}, - {0x530c, 0x06}, - {0x5480, 0x01}, - {0x5481, 0x08}, - {0x5482, 0x14}, - {0x5483, 0x28}, - {0x5484, 0x51}, - {0x5485, 0x65}, - {0x5486, 0x71}, - {0x5487, 0x7d}, - {0x5488, 0x87}, - {0x5489, 0x91}, - {0x548a, 0x9a}, - {0x548b, 0xaa}, - {0x548c, 0xb8}, - {0x548d, 0xcd}, - {0x548e, 0xdd}, - {0x548f, 0xea}, - {0x5490, 0x1d}, - {0x5580, 0x02}, - {0x5583, 0x40}, - {0x5584, 0x10}, - {0x5589, 0x10}, - {0x558a, 0x00}, - {0x558b, 0xf8}, - {0x5800, 0x23}, - {0x5801, 0x14}, - {0x5802, 0x0f}, - {0x5803, 0x0f}, - {0x5804, 0x12}, - {0x5805, 0x26}, - {0x5806, 0x0c}, - {0x5807, 0x08}, - {0x5808, 0x05}, - {0x5809, 0x05}, - {0x580a, 0x08}, - {0x580b, 0x0d}, - {0x580c, 0x08}, - {0x580d, 0x03}, - {0x580e, 0x00}, - {0x580f, 0x00}, - {0x5810, 0x03}, - {0x5811, 0x09}, - {0x5812, 0x07}, - {0x5813, 0x03}, - {0x5814, 0x00}, - {0x5815, 0x01}, - {0x5816, 0x03}, - {0x5817, 0x08}, - {0x5818, 0x0d}, - {0x5819, 0x08}, - {0x581a, 0x05}, - {0x581b, 0x06}, - {0x581c, 0x08}, - {0x581d, 0x0e}, - {0x581e, 0x29}, - {0x581f, 0x17}, - {0x5820, 0x11}, - {0x5821, 0x11}, - {0x5822, 0x15}, - {0x5823, 0x28}, - {0x5824, 0x46}, - {0x5825, 0x26}, - {0x5826, 0x08}, - {0x5827, 0x26}, - {0x5828, 0x64}, - {0x5829, 0x26}, - {0x582a, 0x24}, - {0x582b, 0x22}, - {0x582c, 0x24}, - {0x582d, 0x24}, - {0x582e, 0x06}, - {0x582f, 0x22}, - {0x5830, 0x40}, - {0x5831, 0x42}, - {0x5832, 0x24}, - {0x5833, 0x26}, - {0x5834, 0x24}, - {0x5835, 0x22}, - {0x5836, 0x22}, - {0x5837, 0x26}, - {0x5838, 0x44}, - {0x5839, 0x24}, - {0x583a, 0x26}, - {0x583b, 0x28}, - {0x583c, 0x42}, - {0x583d, 0xce}, - {0x5025, 0x00}, - {0x3a0f, 0x30}, - {0x3a10, 0x28}, - {0x3a1b, 0x30}, - {0x3a1e, 0x26}, - {0x3a11, 0x60}, - {0x3a1f, 0x14}, - {0x3008, 0x02}, - {0x302c, 0xc2}, - {SEQUENCE_END, 0x00} -}; - -/* 720p 15fps @ 1280x720 */ - -static struct reginfo sensor_720p[]= -{ - {0x3503, 0x00}, - - {0x3c07,0x07}, - {0x3803,0xfa}, - {0x3806,0x06},//// - {0x3807,0xa9}, - {0x3808,0x05}, - {0x3809,0x00}, - {0x380a,0x02}, - {0x380b,0xd0}, - {0x380c,0x07}, - {0x380d,0x64}, - {0x380e,0x02}, - {0x380f,0xe4}, - {0x3813,0x04}, - {0x3a02,0x02}, - {0x3a03,0xe4}, - {0x3a08,0x01},/// - {0x3a09,0xbc},//// - {0x3a0a,0x01},/// - {0x3a0b,0x72},//// - {0x3a0e,0x01}, - {0x3a0d,0x02}, - {0x3a14,0x02}, - {0x3a15,0xe4}, - - {0x3820, 0x41}, //ddl@rock-chips.com add start: qsxvga -> 720p isn't stream on - {0x3821, 0x07}, - {0x3814, 0x31}, - {0x3815, 0x31}, - - {0x3618, 0x00}, - {0x3612, 0x29}, - {0x3709, 0x52}, - {0x370c, 0x03}, - {0x3a02, 0x03}, - {0x3a03, 0xd8}, - {0x3a08 ,0x01},/// - {0x3a09, 0x27},/// - {0x3a0a, 0x00},/// - {0x3a0b, 0xf6},/// - {0x3a0e, 0x03}, - {0x3a0d, 0x04}, - {0x3a14, 0x03}, - {0x3a15, 0xd8}, - {0x4004, 0x02}, - {0x3002, 0x1c},//// - {0x4713, 0x03},//////ddl@rock-chips.com add end - - {0x3002,0x00},/// - {0x4713,0x02},/// - {0x4837,0x16}, - {0x3824,0x04},/// - {0x5001,0x83}, - {0x3035,0x21}, - {0x3036,0x46}, - - {0x4837, 0x22}, - {0x5001, 0xa3}, - - {SEQUENCE_END, 0x00} -}; - -/* 1080p, 0x15fps, 0xyuv @1920x1080 */ - -static struct reginfo sensor_1080p[]= -{ - - {SEQUENCE_END, 0x00} -}; - -/* 2592X1944 QSXGA */ -static struct reginfo sensor_qsxga[] = -{ -#if 0 - {0x3503, 0x07}, - {0x3a00, 0x78}, - {0x350c, 0x00}, - {0x350d, 0x00}, - {0x3c07, 0x07}, - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x0a}, - {0x3809, 0x20}, - {0x380a, 0x07}, - {0x380b, 0x98}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x2c}, - {0x5001, 0x83}, -#else - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x0a}, - {0x3809, 0x20}, - {0x380a, 0x07}, - {0x380b, 0x98}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3811, 0x10}, // - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, //4b - {0x3708, 0x64}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x5000, 0xa7}, - {0x5001, 0x83}, - {0x519e, 0x38}, - {0x5381, 0x1e}, - {0x5382, 0x5b}, - {0x5383, 0x08}, - {0x460b, 0x37}, - {0x460c, 0x20}, - {0x3824, 0x01}, - {0x4005, 0x1A}, -#endif - {SEQUENCE_END, 0x00} -}; -/* 2048*1536 QXGA */ -static struct reginfo sensor_qxga[] = -{ -#if 0 - {0x3503, 0x07}, - {0x3a00, 0x78}, - {0x350c, 0x00}, - {0x350d, 0x00}, - {0x3c07, 0x07}, - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x08}, - {0x3809, 0x00}, - {0x380a, 0x06}, - {0x380b, 0x00}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x2c}, - {0x5001, 0xa3}, -#endif - {SEQUENCE_END, 0x00} -}; - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ -#if 0 - {0x3503, 0x07}, - {0x3a00, 0x78}, - {0x350c, 0x00}, - {0x350d, 0x00}, - {0x3c07, 0x07}, - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x06}, - {0x3809, 0x40}, - {0x380a, 0x04}, - {0x380b, 0xb0}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x2c}, - {0x5001, 0xa3}, -#endif - {SEQUENCE_END, 0x00} -}; - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ -#if 0 - {0x3503, 0x07}, - {0x3a00, 0x78}, - {0x350c, 0x00}, - {0x350d, 0x00}, - {0x3c07, 0x07}, - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x05}, - {0x3809, 0x00}, - {0x380a, 0x04}, - {0x380b, 0x00}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x2c}, - {0x5001, 0xa3}, -#endif - {SEQUENCE_END, 0x00} -}; -/* 1024X768 XGA */ -static struct reginfo sensor_xga[] = -{ -#if 0 - {0x3503, 0x07}, - {0x3a00, 0x78}, - {0x350c, 0x00}, - {0x350d, 0x00}, - {0x3c07, 0x07}, - {0x3820, 0x40}, - {0x3821, 0x06}, - {0x3814, 0x11}, - {0x3815, 0x11}, - {0x3803, 0x00}, - {0x3807, 0x9f}, - {0x3808, 0x05}, - {0x3809, 0x00}, - {0x380a, 0x04}, - {0x380b, 0x00}, - {0x380c, 0x0b}, - {0x380d, 0x1c}, - {0x380e, 0x07}, - {0x380f, 0xb0}, - {0x3813, 0x04}, - {0x3618, 0x04}, - {0x3612, 0x2b}, - {0x3709, 0x12}, - {0x370c, 0x00}, - {0x3a02, 0x07}, - {0x3a03, 0xb0}, - {0x3a0e, 0x06}, - {0x3a0d, 0x08}, - {0x3a14, 0x07}, - {0x3a15, 0xb0}, - {0x4004, 0x06}, - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x2c}, - {0x5001, 0xa3}, -#endif - {SEQUENCE_END, 0x00} -}; -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0x3503, 0x00}, - {0x3c07, 0x08}, - {0x3820, 0x41}, - {0x3821, 0x07}, - {0x3814, 0x31}, - {0x3815, 0x31}, - {0x3803, 0x04}, - {0x3806, 0x07},/// - {0x3807, 0x9b}, - {0x3808, 0x03}, - {0x3809, 0x20}, - {0x380a, 0x02}, - {0x380b, 0x58}, - {0x380c, 0x07}, - {0x380d, 0x68}, - {0x380e, 0x03}, - {0x380f, 0xd8}, - {0x3813, 0x06}, - {0x3618, 0x00}, - {0x3612, 0x29}, - {0x3709, 0x52}, - {0x370c, 0x03}, - {0x3a02, 0x03}, - {0x3a03, 0xd8}, - {0x3a08 ,0x01},/// - {0x3a09, 0x27},/// - {0x3a0a, 0x00},/// - {0x3a0b, 0xf6},/// - {0x3a0e, 0x03}, - {0x3a0d, 0x04}, - {0x3a14, 0x03}, - {0x3a15, 0xd8}, - {0x4004, 0x02}, - {0x3002, 0x1c},//// - {0x4713, 0x03},//// - {0x3035, 0x21}, - {0x3036, 0x46}, - {0x4837, 0x22}, - {0x3824, 0x02},//// - {0x5001, 0xa3}, - {SEQUENCE_END, 0x00} -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ - - {SEQUENCE_END, 0x00} -}; -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - - {SEQUENCE_END, 0x00} -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ - - {SEQUENCE_END, 0x00} -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - - {SEQUENCE_END, 0x00} -}; -#endif -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - {0x4300,0x30}, - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - {0x4300,0x32}, - {SEQUENCE_END, 0x00} -}; - - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0x3406 ,0x00}, - {0x5192 ,0x04}, - {0x5191 ,0xf8}, - {0x5193 ,0x70}, - {0x5194 ,0xf0}, - {0x5195 ,0xf0}, - {0x518d ,0x3d}, - {0x518f ,0x54}, - {0x518e ,0x3d}, - {0x5190 ,0x54}, - {0x518b ,0xa8}, - {0x518c ,0xa8}, - {0x5187 ,0x18}, - {0x5188 ,0x18}, - {0x5189 ,0x6e}, - {0x518a ,0x68}, - {0x5186 ,0x1c}, - {0x5181 ,0x50}, - {0x5184 ,0x25}, - {0x5182 ,0x11}, - {0x5183 ,0x14}, - {0x5184 ,0x25}, - {0x5185 ,0x24}, - {SEQUENCE_END, 0x00} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0x3406 ,0x1 }, - {0x3400 ,0x6 }, - {0x3401 ,0x48}, - {0x3402 ,0x4 }, - {0x3403 ,0x0 }, - {0x3404 ,0x4 }, - {0x3405 ,0xd3 }, - {SEQUENCE_END, 0x00} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - {0x3406 ,0x1 }, - {0x3400 ,0x6 }, - {0x3401 ,0x1c}, - {0x3402 ,0x4 }, - {0x3403 ,0x0 }, - {0x3404 ,0x4 }, - {0x3405 ,0xf3}, - {SEQUENCE_END, 0x00} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - {0x3406 ,0x1 }, - {0x3400 ,0x5 }, - {0x3401 ,0x48}, - {0x3402 ,0x4 }, - {0x3403 ,0x0 }, - {0x3404 ,0x7 }, - {0x3405 ,0xcf}, - {SEQUENCE_END, 0x00} -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - {0x3406 ,0x1 }, - {0x3400 ,0x4 }, - {0x3401 ,0x10}, - {0x3402 ,0x4 }, - {0x3403 ,0x0 }, - {0x3404 ,0x8 }, - {0x3405 ,0xb6}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Brightness1[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Brightness2[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Brightness3[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Brightness4[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Brightness5[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0x5001, 0x7f}, - {0x5580, 0x00}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Effect_WandB[] = -{ - {0x5001, 0xff}, - {0x5580, 0x18}, - {0x5583, 0x80}, - {0x5584, 0x80}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Effect_Sepia[] = -{ - {0x5001, 0xff}, - {0x5580, 0x18}, - {0x5583, 0x40}, - {0x5584, 0xa0}, - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - //Negative - {0x5001, 0xff}, - {0x5580, 0x40}, - {SEQUENCE_END, 0x00} -};static struct reginfo sensor_Effect_Bluish[] = -{ - // Bluish - {0x5001, 0xff}, - {0x5580, 0x18}, - {0x5583, 0xa0}, - {0x5584, 0x40}, - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - // Greenish - {0x5001, 0xff}, - {0x5580, 0x18}, - {0x5583, 0x60}, - {0x5584, 0x60}, - {SEQUENCE_END, 0x00} -}; -/*static struct reginfo sensor_Effect_Reddish[] = -{ - // Greenish - {0x5001, 0xff}, - {0x5580, 0x18}, - {0x5583, 0x80}, - {0x5584, 0xc0}, - {SEQUENCE_END, 0x00} -};*/ - -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - {0x3a0f, 0x10}, - {0x3a10, 0x08}, - {0x3a1b, 0x10}, - {0x3a1e, 0x08}, - {0x3a11, 0x20}, - {0x3a1f, 0x10}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Exposure1[]= -{ - {0x3a0f, 0x20}, - {0x3a10, 0x18}, - {0x3a11, 0x41}, - {0x3a1b, 0x20}, - {0x3a1e, 0x18}, - {0x3a1f, 0x10}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Exposure2[]= -{ - {0x3a0f, 0x30}, - {0x3a10, 0x28}, - {0x3a11, 0x61}, - {0x3a1b, 0x30}, - {0x3a1e, 0x28}, - {0x3a1f, 0x10}, - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Exposure3[]= -{ - {0x3a0f, 0x38}, - {0x3a10, 0x30}, - {0x3a11, 0x61}, - {0x3a1b, 0x38}, - {0x3a1e, 0x30}, - {0x3a1f, 0x10}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Exposure4[]= -{ - {0x3a0f, 0x40}, - {0x3a10, 0x38}, - {0x3a11, 0x71}, - {0x3a1b, 0x40}, - {0x3a1e, 0x38}, - {0x3a1f, 0x10}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Exposure5[]= -{ - {0x3a0f, 0x50}, - {0x3a10, 0x48}, - {0x3a11, 0x90}, - {0x3a1b, 0x50}, - {0x3a1e, 0x48}, - {0x3a1f, 0x20}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Exposure6[]= -{ - {0x3a0f, 0x60}, - {0x3a10, 0x58}, - {0x3a11, 0xa0}, - {0x3a1b, 0x60}, - {0x3a1e, 0x58}, - {0x3a1f, 0x20}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {SEQUENCE_END, 0x00} -};static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Contrast1[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Contrast2[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Contrast3[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Contrast4[]= -{ - {SEQUENCE_END, 0x00} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Contrast6[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_MirrorOff[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif -#if CONFIG_SENSOR_Scene -static struct reginfo sensor_SceneAuto[] = -{ - {0x3a00 , 0x78}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_SceneNight[] = -{ - //15fps ~ 3.75fps night mode for 60/50Hz light environment, 24Mhz clock input,24Mzh pclk - {0x3034 ,0x1a}, - {0x3035 ,0x21}, - {0x3036 ,0x46}, - {0x3037 ,0x13}, - {0x3038 ,0x00}, - {0x3039 ,0x00}, - {0x3a00 ,0x7c}, - {0x3a08 ,0x01}, - {0x3a09 ,0x27}, - {0x3a0a ,0x00}, - {0x3a0b ,0xf6}, - {0x3a0d ,0x04}, - {0x3a0e ,0x04}, - {0x3a02 ,0x0b}, - {0x3a03 ,0x88}, - {0x3a14 ,0x0b}, - {0x3a15 ,0x88}, - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo sensor_Zoom1[] = -{ - {SEQUENCE_END, 0x00} -}; - -static struct reginfo sensor_Zoom2[] = -{ - {SEQUENCE_END, 0x00} -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {SEQUENCE_END, 0x00} -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL}; -#endif -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - /*{ - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - },*/ - { - .id = V4L2_CID_FOCUSZONE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "FocusZone Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - },{ - .id = V4L2_CID_FOCUS_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Focus Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #if CONFIG_SENSOR_FocusContinues - { - .id = V4L2_CID_FOCUS_CONTINUOUS, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Focus Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; -enum sensor_wq_cmd -{ - WqCmd_af_init, - WqCmd_af_single, - WqCmd_af_special_pos, - WqCmd_af_far_pos, - WqCmd_af_near_pos, - WqCmd_af_continues, - WqCmd_af_return_idle, -}; -enum sensor_wq_result -{ - WqRet_success = 0, - WqRet_fail = -1, - WqRet_inval = -2 -}; -struct sensor_work -{ - struct i2c_client *client; - struct delayed_work dwork; - enum sensor_wq_cmd cmd; - wait_queue_head_t done; - enum sensor_wq_result result; - bool wait; - int var; - int zone_center_pos[2]; -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int auto_focus; - int affm_reinit; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - struct reginfo *winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int enable; - unsigned int funmodule_state; -} sensor_info_priv_t; - - - -struct sensor_parameter -{ - unsigned short int preview_maxlines; - unsigned int preview_exposure; - unsigned short int preview_line_width; - unsigned short int preview_gain; - - unsigned short int capture_framerate; - unsigned short int preview_framerate; - char awb[6]; -}; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - struct sensor_parameter parameter; - struct workqueue_struct *sensor_wq; - struct mutex wq_lock; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } - return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - -} - - -#if CONFIG_SENSOR_WRITE_REGS -static int sensor_write_regs(struct i2c_client *client, u8 *reg_info, int num) -{ - int err=0,cnt; - struct i2c_msg msg[1]; - - msg->len = num; - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = reg_info; - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - - cnt= 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg failed, try to write again!\n", SENSOR_NAME_STRING()); - udelay(10); - } - } - - return err; - -} - -#endif - - - - -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u16 reg, u8 val) -{ - int err,cnt; - u8 buf[3]; - struct i2c_msg msg[1]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - buf[2] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[2]; - - buf[0] = reg >> 8; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err = 0, cnt; - int i = 0; -#if CONFIG_SENSOR_Focus - struct sensor *sensor = to_sensor(client); -#endif -#if CONFIG_SENSOR_I2C_RDWRCHK - char valchk; -#endif -#if CONFIG_SENSOR_WRITE_REGS - int j = 0, reg_num; - u8 *ptemp, *phead; - int reg_length; -#endif - - cnt = 0; - if (sensor_task_lock(client, 1) < 0) - goto sensor_write_array_end; - while (regarray[i].reg != SEQUENCE_END) { - #if CONFIG_SENSOR_Focus - if ((regarray == sensor_af_firmware) && (sensor->info_priv.enable == 0)) { - SENSOR_DG("%s disable, Download af firmware terminated!\n",SENSOR_NAME_STRING()); - err = -EINVAL; - goto sensor_write_array_end; - } - #endif - -#if CONFIG_SENSOR_WRITE_REGS - - j = i; - reg_num = 2; - reg_length = 0x0001; - - while((regarray[i].reg + reg_length) == regarray[i+1].reg) { - i++; - reg_num++; - if(reg_num >= WRITE_REGS_NUM) - break; - } - - if(reg_num > 2) { - - int size_num; - size_num = reg_num + 1; - - ptemp = phead = (u8*)kmalloc((size_num+10)*sizeof(u8),GFP_KERNEL); - if (!phead) { - SENSOR_DG("-------------write registers allocate memory fail!!!\n"); - i = j; - err = sensor_write(client, regarray[i].reg, regarray[i].val); - } else { - *phead = regarray[j].reg >> 8; - *(ptemp+1) = regarray[j].reg & 0xFF; - ptemp += 2; - for( ; reg_num > 0; reg_num --, j++) { - *ptemp ++ = regarray[j].val; - } - - ptemp = phead; - err = sensor_write_regs(client, ptemp,size_num); - kfree(phead); - } - }else{ - err = sensor_write(client, regarray[i].reg, regarray[i].val); - } -#else - err = sensor_write(client, regarray[i].reg, regarray[i].val); -#endif - if (err < 0) - { - if (cnt-- > 0) { - SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); - i = 0; - continue; - } else { - SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); - err = -EPERM; - goto sensor_write_array_end; - } - } else { - #if CONFIG_SENSOR_I2C_RDWRCHK - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - #endif - } - i++; - } - - #if CONFIG_SENSOR_Focus - if (((regarray->reg == SEQUENCE_PROPERTY) && (regarray->val == SEQUENCE_INIT)) - || (regarray == sensor_init_data)) { - sensor->info_priv.affm_reinit = 1; - } - #endif - -sensor_write_array_end: - sensor_task_lock(client,0); - return err; -} -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) -{ - int cnt; - int i = 0; - char valchk; - - cnt = 0; - valchk = 0; - while (regarray[i].reg != 0) - { - sensor_read(client, regarray[i].reg, &valchk); - if (valchk != regarray[i].val) - SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); - - i++; - } - return 0; -} -#endif -#if CONFIG_SENSOR_Focus -struct af_cmdinfo -{ - char cmd_tag; - char cmd_para[4]; - char validate_bit; -}; -static int sensor_af_cmdset(struct i2c_client *client, int cmd_main, struct af_cmdinfo *cmdinfo) -{ - int i; - char read_tag=0xff,cnt; - - if (cmdinfo) { - for (i=0; i<4; i++) { - if (cmdinfo->validate_bit & (1<cmd_para[i])) { - SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); - goto sensor_af_cmdset_err; - } - SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); - } - } - - if (cmdinfo->validate_bit & 0x80) { - if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) { - SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); - goto sensor_af_cmdset_err; - } - SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); - } - - } else { - if (sensor_write(client, CMD_ACK_Reg, 0x01)) { - SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main); - goto sensor_af_cmdset_err; - } - SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x no tag) success!\n",SENSOR_NAME_STRING(),cmd_main); - } - - if (sensor_write(client, CMD_MAIN_Reg, cmd_main)) { - SENSOR_TR("%s write CMD_MAIN_Reg(main:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main); - goto sensor_af_cmdset_err; - } - - cnt = 0; - do - { - msleep(5); - if (sensor_read(client,CMD_ACK_Reg,&read_tag)){ - SENSOR_TR("%s[%d] read TAG failed\n",SENSOR_NAME_STRING(),__LINE__); - break; - } - } while((read_tag != 0x00)&& (cnt++<100)); - - SENSOR_DG("%s write CMD_MAIN_Reg(main:0x%x read tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,read_tag); - return 0; -sensor_af_cmdset_err: - return -1; -} - -static int sensor_af_idlechk(struct i2c_client *client) -{ - int ret = 0; - char state; - struct af_cmdinfo cmdinfo; - - SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__); - - cmdinfo.cmd_tag = 0x01; - cmdinfo.validate_bit = 0x80; - ret = sensor_af_cmdset(client, ReturnIdle_Cmd, &cmdinfo); - if(0 != ret) { - SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); - ret = -1; - goto sensor_af_idlechk_end; - } - - - do{ - ret = sensor_read(client, CMD_ACK_Reg, &state); - if (ret != 0){ - SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); - ret = -1; - goto sensor_af_idlechk_end; - } - }while(0x00 != state); - - -sensor_af_idlechk_end: - return ret; -} -static int sensor_af_touch_zone(struct i2c_client *client, int *zone_center_pos) -{ - int ret = 0; - struct af_cmdinfo cmdinfo; - - cmdinfo.cmd_tag = 0x01; - cmdinfo.validate_bit = 0x83; - if (zone_center_pos[0]<=8) - cmdinfo.cmd_para[0] = 0; - else if ((zone_center_pos[0]>8) && (zone_center_pos[0]<72)) - cmdinfo.cmd_para[0] = zone_center_pos[0]-8; - else - cmdinfo.cmd_para[0] = 72; - - if (zone_center_pos[1]<=6) - cmdinfo.cmd_para[1] = 0; - else if ((zone_center_pos[1]>6) && (zone_center_pos[1]<54)) - cmdinfo.cmd_para[1] = zone_center_pos[1]-6; - else - cmdinfo.cmd_para[1] = 54; - - ret = sensor_af_cmdset(client, TouchZoneConfig_Cmd, &cmdinfo); - if(0 != ret) { - SENSOR_TR("%s touch zone config error!\n",SENSOR_NAME_STRING()); - ret = -1; - goto sensor_af_zone_end; - } -sensor_af_zone_end: - return ret; -} -static int sensor_af_single(struct i2c_client *client) -{ - int ret = 0; - char state,cnt; - struct af_cmdinfo cmdinfo; - char s_zone[5],i; - - cmdinfo.cmd_tag = 0x01; - cmdinfo.validate_bit = 0x80; - ret = sensor_af_cmdset(client, SingleFocus_Cmd, &cmdinfo); - if(0 != ret) { - SENSOR_TR("%s single focus mode set error!\n",SENSOR_NAME_STRING()); - ret = -1; - goto sensor_af_single_end; - } - - cnt = 0; - do - { - if (cnt != 0) { - msleep(1); - } - cnt++; - ret = sensor_read(client, STA_FOCUS_Reg, &state); - if (ret != 0){ - SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); - ret = -1; - goto sensor_af_single_end; - } - }while((state == S_FOCUSING) && (cnt<100)); - - if (state != S_FOCUSED) { - SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state); - ret = -1; - goto sensor_af_single_end; - } else { - SENSOR_DG("%s[%d] single focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); - } -sensor_af_single_end: - return ret; -} - -static int sensor_af_const(struct i2c_client *client) -{ - int ret = 0; - struct af_cmdinfo cmdinfo; - - - cmdinfo.cmd_tag = 0x01; - cmdinfo.cmd_para[0] = 0x00; - cmdinfo.validate_bit = 0x81; - - if (sensor_af_cmdset(client, ConstFocus_Cmd, &cmdinfo)) { - SENSOR_TR("%s[%d] const focus mode set error!\n",SENSOR_NAME_STRING(),__LINE__); - ret = -1; - goto sensor_af_const_end; - } else { - SENSOR_DG("%s[%d] const focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); - } -sensor_af_const_end: - return ret; -} -static int sensor_af_pause2capture(struct i2c_client *client) -{ - int ret = 0; - - if (sensor_af_cmdset(client, PauseFocus_Cmd, NULL)) { - SENSOR_TR("%s pause focus mode set error!\n",SENSOR_NAME_STRING()); - ret = -1; - goto sensor_af_pause_end; - } -sensor_af_pause_end: - return ret; -} - -static int sensor_af_init(struct i2c_client *client) -{ - int ret = 0, cnt; - char state; - - ret = sensor_write_array(client, sensor_af_firmware); - if (ret != 0) { - SENSOR_TR("%s Download firmware failed\n",SENSOR_NAME_STRING()); - ret = -1; - goto sensor_af_init_end; - } - - cnt = 0; - do - { - msleep(1); - if (cnt++ > 500) - break; - ret = sensor_read(client, STA_FOCUS_Reg, &state); - if (ret != 0){ - SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); - ret = -1; - goto sensor_af_init_end; - } - } while (state != S_IDLE); - - if (state != S_IDLE) { - SENSOR_TR("%s focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),state); - ret = -1; - goto sensor_af_init_end; - } - -sensor_af_init_end: - SENSOR_DG("%s %s ret:0x%x \n",SENSOR_NAME_STRING(),__FUNCTION__,ret); - return ret; -} - -static int sensor_af_downfirmware(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - int ret=0; - struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_mbus_framefmt mf; - - SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__); - - if (sensor_af_init(client)) { - sensor->info_priv.funmodule_state &= (~SENSOR_AF_IS_OK); - ret = -1; - } else { - sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; - - mf.width = icd->user_width; - mf.height = icd->user_height; - mf.code = sensor->info_priv.fmt.code; - mf.colorspace = sensor->info_priv.fmt.colorspace; - mf.field = V4L2_FIELD_NONE; - if (sensor_fmt_videochk(NULL, &mf) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ - ret = sensor_af_const(client); - } else { - switch (sensor->info_priv.auto_focus) - { - case SENSOR_AF_MODE_AUTO: - { - ret = sensor_af_single(client); - break; - } - case SENSOR_AF_MODE_CLOSE: - { - ret = 0; - break; - } - case SENSOR_AF_MODE_CONTINUOUS: - { - ret = sensor_af_const(client); - break; - } - default: - { - SENSOR_DG("%s focus mode(0x%x) is unkonwn\n",SENSOR_NAME_STRING(),sensor->info_priv.auto_focus); - goto sensor_af_downfirmware_end; - } - } - } - SENSOR_DG("%s sensor_af_downfirmware set focus mode(0x%x) ret:0x%x\n",SENSOR_NAME_STRING(), sensor->info_priv.auto_focus,ret); - } - -sensor_af_downfirmware_end: - - return ret; -} -static void sensor_af_workqueue(struct work_struct *work) -{ - struct sensor_work *sensor_work = container_of(work, struct sensor_work, dwork.work); - struct i2c_client *client = sensor_work->client; - struct sensor *sensor = to_sensor(client); - struct af_cmdinfo cmdinfo; - - SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd); - - mutex_lock(&sensor->wq_lock); - - switch (sensor_work->cmd) - { - case WqCmd_af_init: - { - if (sensor_af_downfirmware(client) < 0) { - SENSOR_TR("%s Sensor_af_init is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); - } - break; - } - case WqCmd_af_single: - { - if ((sensor_work->zone_center_pos[0] >=0) && (sensor_work->zone_center_pos[1]>=0)) - sensor_af_touch_zone(client,sensor_work->zone_center_pos); - - if (sensor_af_single(client) < 0) { - SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); - sensor_work->result = WqRet_fail; - } else { - sensor_work->result = WqRet_success; - } - break; - } - case WqCmd_af_special_pos: - { - sensor_af_idlechk(client); - - cmdinfo.cmd_tag = StepFocus_Spec_Tag; - cmdinfo.cmd_para[0] = sensor_work->var; - cmdinfo.validate_bit = 0x81; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_near_pos: - { - sensor_af_idlechk(client); - cmdinfo.cmd_tag = StepFocus_Near_Tag; - cmdinfo.validate_bit = 0x80; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_far_pos: - { - sensor_af_idlechk(client); - cmdinfo.cmd_tag = StepFocus_Far_Tag; - cmdinfo.validate_bit = 0x80; - if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_continues: - { - if (sensor_af_const(client) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - case WqCmd_af_return_idle: - { - if (sensor_af_idlechk(client) < 0) - sensor_work->result = WqRet_fail; - else - sensor_work->result = WqRet_success; - break; - } - default: - SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING()); - break; - } -set_end: - if (sensor_work->wait == false) { - kfree((void*)sensor_work); - } else { - wake_up(&sensor_work->done); - } - mutex_unlock(&sensor->wq_lock); - return; -} - -static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait, int *zone_pos) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - struct sensor_work *wk; - int ret=0; - - if (sensor->sensor_wq == NULL) { - ret = -EINVAL; - goto sensor_af_workqueue_set_end; - } - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) != SENSOR_AF_IS_OK) { - if (cmd != WqCmd_af_init) { - SENSOR_TR("%s %s cmd(%d) ingore,because af module isn't ready!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - ret = -1; - goto sensor_af_workqueue_set_end; - } - } - - wk = kzalloc(sizeof(struct sensor_work), GFP_KERNEL); - if (wk) { - wk->client = client; - INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue); - wk->cmd = cmd; - wk->result = WqRet_inval; - wk->wait = wait; - wk->var = var; - - if (zone_pos) { - if (*zone_pos || *(zone_pos+1) || *(zone_pos+2) || *(zone_pos+3)) { - *zone_pos += 1000; - *(zone_pos+1) += 1000; - *(zone_pos+2) += 1000; - *(zone_pos+3) += 1000; - wk->zone_center_pos[0] = ((*zone_pos + *(zone_pos+2))>>1)*80/2000; - wk->zone_center_pos[1] = ((*(zone_pos+1) + *(zone_pos+3))>>1)*60/2000; - } else { - #if CONFIG_SENSOR_FocusCenterInCapture - wk->zone_center_pos[0] = 32; - wk->zone_center_pos[1] = 24; - #else - wk->zone_center_pos[0] = -1; - wk->zone_center_pos[1] = -1; - #endif - } - } - - init_waitqueue_head(&wk->done); - - /* ddl@rock-chips.com: - * video_lock is been locked in v4l2_ioctl function, but auto focus may slow, - * As a result any other ioctl calls will proceed very, very slowly since each call - * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF - * and VIDIOC_DQBUF is sched. so unlock video_lock here. - */ - if (wait == true) { - queue_delayed_work(sensor->sensor_wq,&(wk->dwork),0); - mutex_unlock(&icd->video_lock); - if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) { //hhb - SENSOR_TR("%s %s cmd(%d) is timeout!\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - } - ret = wk->result; - kfree((void*)wk); - mutex_lock(&icd->video_lock); - } else { - queue_delayed_work(sensor->sensor_wq,&(wk->dwork),msecs_to_jiffies(10)); - } - - } else { - SENSOR_TR("%s %s cmd(%d) ingore,because struct sensor_work malloc failed!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - ret = -1; - } -sensor_af_workqueue_set_end: - return ret; -} -#endif -static int sensor_parameter_record(struct i2c_client *client) -{ - u8 ret_l,ret_m,ret_h; - int tp_l,tp_m,tp_h; - struct sensor *sensor = to_sensor(client); - - sensor_read(client,0x3a00, &ret_l); - sensor_write(client,0x3a00, ret_l&0xfb); - - sensor_write(client,0x3503,0x07); //stop AE/AG - sensor_read(client,0x3406, &ret_l); - sensor_write(client,0x3406, ret_l|0x01); - - sensor_read(client,0x3500,&ret_h); - sensor_read(client,0x3501, &ret_m); - sensor_read(client,0x3502, &ret_l); - tp_l = ret_l; - tp_m = ret_m; - tp_h = ret_h; - sensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); - - //Read back AGC Gain for preview - sensor_read(client,0x350b, &ret_l); - sensor->parameter.preview_gain = ret_l; - - SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n", - SENSOR_NAME_STRING(), tp_l,sensor->parameter.preview_exposure,tp_h, tp_m, tp_l); - return 0; -} -#define OV5640_FULL_PERIOD_PIXEL_NUMS_HTS (2844) -#define OV5640_FULL_PERIOD_LINE_NUMS_VTS (1968) -#define OV5640_PV_PERIOD_PIXEL_NUMS_HTS (1896) -#define OV5640_PV_PERIOD_LINE_NUMS_VTS (984) -static int sensor_ae_transfer(struct i2c_client *client) -{ - u8 ExposureLow; - u8 ExposureMid; - u8 ExposureHigh; - u16 ulCapture_Exposure; - u16 Preview_Maxlines; - u8 Gain; - u16 OV5640_g_iExtra_ExpLines; - struct sensor *sensor = to_sensor(client); - - //Preview_Maxlines = sensor->parameter.preview_line_width; - Preview_Maxlines = sensor->parameter.preview_maxlines; - Gain = sensor->parameter.preview_gain; - - - ulCapture_Exposure = (sensor->parameter.preview_exposure*OV5640_PV_PERIOD_PIXEL_NUMS_HTS)/OV5640_FULL_PERIOD_PIXEL_NUMS_HTS; - - SENSOR_DG("cap shutter calutaed = %d, 0x%x\n", ulCapture_Exposure,ulCapture_Exposure); - - // write the gain and exposure to 0x350* registers - sensor_write(client,0x350b, Gain); - - if (ulCapture_Exposure <= 1940) { - OV5640_g_iExtra_ExpLines = 0; - }else { - OV5640_g_iExtra_ExpLines = ulCapture_Exposure - 1940; - } - SENSOR_DG("Set Extra-line = %d, iExp = %d \n", OV5640_g_iExtra_ExpLines, ulCapture_Exposure); - - ExposureLow = (ulCapture_Exposure<<4)&0xff; - ExposureMid = (ulCapture_Exposure>>4)&0xff; - ExposureHigh = (ulCapture_Exposure>>12); - - sensor_write(client,0x350c, (OV5640_g_iExtra_ExpLines&0xff00)>>8); - sensor_write(client,0x350d, OV5640_g_iExtra_ExpLines&0xff); - sensor_write(client,0x3502, ExposureLow); - sensor_write(client,0x3501, ExposureMid); - sensor_write(client,0x3500, ExposureHigh); - - SENSOR_DG(" %s Write 0x350b=0x%02x 0x350c=0x%2x 0x350d=0x%2x 0x3502=0x%02x 0x3501=0x%02x 0x3500=0x%02x\n",SENSOR_NAME_STRING(), Gain, ExposureLow, ExposureMid, ExposureHigh); - mdelay(100); - return 0; -} - -static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - int ret = 0; - - SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); - - switch (cmd) - { - case Sensor_PowerDown: - { - if (icl->powerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(2); - if (icl->reset) - icl->reset(icd->pdev); - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - if(on == Flash_On){ - //flash off after 2 secs - hrtimer_cancel(&(flash_off_timer.timer)); - hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); - } - } - break; - } - default: - { - SENSOR_TR("%s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd); - break; - } - } - -sensor_power_end: - return ret; -} - -static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ - struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); - sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); - SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); - return 0; - -} - -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - char value; - int ret,pid = 0; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - ret = sensor_write(client, 0x3008, 0x80); - if (ret != 0) { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); //delay 5 microseconds - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x300a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x300b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); - - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - ret = sensor_write_array(client, sensor_init_data); - udelay(1000); //wait sensor power on,so that I2C write sensor registers would sucess hhb@rock-chips.con - - if (ret != 0) { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - sensor_task_lock(client,0); - sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - flash_off_timer.icd = icd; - flash_off_timer.timer.function = flash_off_func; - #endif - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - - sensor->info_priv.funmodule_state = SENSOR_INIT_IS_OK; - - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { - sensor_task_lock(client, 1); - sensor_write(client, 0x3017, 0x00); // FREX,VSYNC,HREF,PCLK,D9-D6 - sensor_write(client, 0x3018, 0x03); // D5-D0 - sensor_write(client,0x3019,0x00); // STROBE,SDA - sensor_task_lock(client, 0); - } - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - return 0; -} - -static struct reginfo sensor_power_down_sequence[]= -{ - {0x00,0x00} -}; - -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - return 0; -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret = 0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_svga; - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_xga; - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_720p; - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_1080p; - set_w = 1920; - set_h = 1080; - } - else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_qxga; - set_w = 2048; - set_h = 1536; - } - else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) - { - winseqe_set_addr = sensor_qsxga; - set_w = 2592; - set_h = 1944; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - - if (winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) - { - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - sensor_parameter_record(client); - #if CONFIG_SENSOR_Focus - if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CONTINUOUS) - sensor_af_pause2capture(client); - #endif - #if CONFIG_SENSOR_Flash - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - #endif - }else { /* ddl@rock-chips.com : Video */ - #if CONFIG_SENSOR_Flash - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - #endif - } - if ((sensor->info_priv.winseqe_cur_addr->reg == SEQUENCE_PROPERTY) && (sensor->info_priv.winseqe_cur_addr->val == SEQUENCE_INIT)) { - if (((winseqe_set_addr->reg == SEQUENCE_PROPERTY) && (winseqe_set_addr->val == SEQUENCE_NORMAL)) - || (winseqe_set_addr->reg != SEQUENCE_PROPERTY)) { - ret |= sensor_write_array(client,sensor_init_data); - udelay(1000); //wait sensor power on,so that I2C write sensor registers would sucess hhb@rock-chips.con - SENSOR_DG("\n%s reinit ret:0x%x \n",SENSOR_NAME_STRING(), ret); - } - } - - if ((winseqe_set_addr == sensor_qsxga) && (sensor->info_priv.winseqe_cur_addr == sensor_720p)) { - sensor_write_array(client, sensor_svga); - } - - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - sensor_ae_transfer(client); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.snap2preview == true) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - #if CONFIG_SENSOR_Focus - if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CLOSE) { - msleep(500); - } else { - sensor_af_workqueue_set(icd,WqCmd_af_return_idle,0,false,NULL); - if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CONTINUOUS) { - sensor_af_workqueue_set(icd,WqCmd_af_continues,0,false,NULL); - } - - msleep(300); - } - #else - msleep(500); - #endif - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - mf->width = set_w; - mf->height = set_h; -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) - { - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) - { - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) - { - set_w = 800; - set_h = 600; - } - else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) - { - set_w = 1024; - set_h = 768; - } - else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) - { - set_w = 1280; - set_h = 720; - } - else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) - { - set_w = 1600; - set_h = 1200; - } - else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) - { - set_w = 1920; - set_h = 1080; - } - else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) - { - set_w = 2048; - set_h = 1536; - } - else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) - { - set_w = 2592; - set_h = 1944; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n%s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) - { - *value = digitalzoom_total - digitalzoom_cur; - } - - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) - { - *value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += *value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Focus -static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int ret = 0; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (!qctrl_info) - return -EINVAL; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { - ret = sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true,NULL); - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EINVAL; - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - } - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } - - return ret; -} -static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int ret = 0; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE); - if (!qctrl_info) - return -EINVAL; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { - if (value > 0) { - ret = sensor_af_workqueue_set(icd, WqCmd_af_near_pos, 0, true,NULL); - } else { - ret = sensor_af_workqueue_set(icd, WqCmd_af_far_pos, 0, true,NULL); - } - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EINVAL; - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - } - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } - return ret; -} - -static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int *zone_pos) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int ret = 0; - - if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { - switch (value) - { - case SENSOR_AF_MODE_AUTO: - { - ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true, zone_pos); - break; - } - - /*case SENSOR_AF_MODE_MACRO: - { - ret = sensor_set_focus_absolute(icd, qctrl, 0xff); - break; - } - - case SENSOR_AF_MODE_INFINITY: - { - ret = sensor_set_focus_absolute(icd, qctrl, 0x00); - break; - } - */ - case SENSOR_AF_MODE_CONTINUOUS: - { - ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true,NULL); - break; - } - default: - SENSOR_TR("\n %s..%s AF value(0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,value); - break; - - } - - SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); - } else { - ret = -EACCES; - SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, - sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); - } - - return ret; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %d\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - sensor_set_focus_relative(icd, qctrl,ext_ctrl->value); - break; - } - case V4L2_CID_FOCUS_AUTO: - { - if (ext_ctrl->value) { - if ((ext_ctrl->value==1) || (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus)) { - if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO,ext_ctrl->rect) != 0) { - if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; - } - return -EINVAL; - } - } - if (ext_ctrl->value == 1) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; - } else if (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus){ - if (ext_ctrl->value == 0) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; - } - break; - } - case V4L2_CID_FOCUS_CONTINUOUS: - { - if (SENSOR_AF_MODE_CONTINUOUS != sensor->info_priv.auto_focus) { - if (ext_ctrl->value == 1) { - if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_CONTINUOUS,NULL) != 0) { - if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; - } - return -EINVAL; - } - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; - } - } else { - if (ext_ctrl->value == 0) - sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - #if CONFIG_SENSOR_Focus - struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_mbus_framefmt mf; - #endif - - if (enable == 1) { - sensor->info_priv.enable = 1; - #if CONFIG_SENSOR_Focus - mf.width = icd->user_width; - mf.height = icd->user_height; - mf.code = sensor->info_priv.fmt.code; - mf.colorspace = sensor->info_priv.fmt.colorspace; - mf.field = V4L2_FIELD_NONE; - /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ - if (sensor_fmt_capturechk(sd, &mf) == false) { - if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { - sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false,NULL); - sensor->info_priv.affm_reinit = 0; - } - } - #endif - } else if (enable == 0) { - sensor->info_priv.enable = 0; - #if CONFIG_SENSOR_Focus - flush_workqueue(sensor->sensor_wq); - #endif - } - return 0; -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char value; - int ret,pid = 0; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - /* soft reset */ - ret = sensor_write(client, 0x3008, 0x80); - if (ret != 0) { - SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - mdelay(5); //delay 5 microseconds - - /* check if it is an sensor sensor */ - ret = sensor_read(client, 0x300a, &value); - if (ret != 0) { - SENSOR_TR("read chip id high byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value << 8); - - ret = sensor_read(client, 0x300b, &value); - if (ret != 0) { - SENSOR_TR("read chip id low byte failed\n"); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - pid |= (value & 0xff); - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - return 0; - -sensor_video_probe_err: - return ret; -} -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0,i; - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - #if CONFIG_SENSOR_Flash //hhb - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - #endif - sensor_deactivate(client); - break; - } - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - printk("flash io:%d\n",sensor->sensor_gpio_res->gpio_flash); - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - sensor_controls[i].id=0xffff; - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - }else{ //two cameras are the same,need to deal diffrently ,zyc - for (i = 0; i < icd->ops->num_controls; i++) { - if(0xffff == icd->ops->controls[i].id){ - sensor_controls[i].id=V4L2_CID_FLASH; - } - } - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } - -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, - .s_stream = sensor_s_stream, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - sensor->info_priv.fmt = sensor_colour_fmts[0]; - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } else { - #if CONFIG_SENSOR_Focus - sensor->sensor_wq = create_singlethread_workqueue(SENSOR_NAME_STRING(_af_workqueue)); - if (sensor->sensor_wq == NULL) - SENSOR_TR("%s create fail!", SENSOR_NAME_STRING(_af_workqueue)); - mutex_init(&sensor->wq_lock); - #endif - } - hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - #if CONFIG_SENSOR_Focus - if (sensor->sensor_wq) { - destroy_workqueue(sensor->sensor_wq); - sensor->sensor_wq = NULL; - } - #endif - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - return i2c_add_driver(&sensor_i2c_driver); -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); - - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,1,0); +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_SENSOR_OV5640 +#define SENSOR_V4L2_IDENT V4L2_IDENT_OV5640 +#define SENSOR_ID 0x5640 +#define SENSOR_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 30000 +#define SENSOR_1080P_FPS 15000 + +#define SENSOR_REGISTER_LEN 2 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect + |CFG_Scene|CFG_Focus + |CFG_FocusZone); + +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 + +#if 1//CONFIG_SENSOR_Focus +#include "ov5640_af_firmware.c" +/* ov5640 VCM Command and Status Registers */ +#define CONFIG_SENSOR_FocusCenterInCapture 0 +#define CMD_MAIN_Reg 0x3022 +//#define CMD_TAG_Reg 0x3023 +#define CMD_ACK_Reg 0x3023 +#define CMD_PARA0_Reg 0x3024 +#define CMD_PARA1_Reg 0x3025 +#define CMD_PARA2_Reg 0x3026 +#define CMD_PARA3_Reg 0x3027 +#define CMD_PARA4_Reg 0x3028 + +//#define STA_ZONE_Reg 0x3026 +#define STA_FOCUS_Reg 0x3029 + +/* ov5640 VCM Command */ + +#define ConstFocus_Cmd 0x04 +#define StepMode_Cmd 0x05 +#define PauseFocus_Cmd 0x06 +#define ReturnIdle_Cmd 0x08 +#define SetZone_Cmd 0x10 +#define UpdateZone_Cmd 0x12 +#define SetMotor_Cmd 0x20 +#define SingleFocus_Cmd 0x03 +#define GetFocusResult_Cmd 0x07 +#define ReleaseFocus_Cmd 0x08 +#define ZoneRelaunch_Cmd 0x12 +#define DefaultZoneConfig_Cmd 0x80 +#define TouchZoneConfig_Cmd 0x81 +#define CustomZoneConfig_Cmd 0x8f + + +/* ov5640 Focus State */ +//#define S_FIRWRE 0xFF /*Firmware is downloaded and not run*/ +#define S_STARTUP 0x7e /*Firmware is initializing*/ +#define S_ERROR 0x7f +#define S_IDLE 0x70 /*Idle state, focus is released; lens is located at the furthest position.*/ +#define S_FOCUSING 0x00 /*Auto Focus is running.*/ +#define S_FOCUSED 0x10 /*Auto Focus is completed.*/ + +#define S_CAPTURE 0x12 +#define S_STEP 0x20 + +/* ov5640 Zone State */ +#define Zone_Is_Focused(a, zone_val) (zone_val&(1<<(a-3))) +#define Zone_Get_ID(zone_val) (zone_val&0x03) + +#define Zone_CenterMode 0x01 +#define Zone_5xMode 0x02 +#define Zone_5PlusMode 0x03 +#define Zone_4fMode 0x04 + +#define ZoneSel_Auto 0x0b +#define ZoneSel_SemiAuto 0x0c +#define ZoneSel_Manual 0x0d +#define ZoneSel_Rotate 0x0e + +/* ov5640 Step Focus Commands */ +#define StepFocus_Near_Tag 0x01 +#define StepFocus_Far_Tag 0x02 +#define StepFocus_Furthest_Tag 0x03 +#define StepFocus_Nearest_Tag 0x04 +#define StepFocus_Spec_Tag 0x10 +#endif + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + unsigned short int preview_maxlines; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* 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[] ={ + {0x3103, 0x11}, + {0x3008, 0x82}, + SensorWaitMs(5), + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0xff}, + {0x3018, 0xff}, + {0x3034, 0x1a}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x3037, 0x12}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x08}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9b}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x64}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x58}, + {0x302e, 0x00}, + {0x4740, 0x20}, + {0x4300, 0x32},//uyvy:0x32,yuyv:0x30 + {0x501f, 0x00}, + {0x4713, 0x03}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x35}, + {0x460c, 0x20}, + {0x4837, 0x22}, + {0x3824, 0x02}, + {0x5000, 0xa7}, + {0x5001, 0xa3}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0x302c, 0xc2}, + SensorWaitUs(1000), + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3811, 0x10}, // + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, //4b + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x3824, 0x01}, + {0x4005, 0x1A}, + 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[] = +{ + {0x3503, 0x00}, + {0x3c07, 0x08}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3803, 0x04}, + {0x3806, 0x07},/// + {0x3807, 0x9b}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3813, 0x06}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08 ,0x01},/// + {0x3a09, 0x27},/// + {0x3a0a, 0x00},/// + {0x3a0b, 0xf6},/// + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4004, 0x02}, + {0x3002, 0x1c},//// + {0x4713, 0x03},//// + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x22}, + {0x3824, 0x02},//// + {0x5001, 0xa3}, + + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + {0x3503, 0x00}, + + {0x3c07,0x07}, + {0x3803,0xfa}, + {0x3806,0x06},//// + {0x3807,0xa9}, + {0x3808,0x05}, + {0x3809,0x00}, + {0x380a,0x02}, + {0x380b,0xd0}, + {0x380c,0x07}, + {0x380d,0x64}, + {0x380e,0x02}, + {0x380f,0xe4}, + {0x3813,0x04}, + {0x3a02,0x02}, + {0x3a03,0xe4}, + {0x3a08,0x01},/// + {0x3a09,0xbc},//// + {0x3a0a,0x01},/// + {0x3a0b,0x72},//// + {0x3a0e,0x01}, + {0x3a0d,0x02}, + {0x3a14,0x02}, + {0x3a15,0xe4}, + + {0x3820, 0x41}, //ddl@rock-chips.com add start: qsxvga -> 720p isn't stream on + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08 ,0x01},/// + {0x3a09, 0x27},/// + {0x3a0a, 0x00},/// + {0x3a0b, 0xf6},/// + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4004, 0x02}, + {0x3002, 0x1c},//// + {0x4713, 0x03},//////ddl@rock-chips.com add end + + {0x3002,0x00},/// + {0x4713,0x02},/// + {0x4837,0x16}, + {0x3824,0x04},/// + {0x5001,0x83}, + {0x3035,0x21}, + {0x3036,0x46}, + + {0x4837, 0x22}, + {0x5001, 0xa3}, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorRegVal(0x3008, 0x80), + SensorWaitMs(5), + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorRegVal(0x300a,0), + SensorRegVal(0x300b,0), + 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[]= +{ + {0x3406 ,0x00}, + {0x5192 ,0x04}, + {0x5191 ,0xf8}, + {0x5193 ,0x70}, + {0x5194 ,0xf0}, + {0x5195 ,0xf0}, + {0x518d ,0x3d}, + {0x518f ,0x54}, + {0x518e ,0x3d}, + {0x5190 ,0x54}, + {0x518b ,0xa8}, + {0x518c ,0xa8}, + {0x5187 ,0x18}, + {0x5188 ,0x18}, + {0x5189 ,0x6e}, + {0x518a ,0x68}, + {0x5186 ,0x1c}, + {0x5181 ,0x50}, + {0x5184 ,0x25}, + {0x5182 ,0x11}, + {0x5183 ,0x14}, + {0x5184 ,0x25}, + {0x5185 ,0x24}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x6 }, + {0x3401 ,0x48}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x4 }, + {0x3405 ,0xd3 }, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x6 }, + {0x3401 ,0x1c}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x4 }, + {0x3405 ,0xf3}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + {0x3406 ,0x1 }, + {0x3400 ,0x5 }, + {0x3401 ,0x48}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x7 }, + {0x3405 ,0xcf}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x3406 ,0x1 }, + {0x3400 ,0x4 }, + {0x3401 ,0x10}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x8 }, + {0x3405 ,0xb6}, + 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[] = +{ + {0x5001, 0x7f}, + {0x5580, 0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x80}, + {0x5584, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x40}, + {0x5584, 0xa0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + {0x5001, 0xff}, + {0x5580, 0x40}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0xa0}, + {0x5584, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x60}, + {0x5584, 0x60}, + 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[]= +{ + {0x3a0f, 0x10}, + {0x3a10, 0x08}, + {0x3a1b, 0x10}, + {0x3a1e, 0x08}, + {0x3a11, 0x20}, + {0x3a1f, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + {0x3a0f, 0x20}, + {0x3a10, 0x18}, + {0x3a11, 0x41}, + {0x3a1b, 0x20}, + {0x3a1e, 0x18}, + {0x3a1f, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a11, 0x61}, + {0x3a1b, 0x30}, + {0x3a1e, 0x28}, + {0x3a1f, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + {0x3a0f, 0x38}, + {0x3a10, 0x30}, + {0x3a11, 0x61}, + {0x3a1b, 0x38}, + {0x3a1e, 0x30}, + {0x3a1f, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + {0x3a0f, 0x40}, + {0x3a10, 0x38}, + {0x3a11, 0x71}, + {0x3a1b, 0x40}, + {0x3a1e, 0x38}, + {0x3a1f, 0x10}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + {0x3a0f, 0x50}, + {0x3a10, 0x48}, + {0x3a11, 0x90}, + {0x3a1b, 0x50}, + {0x3a1e, 0x48}, + {0x3a1f, 0x20}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + {0x3a0f, 0x60}, + {0x3a10, 0x58}, + {0x3a11, 0xa0}, + {0x3a1b, 0x60}, + {0x3a1e, 0x58}, + {0x3a1f, 0x20}, + 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[] = +{ + {0x3a00, 0x78}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + //15fps ~ 3.75fps night mode for 60/50Hz light environment, 24Mhz clock input,24Mzh pclk + {0x3034 ,0x1a}, + {0x3035 ,0x21}, + {0x3036 ,0x46}, + {0x3037 ,0x13}, + {0x3038 ,0x00}, + {0x3039 ,0x00}, + {0x3a00 ,0x7c}, + {0x3a08 ,0x01}, + {0x3a09 ,0x27}, + {0x3a0a ,0x00}, + {0x3a0b ,0xf6}, + {0x3a0d ,0x04}, + {0x3a0e ,0x04}, + {0x3a02 ,0x0b}, + {0x3a03 ,0x88}, + {0x3a14 ,0x0b}, + {0x3a15 ,0x88}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//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} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ + static int sensor_parameter_record(struct i2c_client *client) + { + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + struct generic_sensor*sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + sensor_read(client,0x3a00, &ret_l); + sensor_write(client,0x3a00, ret_l&0xfb); + + sensor_write(client,0x3503,0x07); //stop AE/AG + sensor_read(client,0x3406, &ret_l); + sensor_write(client,0x3406, ret_l|0x01); + + sensor_read(client,0x3500,&ret_h); + sensor_read(client,0x3501, &ret_m); + sensor_read(client,0x3502, &ret_l); + tp_l = ret_l; + tp_m = ret_m; + tp_h = ret_h; + spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x350b, &ret_l); + spsensor->parameter.preview_gain = ret_l; + + SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n", + SENSOR_NAME_STRING(), tp_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l); + return 0; + } +#define OV5640_FULL_PERIOD_PIXEL_NUMS_HTS (2844) +#define OV5640_FULL_PERIOD_LINE_NUMS_VTS (1968) +#define OV5640_PV_PERIOD_PIXEL_NUMS_HTS (1896) +#define OV5640_PV_PERIOD_LINE_NUMS_VTS (984) + static int sensor_ae_transfer(struct i2c_client *client) + { + u8 ExposureLow; + u8 ExposureMid; + u8 ExposureHigh; + u16 ulCapture_Exposure; + u16 Preview_Maxlines; + u8 Gain; + u16 OV5640_g_iExtra_ExpLines; + struct generic_sensor*sensor = to_generic_sensor(client); + struct specific_sensor *spsensor = to_specific_sensor(sensor); + //Preview_Maxlines = sensor->parameter.preview_line_width; + Preview_Maxlines = spsensor->parameter.preview_maxlines; + Gain = spsensor->parameter.preview_gain; + + + ulCapture_Exposure = (spsensor->parameter.preview_exposure*OV5640_PV_PERIOD_PIXEL_NUMS_HTS)/OV5640_FULL_PERIOD_PIXEL_NUMS_HTS; + + SENSOR_DG("cap shutter calutaed = %d, 0x%x\n", ulCapture_Exposure,ulCapture_Exposure); + + // write the gain and exposure to 0x350* registers + sensor_write(client,0x350b, Gain); + + if (ulCapture_Exposure <= 1940) { + OV5640_g_iExtra_ExpLines = 0; + }else { + OV5640_g_iExtra_ExpLines = ulCapture_Exposure - 1940; + } + SENSOR_DG("Set Extra-line = %d, iExp = %d \n", OV5640_g_iExtra_ExpLines, ulCapture_Exposure); + + ExposureLow = (ulCapture_Exposure<<4)&0xff; + ExposureMid = (ulCapture_Exposure>>4)&0xff; + ExposureHigh = (ulCapture_Exposure>>12); + + sensor_write(client,0x350c, (OV5640_g_iExtra_ExpLines&0xff00)>>8); + sensor_write(client,0x350d, OV5640_g_iExtra_ExpLines&0xff); + sensor_write(client,0x3502, ExposureLow); + sensor_write(client,0x3501, ExposureMid); + sensor_write(client,0x3500, ExposureHigh); + + //SENSOR_DG(" %s Write 0x350b=0x%02x 0x350c=0x%2x 0x350d=0x%2x 0x3502=0x%02x 0x3501=0x%02x 0x3500=0x%02x\n",SENSOR_NAME_STRING(), Gain, ExposureLow, ExposureMid, ExposureHigh); + mdelay(100); + return 0; + } +/* +********************************************************** +* 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) +{ + SENSOR_DG("%s",__FUNCTION__); + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + + SENSOR_DG("%s",__FUNCTION__); + + + 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) +{ + struct generic_sensor*sensor = to_generic_sensor(client); + + if (capture) { + sensor_parameter_record(client); + } + 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) +{ + return 0; +} + +/* +* 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) +{ + struct generic_sensor*sensor = to_generic_sensor(client); + if (capture) { + sensor_ae_transfer(client); + } + msleep(400); + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + + SENSOR_DG("mirror: %d",mirror); + + 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + SENSOR_DG("flip: %d",flip); + + 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* the functions are focus callbacks +*/ +/* +for 5640 focus +*/ +struct af_cmdinfo +{ + char cmd_tag; + char cmd_para[4]; + char validate_bit; +}; +static int sensor_af_cmdset(struct i2c_client *client, int cmd_main, struct af_cmdinfo *cmdinfo) +{ + int i; + char read_tag=0xff,cnt; + + if (cmdinfo) { + for (i=0; i<4; i++) { + if (cmdinfo->validate_bit & (1<cmd_para[i])) { + SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); + } + } + + if (cmdinfo->validate_bit & 0x80) { + if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) { + SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); + } + + } else { + if (sensor_write(client, CMD_ACK_Reg, 0x01)) { + SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x no tag) success!\n",SENSOR_NAME_STRING(),cmd_main); + } + + if (sensor_write(client, CMD_MAIN_Reg, cmd_main)) { + SENSOR_TR("%s write CMD_MAIN_Reg(main:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main); + goto sensor_af_cmdset_err; + } + + cnt = 0; + do + { + msleep(5); + if (sensor_read(client,CMD_ACK_Reg,&read_tag)){ + SENSOR_TR("%s[%d] read TAG failed\n",SENSOR_NAME_STRING(),__LINE__); + break; + } + } while((read_tag != 0x00)&& (cnt++<100)); + + SENSOR_DG("%s write CMD_MAIN_Reg(main:0x%x read tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,read_tag); + return 0; +sensor_af_cmdset_err: + return -1; +} +static int sensor_af_idlechk(struct i2c_client *client) +{ + int ret = 0; + char state; + struct af_cmdinfo cmdinfo; + + SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__); + + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x80; + ret = sensor_af_cmdset(client, ReturnIdle_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_idlechk_end; + } + + + do{ + ret = sensor_read(client, CMD_ACK_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_idlechk_end; + } + }while(0x00 != state); + + SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__); +sensor_af_idlechk_end: + return ret; +} +/*for 5640 focus end*/ +// +static int sensor_focus_af_single_usr_cb(struct i2c_client *client); + +static int sensor_focus_init_usr_cb(struct i2c_client *client) +{ + int ret = 0, cnt; + char state; + + msleep(1); + ret = sensor_write_array(client, sensor_af_firmware); + if (ret != 0) { + SENSOR_TR("%s Download firmware failed\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_init_end; + } + + cnt = 0; + do + { + msleep(1); + if (cnt++ > 500) + break; + ret = sensor_read(client, STA_FOCUS_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_init_end; + } + } while (state != S_IDLE); + + if (state != S_IDLE) { + SENSOR_TR("%s focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),state); + ret = -1; + goto sensor_af_init_end; + } +sensor_af_init_end: + SENSOR_DG("%s %s ret:0x%x \n",SENSOR_NAME_STRING(),__FUNCTION__,ret); + return ret; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client) +{ + int ret = 0; + char state,cnt; + struct af_cmdinfo cmdinfo; + char s_zone[5],i; + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x80; + ret = sensor_af_cmdset(client, SingleFocus_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s single focus mode set error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_single_end; + } + + cnt = 0; + do + { + if (cnt != 0) { + msleep(1); + } + cnt++; + ret = sensor_read(client, STA_FOCUS_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_single_end; + } + }while((state == S_FOCUSING) && (cnt<100)); + + if (state != S_FOCUSED) { + SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state); + ret = -1; + goto sensor_af_single_end; + } else { + SENSOR_DG("%s[%d] single focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); + } +sensor_af_single_end: + return ret; +} + +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) +{ + struct af_cmdinfo cmdinfo; + sensor_af_idlechk(client); + return 0; + cmdinfo.cmd_tag = StepFocus_Spec_Tag; + cmdinfo.cmd_para[0] = pos; + cmdinfo.validate_bit = 0x81; + return sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo); +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client) +{ + int ret = 0; + struct af_cmdinfo cmdinfo; + cmdinfo.cmd_tag = 0x01; + cmdinfo.cmd_para[0] = 0x00; + cmdinfo.validate_bit = 0x81; + sensor_af_idlechk(client); + if (sensor_af_cmdset(client, ConstFocus_Cmd, &cmdinfo)) { + SENSOR_TR("%s[%d] const focus mode set error!\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_const_end; + } else { + SENSOR_DG("%s[%d] const focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); + } +sensor_af_const_end: + return ret; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client) +{ + int ret = 0; + sensor_af_idlechk(client); + if (sensor_af_cmdset(client, PauseFocus_Cmd, NULL)) { + SENSOR_TR("%s pause focus mode set error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_pause_end; + } +sensor_af_pause_end: + return ret; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos) +{ + int ret = 0; + struct af_cmdinfo cmdinfo; + //int zone_tm_pos[4]; + int zone_center_pos[2]; + struct generic_sensor*sensor = to_generic_sensor(client); + + if (zone_tm_pos) { + zone_tm_pos[0] += 1000; + zone_tm_pos[1] += 1000; + zone_tm_pos[2]+= 1000; + zone_tm_pos[3] += 1000; + zone_center_pos[0] = ((zone_tm_pos[0] + zone_tm_pos[2])>>1)*80/2000; + zone_center_pos[1] = ((zone_tm_pos[1] + zone_tm_pos[3])>>1)*60/2000; + } else { +#if CONFIG_SENSOR_FocusCenterInCapture + zone_center_pos[0] = 32; + zone_center_pos[1] = 24; +#else + zone_center_pos[0] = -1; + zone_center_pos[1] = -1; +#endif + } + if ((zone_center_pos[0] >=0) && (zone_center_pos[1]>=0)){ + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x83; + if (zone_center_pos[0]<=8) + cmdinfo.cmd_para[0] = 0; + else if ((zone_center_pos[0]>8) && (zone_center_pos[0]<72)) + cmdinfo.cmd_para[0] = zone_center_pos[0]-8; + else + cmdinfo.cmd_para[0] = 72; + + if (zone_center_pos[1]<=6) + cmdinfo.cmd_para[1] = 0; + else if ((zone_center_pos[1]>6) && (zone_center_pos[1]<54)) + cmdinfo.cmd_para[1] = zone_center_pos[1]-6; + else + cmdinfo.cmd_para[1] = 54; + + ret = sensor_af_cmdset(client, TouchZoneConfig_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s touch zone config error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_zone_end; + } + } +sensor_af_zone_end: + return ret; +} + +/* +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) +{ + 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/ov5640_af_firmware.c b/drivers/media/video/ov5640_af_firmware.c index 4341b102c17b..553ba774d527 100755 --- a/drivers/media/video/ov5640_af_firmware.c +++ b/drivers/media/video/ov5640_af_firmware.c @@ -7,10 +7,11 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include "ov5640.h" +//#include "ov5640.h" -static struct reginfo sensor_af_firmware[] = +static struct rk_sensor_reg sensor_af_firmware[] = { + SensorStreamChk, #if 0 {0x3000, 0x20}, {0x8000, 0x02}, @@ -11925,5 +11926,5 @@ static struct reginfo sensor_af_firmware[] = {0x3029,0x7F}, {0x3000,0x00}, #endif - {SEQUENCE_END,0x00}, +SensorEnd }; diff --git a/drivers/media/video/ov5640_af_firmware_old.c b/drivers/media/video/ov5640_af_firmware_old.c new file mode 100755 index 000000000000..4341b102c17b --- /dev/null +++ b/drivers/media/video/ov5640_af_firmware_old.c @@ -0,0 +1,11929 @@ +/* + * Driver for OV5640 CMOS Image Sensor from OmniVision + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include "ov5640.h" + +static struct reginfo sensor_af_firmware[] = +{ +#if 0 + {0x3000, 0x20}, + {0x8000, 0x02}, + {0x8001, 0x0b}, + {0x8002, 0x61}, + {0x8003, 0x02}, + {0x8004, 0x07}, + {0x8005, 0xb1}, + {0x8006, 0xc2}, + {0x8007, 0x01}, + {0x8008, 0x22}, + {0x8009, 0x22}, + {0x800a, 0x00}, + {0x800b, 0x02}, + {0x800c, 0x0b}, + {0x800d, 0x4b}, + {0x800e, 0xe5}, + {0x800f, 0x1f}, + {0x8010, 0x60}, + {0x8011, 0x03}, + {0x8012, 0x02}, + {0x8013, 0x00}, + {0x8014, 0x97}, + {0x8015, 0xf5}, + {0x8016, 0x1e}, + {0x8017, 0xd2}, + {0x8018, 0x34}, + {0x8019, 0x75}, + {0x801a, 0x34}, + {0x801b, 0xff}, + {0x801c, 0x75}, + {0x801d, 0x35}, + {0x801e, 0x0e}, + {0x801f, 0x75}, + {0x8020, 0x36}, + {0x8021, 0x55}, + {0x8022, 0x75}, + {0x8023, 0x37}, + {0x8024, 0x01}, + {0x8025, 0x12}, + {0x8026, 0x0a}, + {0x8027, 0x3e}, + {0x8028, 0xe4}, + {0x8029, 0xff}, + {0x802a, 0xef}, + {0x802b, 0x25}, + {0x802c, 0xe0}, + {0x802d, 0x24}, + {0x802e, 0x4b}, + {0x802f, 0xf8}, + {0x8030, 0xe4}, + {0x8031, 0xf6}, + {0x8032, 0x08}, + {0x8033, 0xf6}, + {0x8034, 0x0f}, + {0x8035, 0xbf}, + {0x8036, 0x34}, + {0x8037, 0xf2}, + {0x8038, 0x90}, + {0x8039, 0x0e}, + {0x803a, 0x88}, + {0x803b, 0xe4}, + {0x803c, 0x93}, + {0x803d, 0xff}, + {0x803e, 0xe5}, + {0x803f, 0x49}, + {0x8040, 0xc3}, + {0x8041, 0x9f}, + {0x8042, 0x50}, + {0x8043, 0x04}, + {0x8044, 0x7f}, + {0x8045, 0x05}, + {0x8046, 0x80}, + {0x8047, 0x02}, + {0x8048, 0x7f}, + {0x8049, 0xfb}, + {0x804a, 0x78}, + {0x804b, 0xba}, + {0x804c, 0xa6}, + {0x804d, 0x07}, + {0x804e, 0x12}, + {0x804f, 0x0a}, + {0x8050, 0xa8}, + {0x8051, 0x40}, + {0x8052, 0x04}, + {0x8053, 0x7f}, + {0x8054, 0x03}, + {0x8055, 0x80}, + {0x8056, 0x02}, + {0x8057, 0x7f}, + {0x8058, 0x30}, + {0x8059, 0x78}, + {0x805a, 0xb9}, + {0x805b, 0xa6}, + {0x805c, 0x07}, + {0x805d, 0xe6}, + {0x805e, 0x18}, + {0x805f, 0xf6}, + {0x8060, 0x08}, + {0x8061, 0xe6}, + {0x8062, 0x78}, + {0x8063, 0xb6}, + {0x8064, 0xf6}, + {0x8065, 0x78}, + {0x8066, 0xb9}, + {0x8067, 0xe6}, + {0x8068, 0x78}, + {0x8069, 0xb7}, + {0x806a, 0xf6}, + {0x806b, 0x78}, + {0x806c, 0xbc}, + {0x806d, 0x76}, + {0x806e, 0x33}, + {0x806f, 0xe4}, + {0x8070, 0x08}, + {0x8071, 0xf6}, + {0x8072, 0x78}, + {0x8073, 0xb5}, + {0x8074, 0x76}, + {0x8075, 0x01}, + {0x8076, 0x75}, + {0x8077, 0x48}, + {0x8078, 0x02}, + {0x8079, 0x78}, + {0x807a, 0xb3}, + {0x807b, 0xf6}, + {0x807c, 0x08}, + {0x807d, 0xf6}, + {0x807e, 0x74}, + {0x807f, 0xff}, + {0x8080, 0x78}, + {0x8081, 0xbe}, + {0x8082, 0xf6}, + {0x8083, 0x08}, + {0x8084, 0xf6}, + {0x8085, 0x75}, + {0x8086, 0x1f}, + {0x8087, 0x01}, + {0x8088, 0x78}, + {0x8089, 0xb9}, + {0x808a, 0xe6}, + {0x808b, 0x75}, + {0x808c, 0xf0}, + {0x808d, 0x05}, + {0x808e, 0xa4}, + {0x808f, 0xf5}, + {0x8090, 0x49}, + {0x8091, 0x12}, + {0x8092, 0x08}, + {0x8093, 0x4f}, + {0x8094, 0xc2}, + {0x8095, 0x36}, + {0x8096, 0x22}, + {0x8097, 0x78}, + {0x8098, 0xb5}, + {0x8099, 0xe6}, + {0x809a, 0xd3}, + {0x809b, 0x94}, + {0x809c, 0x00}, + {0x809d, 0x40}, + {0x809e, 0x02}, + {0x809f, 0x16}, + {0x80a0, 0x22}, + {0x80a1, 0xe5}, + {0x80a2, 0x1f}, + {0x80a3, 0xb4}, + {0x80a4, 0x05}, + {0x80a5, 0x23}, + {0x80a6, 0xe4}, + {0x80a7, 0xf5}, + {0x80a8, 0x1f}, + {0x80a9, 0xc2}, + {0x80aa, 0x01}, + {0x80ab, 0x78}, + {0x80ac, 0xb3}, + {0x80ad, 0xe6}, + {0x80ae, 0xfe}, + {0x80af, 0x08}, + {0x80b0, 0xe6}, + {0x80b1, 0xff}, + {0x80b2, 0x78}, + {0x80b3, 0x4b}, + {0x80b4, 0xa6}, + {0x80b5, 0x06}, + {0x80b6, 0x08}, + {0x80b7, 0xa6}, + {0x80b8, 0x07}, + {0x80b9, 0xa2}, + {0x80ba, 0x36}, + {0x80bb, 0xe4}, + {0x80bc, 0x33}, + {0x80bd, 0xf5}, + {0x80be, 0x3c}, + {0x80bf, 0x90}, + {0x80c0, 0x30}, + {0x80c1, 0x28}, + {0x80c2, 0xf0}, + {0x80c3, 0x75}, + {0x80c4, 0x1e}, + {0x80c5, 0x10}, + {0x80c6, 0xd2}, + {0x80c7, 0x34}, + {0x80c8, 0x22}, + {0x80c9, 0xe5}, + {0x80ca, 0x49}, + {0x80cb, 0x75}, + {0x80cc, 0xf0}, + {0x80cd, 0x05}, + {0x80ce, 0x84}, + {0x80cf, 0x78}, + {0x80d0, 0xb9}, + {0x80d1, 0xf6}, + {0x80d2, 0x90}, + {0x80d3, 0x0e}, + {0x80d4, 0x85}, + {0x80d5, 0xe4}, + {0x80d6, 0x93}, + {0x80d7, 0xff}, + {0x80d8, 0x25}, + {0x80d9, 0xe0}, + {0x80da, 0x24}, + {0x80db, 0x0a}, + {0x80dc, 0xf8}, + {0x80dd, 0xe6}, + {0x80de, 0xfc}, + {0x80df, 0x08}, + {0x80e0, 0xe6}, + {0x80e1, 0xfd}, + {0x80e2, 0x78}, + {0x80e3, 0xb9}, + {0x80e4, 0xe6}, + {0x80e5, 0x25}, + {0x80e6, 0xe0}, + {0x80e7, 0x24}, + {0x80e8, 0x4b}, + {0x80e9, 0xf8}, + {0x80ea, 0xa6}, + {0x80eb, 0x04}, + {0x80ec, 0x08}, + {0x80ed, 0xa6}, + {0x80ee, 0x05}, + {0x80ef, 0xef}, + {0x80f0, 0x12}, + {0x80f1, 0x0a}, + {0x80f2, 0xaf}, + {0x80f3, 0xd3}, + {0x80f4, 0x78}, + {0x80f5, 0xb4}, + {0x80f6, 0x96}, + {0x80f7, 0xee}, + {0x80f8, 0x18}, + {0x80f9, 0x96}, + {0x80fa, 0x40}, + {0x80fb, 0x0d}, + {0x80fc, 0x78}, + {0x80fd, 0xb9}, + {0x80fe, 0xe6}, + {0x80ff, 0x78}, + {0x8100, 0xb6}, + {0x8101, 0xf6}, + {0x8102, 0x78}, + {0x8103, 0xb3}, + {0x8104, 0xa6}, + {0x8105, 0x06}, + {0x8106, 0x08}, + {0x8107, 0xa6}, + {0x8108, 0x07}, + {0x8109, 0x90}, + {0x810a, 0x0e}, + {0x810b, 0x85}, + {0x810c, 0xe4}, + {0x810d, 0x93}, + {0x810e, 0x12}, + {0x810f, 0x0a}, + {0x8110, 0xaf}, + {0x8111, 0xc3}, + {0x8112, 0x78}, + {0x8113, 0xbf}, + {0x8114, 0x96}, + {0x8115, 0xee}, + {0x8116, 0x18}, + {0x8117, 0x96}, + {0x8118, 0x50}, + {0x8119, 0x0d}, + {0x811a, 0x78}, + {0x811b, 0xb9}, + {0x811c, 0xe6}, + {0x811d, 0x78}, + {0x811e, 0xb7}, + {0x811f, 0xf6}, + {0x8120, 0x78}, + {0x8121, 0xbe}, + {0x8122, 0xa6}, + {0x8123, 0x06}, + {0x8124, 0x08}, + {0x8125, 0xa6}, + {0x8126, 0x07}, + {0x8127, 0x78}, + {0x8128, 0xb3}, + {0x8129, 0xe6}, + {0x812a, 0xfe}, + {0x812b, 0x08}, + {0x812c, 0xe6}, + {0x812d, 0xc3}, + {0x812e, 0x78}, + {0x812f, 0xbf}, + {0x8130, 0x96}, + {0x8131, 0xff}, + {0x8132, 0xee}, + {0x8133, 0x18}, + {0x8134, 0x96}, + {0x8135, 0x78}, + {0x8136, 0xc0}, + {0x8137, 0xf6}, + {0x8138, 0x08}, + {0x8139, 0xa6}, + {0x813a, 0x07}, + {0x813b, 0x90}, + {0x813c, 0x0e}, + {0x813d, 0x8a}, + {0x813e, 0xe4}, + {0x813f, 0x18}, + {0x8140, 0x12}, + {0x8141, 0x0a}, + {0x8142, 0x8d}, + {0x8143, 0x40}, + {0x8144, 0x02}, + {0x8145, 0xd2}, + {0x8146, 0x36}, + {0x8147, 0x78}, + {0x8148, 0xb9}, + {0x8149, 0xe6}, + {0x814a, 0x08}, + {0x814b, 0x26}, + {0x814c, 0x08}, + {0x814d, 0xf6}, + {0x814e, 0xe5}, + {0x814f, 0x1f}, + {0x8150, 0x64}, + {0x8151, 0x01}, + {0x8152, 0x70}, + {0x8153, 0x4a}, + {0x8154, 0xe6}, + {0x8155, 0xc3}, + {0x8156, 0x78}, + {0x8157, 0xbd}, + {0x8158, 0x12}, + {0x8159, 0x0a}, + {0x815a, 0x83}, + {0x815b, 0x40}, + {0x815c, 0x05}, + {0x815d, 0x12}, + {0x815e, 0x0a}, + {0x815f, 0x7e}, + {0x8160, 0x40}, + {0x8161, 0x39}, + {0x8162, 0x12}, + {0x8163, 0x0a}, + {0x8164, 0xa6}, + {0x8165, 0x40}, + {0x8166, 0x04}, + {0x8167, 0x7f}, + {0x8168, 0xfe}, + {0x8169, 0x80}, + {0x816a, 0x02}, + {0x816b, 0x7f}, + {0x816c, 0x02}, + {0x816d, 0x78}, + {0x816e, 0xba}, + {0x816f, 0xa6}, + {0x8170, 0x07}, + {0x8171, 0x78}, + {0x8172, 0xb6}, + {0x8173, 0xe6}, + {0x8174, 0x24}, + {0x8175, 0x03}, + {0x8176, 0x78}, + {0x8177, 0xbc}, + {0x8178, 0xf6}, + {0x8179, 0x78}, + {0x817a, 0xb6}, + {0x817b, 0xe6}, + {0x817c, 0x24}, + {0x817d, 0xfd}, + {0x817e, 0x78}, + {0x817f, 0xbd}, + {0x8180, 0xf6}, + {0x8181, 0x12}, + {0x8182, 0x0a}, + {0x8183, 0xa6}, + {0x8184, 0x40}, + {0x8185, 0x06}, + {0x8186, 0x78}, + {0x8187, 0xbd}, + {0x8188, 0xe6}, + {0x8189, 0xff}, + {0x818a, 0x80}, + {0x818b, 0x04}, + {0x818c, 0x78}, + {0x818d, 0xbc}, + {0x818e, 0xe6}, + {0x818f, 0xff}, + {0x8190, 0x78}, + {0x8191, 0xbb}, + {0x8192, 0xa6}, + {0x8193, 0x07}, + {0x8194, 0x75}, + {0x8195, 0x1f}, + {0x8196, 0x02}, + {0x8197, 0x78}, + {0x8198, 0xb5}, + {0x8199, 0x76}, + {0x819a, 0x01}, + {0x819b, 0x02}, + {0x819c, 0x02}, + {0x819d, 0x5d}, + {0x819e, 0xe5}, + {0x819f, 0x1f}, + {0x81a0, 0x64}, + {0x81a1, 0x02}, + {0x81a2, 0x60}, + {0x81a3, 0x03}, + {0x81a4, 0x02}, + {0x81a5, 0x02}, + {0x81a6, 0x3d}, + {0x81a7, 0x78}, + {0x81a8, 0xbb}, + {0x81a9, 0xe6}, + {0x81aa, 0xff}, + {0x81ab, 0xc3}, + {0x81ac, 0x78}, + {0x81ad, 0xbd}, + {0x81ae, 0x12}, + {0x81af, 0x0a}, + {0x81b0, 0x84}, + {0x81b1, 0x40}, + {0x81b2, 0x08}, + {0x81b3, 0x12}, + {0x81b4, 0x0a}, + {0x81b5, 0x7e}, + {0x81b6, 0x50}, + {0x81b7, 0x03}, + {0x81b8, 0x02}, + {0x81b9, 0x02}, + {0x81ba, 0x3b}, + {0x81bb, 0x12}, + {0x81bc, 0x0a}, + {0x81bd, 0xa6}, + {0x81be, 0x40}, + {0x81bf, 0x04}, + {0x81c0, 0x7f}, + {0x81c1, 0xff}, + {0x81c2, 0x80}, + {0x81c3, 0x02}, + {0x81c4, 0x7f}, + {0x81c5, 0x01}, + {0x81c6, 0x78}, + {0x81c7, 0xba}, + {0x81c8, 0xa6}, + {0x81c9, 0x07}, + {0x81ca, 0x78}, + {0x81cb, 0xb6}, + {0x81cc, 0xe6}, + {0x81cd, 0x04}, + {0x81ce, 0x78}, + {0x81cf, 0xbc}, + {0x81d0, 0xf6}, + {0x81d1, 0x78}, + {0x81d2, 0xb6}, + {0x81d3, 0xe6}, + {0x81d4, 0x14}, + {0x81d5, 0x78}, + {0x81d6, 0xbd}, + {0x81d7, 0xf6}, + {0x81d8, 0x18}, + {0x81d9, 0x12}, + {0x81da, 0x0a}, + {0x81db, 0xa8}, + {0x81dc, 0x40}, + {0x81dd, 0x04}, + {0x81de, 0xe6}, + {0x81df, 0xff}, + {0x81e0, 0x80}, + {0x81e1, 0x02}, + {0x81e2, 0x7f}, + {0x81e3, 0x00}, + {0x81e4, 0x78}, + {0x81e5, 0xbc}, + {0x81e6, 0xa6}, + {0x81e7, 0x07}, + {0x81e8, 0xd3}, + {0x81e9, 0x08}, + {0x81ea, 0xe6}, + {0x81eb, 0x64}, + {0x81ec, 0x80}, + {0x81ed, 0x94}, + {0x81ee, 0x80}, + {0x81ef, 0x40}, + {0x81f0, 0x04}, + {0x81f1, 0xe6}, + {0x81f2, 0xff}, + {0x81f3, 0x80}, + {0x81f4, 0x02}, + {0x81f5, 0x7f}, + {0x81f6, 0x00}, + {0x81f7, 0x78}, + {0x81f8, 0xbd}, + {0x81f9, 0xa6}, + {0x81fa, 0x07}, + {0x81fb, 0xc3}, + {0x81fc, 0x18}, + {0x81fd, 0xe6}, + {0x81fe, 0x64}, + {0x81ff, 0x80}, + {0x8200, 0x94}, + {0x8201, 0xb3}, + {0x8202, 0x50}, + {0x8203, 0x04}, + {0x8204, 0xe6}, + {0x8205, 0xff}, + {0x8206, 0x80}, + {0x8207, 0x02}, + {0x8208, 0x7f}, + {0x8209, 0x33}, + {0x820a, 0x78}, + {0x820b, 0xbc}, + {0x820c, 0xa6}, + {0x820d, 0x07}, + {0x820e, 0xc3}, + {0x820f, 0x08}, + {0x8210, 0xe6}, + {0x8211, 0x64}, + {0x8212, 0x80}, + {0x8213, 0x94}, + {0x8214, 0xb3}, + {0x8215, 0x50}, + {0x8216, 0x04}, + {0x8217, 0xe6}, + {0x8218, 0xff}, + {0x8219, 0x80}, + {0x821a, 0x02}, + {0x821b, 0x7f}, + {0x821c, 0x33}, + {0x821d, 0x78}, + {0x821e, 0xbd}, + {0x821f, 0xa6}, + {0x8220, 0x07}, + {0x8221, 0x12}, + {0x8222, 0x0a}, + {0x8223, 0xa6}, + {0x8224, 0x40}, + {0x8225, 0x06}, + {0x8226, 0x78}, + {0x8227, 0xbd}, + {0x8228, 0xe6}, + {0x8229, 0xff}, + {0x822a, 0x80}, + {0x822b, 0x04}, + {0x822c, 0x78}, + {0x822d, 0xbc}, + {0x822e, 0xe6}, + {0x822f, 0xff}, + {0x8230, 0x78}, + {0x8231, 0xbb}, + {0x8232, 0xa6}, + {0x8233, 0x07}, + {0x8234, 0x75}, + {0x8235, 0x1f}, + {0x8236, 0x03}, + {0x8237, 0x78}, + {0x8238, 0xb5}, + {0x8239, 0x76}, + {0x823a, 0x01}, + {0x823b, 0x80}, + {0x823c, 0x20}, + {0x823d, 0xe5}, + {0x823e, 0x1f}, + {0x823f, 0x64}, + {0x8240, 0x03}, + {0x8241, 0x70}, + {0x8242, 0x26}, + {0x8243, 0x78}, + {0x8244, 0xbb}, + {0x8245, 0xe6}, + {0x8246, 0xff}, + {0x8247, 0xc3}, + {0x8248, 0x78}, + {0x8249, 0xbd}, + {0x824a, 0x12}, + {0x824b, 0x0a}, + {0x824c, 0x84}, + {0x824d, 0x40}, + {0x824e, 0x05}, + {0x824f, 0x12}, + {0x8250, 0x0a}, + {0x8251, 0x7e}, + {0x8252, 0x40}, + {0x8253, 0x09}, + {0x8254, 0x78}, + {0x8255, 0xb6}, + {0x8256, 0xe6}, + {0x8257, 0x78}, + {0x8258, 0xbb}, + {0x8259, 0xf6}, + {0x825a, 0x75}, + {0x825b, 0x1f}, + {0x825c, 0x04}, + {0x825d, 0x78}, + {0x825e, 0xbb}, + {0x825f, 0xe6}, + {0x8260, 0x75}, + {0x8261, 0xf0}, + {0x8262, 0x05}, + {0x8263, 0xa4}, + {0x8264, 0xf5}, + {0x8265, 0x49}, + {0x8266, 0x02}, + {0x8267, 0x08}, + {0x8268, 0x4f}, + {0x8269, 0xe5}, + {0x826a, 0x1f}, + {0x826b, 0xb4}, + {0x826c, 0x04}, + {0x826d, 0x1f}, + {0x826e, 0x90}, + {0x826f, 0x0e}, + {0x8270, 0x89}, + {0x8271, 0xe4}, + {0x8272, 0x78}, + {0x8273, 0xc0}, + {0x8274, 0x12}, + {0x8275, 0x0a}, + {0x8276, 0x8d}, + {0x8277, 0x40}, + {0x8278, 0x02}, + {0x8279, 0xd2}, + {0x827a, 0x36}, + {0x827b, 0x75}, + {0x827c, 0x1f}, + {0x827d, 0x05}, + {0x827e, 0x75}, + {0x827f, 0x34}, + {0x8280, 0xff}, + {0x8281, 0x75}, + {0x8282, 0x35}, + {0x8283, 0x0e}, + {0x8284, 0x75}, + {0x8285, 0x36}, + {0x8286, 0x59}, + {0x8287, 0x75}, + {0x8288, 0x37}, + {0x8289, 0x01}, + {0x828a, 0x12}, + {0x828b, 0x0a}, + {0x828c, 0x3e}, + {0x828d, 0x22}, + {0x828e, 0xef}, + {0x828f, 0x8d}, + {0x8290, 0xf0}, + {0x8291, 0xa4}, + {0x8292, 0xa8}, + {0x8293, 0xf0}, + {0x8294, 0xcf}, + {0x8295, 0x8c}, + {0x8296, 0xf0}, + {0x8297, 0xa4}, + {0x8298, 0x28}, + {0x8299, 0xce}, + {0x829a, 0x8d}, + {0x829b, 0xf0}, + {0x829c, 0xa4}, + {0x829d, 0x2e}, + {0x829e, 0xfe}, + {0x829f, 0x22}, + {0x82a0, 0xbc}, + {0x82a1, 0x00}, + {0x82a2, 0x0b}, + {0x82a3, 0xbe}, + {0x82a4, 0x00}, + {0x82a5, 0x29}, + {0x82a6, 0xef}, + {0x82a7, 0x8d}, + {0x82a8, 0xf0}, + {0x82a9, 0x84}, + {0x82aa, 0xff}, + {0x82ab, 0xad}, + {0x82ac, 0xf0}, + {0x82ad, 0x22}, + {0x82ae, 0xe4}, + {0x82af, 0xcc}, + {0x82b0, 0xf8}, + {0x82b1, 0x75}, + {0x82b2, 0xf0}, + {0x82b3, 0x08}, + {0x82b4, 0xef}, + {0x82b5, 0x2f}, + {0x82b6, 0xff}, + {0x82b7, 0xee}, + {0x82b8, 0x33}, + {0x82b9, 0xfe}, + {0x82ba, 0xec}, + {0x82bb, 0x33}, + {0x82bc, 0xfc}, + {0x82bd, 0xee}, + {0x82be, 0x9d}, + {0x82bf, 0xec}, + {0x82c0, 0x98}, + {0x82c1, 0x40}, + {0x82c2, 0x05}, + {0x82c3, 0xfc}, + {0x82c4, 0xee}, + {0x82c5, 0x9d}, + {0x82c6, 0xfe}, + {0x82c7, 0x0f}, + {0x82c8, 0xd5}, + {0x82c9, 0xf0}, + {0x82ca, 0xe9}, + {0x82cb, 0xe4}, + {0x82cc, 0xce}, + {0x82cd, 0xfd}, + {0x82ce, 0x22}, + {0x82cf, 0xed}, + {0x82d0, 0xf8}, + {0x82d1, 0xf5}, + {0x82d2, 0xf0}, + {0x82d3, 0xee}, + {0x82d4, 0x84}, + {0x82d5, 0x20}, + {0x82d6, 0xd2}, + {0x82d7, 0x1c}, + {0x82d8, 0xfe}, + {0x82d9, 0xad}, + {0x82da, 0xf0}, + {0x82db, 0x75}, + {0x82dc, 0xf0}, + {0x82dd, 0x08}, + {0x82de, 0xef}, + {0x82df, 0x2f}, + {0x82e0, 0xff}, + {0x82e1, 0xed}, + {0x82e2, 0x33}, + {0x82e3, 0xfd}, + {0x82e4, 0x40}, + {0x82e5, 0x07}, + {0x82e6, 0x98}, + {0x82e7, 0x50}, + {0x82e8, 0x06}, + {0x82e9, 0xd5}, + {0x82ea, 0xf0}, + {0x82eb, 0xf2}, + {0x82ec, 0x22}, + {0x82ed, 0xc3}, + {0x82ee, 0x98}, + {0x82ef, 0xfd}, + {0x82f0, 0x0f}, + {0x82f1, 0xd5}, + {0x82f2, 0xf0}, + {0x82f3, 0xea}, + {0x82f4, 0x22}, + {0x82f5, 0xe8}, + {0x82f6, 0x8f}, + {0x82f7, 0xf0}, + {0x82f8, 0xa4}, + {0x82f9, 0xcc}, + {0x82fa, 0x8b}, + {0x82fb, 0xf0}, + {0x82fc, 0xa4}, + {0x82fd, 0x2c}, + {0x82fe, 0xfc}, + {0x82ff, 0xe9}, + {0x8300, 0x8e}, + {0x8301, 0xf0}, + {0x8302, 0xa4}, + {0x8303, 0x2c}, + {0x8304, 0xfc}, + {0x8305, 0x8a}, + {0x8306, 0xf0}, + {0x8307, 0xed}, + {0x8308, 0xa4}, + {0x8309, 0x2c}, + {0x830a, 0xfc}, + {0x830b, 0xea}, + {0x830c, 0x8e}, + {0x830d, 0xf0}, + {0x830e, 0xa4}, + {0x830f, 0xcd}, + {0x8310, 0xa8}, + {0x8311, 0xf0}, + {0x8312, 0x8b}, + {0x8313, 0xf0}, + {0x8314, 0xa4}, + {0x8315, 0x2d}, + {0x8316, 0xcc}, + {0x8317, 0x38}, + {0x8318, 0x25}, + {0x8319, 0xf0}, + {0x831a, 0xfd}, + {0x831b, 0xe9}, + {0x831c, 0x8f}, + {0x831d, 0xf0}, + {0x831e, 0xa4}, + {0x831f, 0x2c}, + {0x8320, 0xcd}, + {0x8321, 0x35}, + {0x8322, 0xf0}, + {0x8323, 0xfc}, + {0x8324, 0xeb}, + {0x8325, 0x8e}, + {0x8326, 0xf0}, + {0x8327, 0xa4}, + {0x8328, 0xfe}, + {0x8329, 0xa9}, + {0x832a, 0xf0}, + {0x832b, 0xeb}, + {0x832c, 0x8f}, + {0x832d, 0xf0}, + {0x832e, 0xa4}, + {0x832f, 0xcf}, + {0x8330, 0xc5}, + {0x8331, 0xf0}, + {0x8332, 0x2e}, + {0x8333, 0xcd}, + {0x8334, 0x39}, + {0x8335, 0xfe}, + {0x8336, 0xe4}, + {0x8337, 0x3c}, + {0x8338, 0xfc}, + {0x8339, 0xea}, + {0x833a, 0xa4}, + {0x833b, 0x2d}, + {0x833c, 0xce}, + {0x833d, 0x35}, + {0x833e, 0xf0}, + {0x833f, 0xfd}, + {0x8340, 0xe4}, + {0x8341, 0x3c}, + {0x8342, 0xfc}, + {0x8343, 0x22}, + {0x8344, 0x75}, + {0x8345, 0xf0}, + {0x8346, 0x08}, + {0x8347, 0x75}, + {0x8348, 0x82}, + {0x8349, 0x00}, + {0x834a, 0xef}, + {0x834b, 0x2f}, + {0x834c, 0xff}, + {0x834d, 0xee}, + {0x834e, 0x33}, + {0x834f, 0xfe}, + {0x8350, 0xcd}, + {0x8351, 0x33}, + {0x8352, 0xcd}, + {0x8353, 0xcc}, + {0x8354, 0x33}, + {0x8355, 0xcc}, + {0x8356, 0xc5}, + {0x8357, 0x82}, + {0x8358, 0x33}, + {0x8359, 0xc5}, + {0x835a, 0x82}, + {0x835b, 0x9b}, + {0x835c, 0xed}, + {0x835d, 0x9a}, + {0x835e, 0xec}, + {0x835f, 0x99}, + {0x8360, 0xe5}, + {0x8361, 0x82}, + {0x8362, 0x98}, + {0x8363, 0x40}, + {0x8364, 0x0c}, + {0x8365, 0xf5}, + {0x8366, 0x82}, + {0x8367, 0xee}, + {0x8368, 0x9b}, + {0x8369, 0xfe}, + {0x836a, 0xed}, + {0x836b, 0x9a}, + {0x836c, 0xfd}, + {0x836d, 0xec}, + {0x836e, 0x99}, + {0x836f, 0xfc}, + {0x8370, 0x0f}, + {0x8371, 0xd5}, + {0x8372, 0xf0}, + {0x8373, 0xd6}, + {0x8374, 0xe4}, + {0x8375, 0xce}, + {0x8376, 0xfb}, + {0x8377, 0xe4}, + {0x8378, 0xcd}, + {0x8379, 0xfa}, + {0x837a, 0xe4}, + {0x837b, 0xcc}, + {0x837c, 0xf9}, + {0x837d, 0xa8}, + {0x837e, 0x82}, + {0x837f, 0x22}, + {0x8380, 0xb8}, + {0x8381, 0x00}, + {0x8382, 0xc1}, + {0x8383, 0xb9}, + {0x8384, 0x00}, + {0x8385, 0x59}, + {0x8386, 0xba}, + {0x8387, 0x00}, + {0x8388, 0x2d}, + {0x8389, 0xec}, + {0x838a, 0x8b}, + {0x838b, 0xf0}, + {0x838c, 0x84}, + {0x838d, 0xcf}, + {0x838e, 0xce}, + {0x838f, 0xcd}, + {0x8390, 0xfc}, + {0x8391, 0xe5}, + {0x8392, 0xf0}, + {0x8393, 0xcb}, + {0x8394, 0xf9}, + {0x8395, 0x78}, + {0x8396, 0x18}, + {0x8397, 0xef}, + {0x8398, 0x2f}, + {0x8399, 0xff}, + {0x839a, 0xee}, + {0x839b, 0x33}, + {0x839c, 0xfe}, + {0x839d, 0xed}, + {0x839e, 0x33}, + {0x839f, 0xfd}, + {0x83a0, 0xec}, + {0x83a1, 0x33}, + {0x83a2, 0xfc}, + {0x83a3, 0xeb}, + {0x83a4, 0x33}, + {0x83a5, 0xfb}, + {0x83a6, 0x10}, + {0x83a7, 0xd7}, + {0x83a8, 0x03}, + {0x83a9, 0x99}, + {0x83aa, 0x40}, + {0x83ab, 0x04}, + {0x83ac, 0xeb}, + {0x83ad, 0x99}, + {0x83ae, 0xfb}, + {0x83af, 0x0f}, + {0x83b0, 0xd8}, + {0x83b1, 0xe5}, + {0x83b2, 0xe4}, + {0x83b3, 0xf9}, + {0x83b4, 0xfa}, + {0x83b5, 0x22}, + {0x83b6, 0x78}, + {0x83b7, 0x18}, + {0x83b8, 0xef}, + {0x83b9, 0x2f}, + {0x83ba, 0xff}, + {0x83bb, 0xee}, + {0x83bc, 0x33}, + {0x83bd, 0xfe}, + {0x83be, 0xed}, + {0x83bf, 0x33}, + {0x83c0, 0xfd}, + {0x83c1, 0xec}, + {0x83c2, 0x33}, + {0x83c3, 0xfc}, + {0x83c4, 0xc9}, + {0x83c5, 0x33}, + {0x83c6, 0xc9}, + {0x83c7, 0x10}, + {0x83c8, 0xd7}, + {0x83c9, 0x05}, + {0x83ca, 0x9b}, + {0x83cb, 0xe9}, + {0x83cc, 0x9a}, + {0x83cd, 0x40}, + {0x83ce, 0x07}, + {0x83cf, 0xec}, + {0x83d0, 0x9b}, + {0x83d1, 0xfc}, + {0x83d2, 0xe9}, + {0x83d3, 0x9a}, + {0x83d4, 0xf9}, + {0x83d5, 0x0f}, + {0x83d6, 0xd8}, + {0x83d7, 0xe0}, + {0x83d8, 0xe4}, + {0x83d9, 0xc9}, + {0x83da, 0xfa}, + {0x83db, 0xe4}, + {0x83dc, 0xcc}, + {0x83dd, 0xfb}, + {0x83de, 0x22}, + {0x83df, 0x75}, + {0x83e0, 0xf0}, + {0x83e1, 0x10}, + {0x83e2, 0xef}, + {0x83e3, 0x2f}, + {0x83e4, 0xff}, + {0x83e5, 0xee}, + {0x83e6, 0x33}, + {0x83e7, 0xfe}, + {0x83e8, 0xed}, + {0x83e9, 0x33}, + {0x83ea, 0xfd}, + {0x83eb, 0xcc}, + {0x83ec, 0x33}, + {0x83ed, 0xcc}, + {0x83ee, 0xc8}, + {0x83ef, 0x33}, + {0x83f0, 0xc8}, + {0x83f1, 0x10}, + {0x83f2, 0xd7}, + {0x83f3, 0x07}, + {0x83f4, 0x9b}, + {0x83f5, 0xec}, + {0x83f6, 0x9a}, + {0x83f7, 0xe8}, + {0x83f8, 0x99}, + {0x83f9, 0x40}, + {0x83fa, 0x0a}, + {0x83fb, 0xed}, + {0x83fc, 0x9b}, + {0x83fd, 0xfd}, + {0x83fe, 0xec}, + {0x83ff, 0x9a}, + {0x8400, 0xfc}, + {0x8401, 0xe8}, + {0x8402, 0x99}, + {0x8403, 0xf8}, + {0x8404, 0x0f}, + {0x8405, 0xd5}, + {0x8406, 0xf0}, + {0x8407, 0xda}, + {0x8408, 0xe4}, + {0x8409, 0xcd}, + {0x840a, 0xfb}, + {0x840b, 0xe4}, + {0x840c, 0xcc}, + {0x840d, 0xfa}, + {0x840e, 0xe4}, + {0x840f, 0xc8}, + {0x8410, 0xf9}, + {0x8411, 0x22}, + {0x8412, 0xeb}, + {0x8413, 0x9f}, + {0x8414, 0xf5}, + {0x8415, 0xf0}, + {0x8416, 0xea}, + {0x8417, 0x9e}, + {0x8418, 0x42}, + {0x8419, 0xf0}, + {0x841a, 0xe9}, + {0x841b, 0x9d}, + {0x841c, 0x42}, + {0x841d, 0xf0}, + {0x841e, 0xe8}, + {0x841f, 0x9c}, + {0x8420, 0x45}, + {0x8421, 0xf0}, + {0x8422, 0x22}, + {0x8423, 0xe8}, + {0x8424, 0x60}, + {0x8425, 0x0f}, + {0x8426, 0xef}, + {0x8427, 0xc3}, + {0x8428, 0x33}, + {0x8429, 0xff}, + {0x842a, 0xee}, + {0x842b, 0x33}, + {0x842c, 0xfe}, + {0x842d, 0xed}, + {0x842e, 0x33}, + {0x842f, 0xfd}, + {0x8430, 0xec}, + {0x8431, 0x33}, + {0x8432, 0xfc}, + {0x8433, 0xd8}, + {0x8434, 0xf1}, + {0x8435, 0x22}, + {0x8436, 0xe4}, + {0x8437, 0x93}, + {0x8438, 0xfc}, + {0x8439, 0x74}, + {0x843a, 0x01}, + {0x843b, 0x93}, + {0x843c, 0xfd}, + {0x843d, 0x74}, + {0x843e, 0x02}, + {0x843f, 0x93}, + {0x8440, 0xfe}, + {0x8441, 0x74}, + {0x8442, 0x03}, + {0x8443, 0x93}, + {0x8444, 0xff}, + {0x8445, 0x22}, + {0x8446, 0xe6}, + {0x8447, 0xfb}, + {0x8448, 0x08}, + {0x8449, 0xe6}, + {0x844a, 0xf9}, + {0x844b, 0x08}, + {0x844c, 0xe6}, + {0x844d, 0xfa}, + {0x844e, 0x08}, + {0x844f, 0xe6}, + {0x8450, 0xcb}, + {0x8451, 0xf8}, + {0x8452, 0x22}, + {0x8453, 0xec}, + {0x8454, 0xf6}, + {0x8455, 0x08}, + {0x8456, 0xed}, + {0x8457, 0xf6}, + {0x8458, 0x08}, + {0x8459, 0xee}, + {0x845a, 0xf6}, + {0x845b, 0x08}, + {0x845c, 0xef}, + {0x845d, 0xf6}, + {0x845e, 0x22}, + {0x845f, 0xa4}, + {0x8460, 0x25}, + {0x8461, 0x82}, + {0x8462, 0xf5}, + {0x8463, 0x82}, + {0x8464, 0xe5}, + {0x8465, 0xf0}, + {0x8466, 0x35}, + {0x8467, 0x83}, + {0x8468, 0xf5}, + {0x8469, 0x83}, + {0x846a, 0x22}, + {0x846b, 0xd0}, + {0x846c, 0x83}, + {0x846d, 0xd0}, + {0x846e, 0x82}, + {0x846f, 0xf8}, + {0x8470, 0xe4}, + {0x8471, 0x93}, + {0x8472, 0x70}, + {0x8473, 0x12}, + {0x8474, 0x74}, + {0x8475, 0x01}, + {0x8476, 0x93}, + {0x8477, 0x70}, + {0x8478, 0x0d}, + {0x8479, 0xa3}, + {0x847a, 0xa3}, + {0x847b, 0x93}, + {0x847c, 0xf8}, + {0x847d, 0x74}, + {0x847e, 0x01}, + {0x847f, 0x93}, + {0x8480, 0xf5}, + {0x8481, 0x82}, + {0x8482, 0x88}, + {0x8483, 0x83}, + {0x8484, 0xe4}, + {0x8485, 0x73}, + {0x8486, 0x74}, + {0x8487, 0x02}, + {0x8488, 0x93}, + {0x8489, 0x68}, + {0x848a, 0x60}, + {0x848b, 0xef}, + {0x848c, 0xa3}, + {0x848d, 0xa3}, + {0x848e, 0xa3}, + {0x848f, 0x80}, + {0x8490, 0xdf}, + {0x8491, 0x90}, + {0x8492, 0x38}, + {0x8493, 0x04}, + {0x8494, 0x78}, + {0x8495, 0x4f}, + {0x8496, 0x12}, + {0x8497, 0x09}, + {0x8498, 0x44}, + {0x8499, 0x90}, + {0x849a, 0x38}, + {0x849b, 0x00}, + {0x849c, 0xe0}, + {0x849d, 0xfe}, + {0x849e, 0xa3}, + {0x849f, 0xe0}, + {0x84a0, 0xfd}, + {0x84a1, 0xed}, + {0x84a2, 0xff}, + {0x84a3, 0xc3}, + {0x84a4, 0x12}, + {0x84a5, 0x08}, + {0x84a6, 0xfd}, + {0x84a7, 0x90}, + {0x84a8, 0x38}, + {0x84a9, 0x10}, + {0x84aa, 0x12}, + {0x84ab, 0x08}, + {0x84ac, 0xf1}, + {0x84ad, 0x90}, + {0x84ae, 0x38}, + {0x84af, 0x06}, + {0x84b0, 0x78}, + {0x84b1, 0x51}, + {0x84b2, 0x12}, + {0x84b3, 0x09}, + {0x84b4, 0x44}, + {0x84b5, 0x90}, + {0x84b6, 0x38}, + {0x84b7, 0x02}, + {0x84b8, 0xe0}, + {0x84b9, 0xfe}, + {0x84ba, 0xa3}, + {0x84bb, 0xe0}, + {0x84bc, 0xfd}, + {0x84bd, 0xed}, + {0x84be, 0xff}, + {0x84bf, 0xc3}, + {0x84c0, 0x12}, + {0x84c1, 0x08}, + {0x84c2, 0xfd}, + {0x84c3, 0x90}, + {0x84c4, 0x38}, + {0x84c5, 0x12}, + {0x84c6, 0x12}, + {0x84c7, 0x08}, + {0x84c8, 0xf1}, + {0x84c9, 0xa3}, + {0x84ca, 0xe0}, + {0x84cb, 0xb4}, + {0x84cc, 0x31}, + {0x84cd, 0x07}, + {0x84ce, 0x78}, + {0x84cf, 0x4f}, + {0x84d0, 0x79}, + {0x84d1, 0x4f}, + {0x84d2, 0x12}, + {0x84d3, 0x09}, + {0x84d4, 0x5a}, + {0x84d5, 0x90}, + {0x84d6, 0x38}, + {0x84d7, 0x14}, + {0x84d8, 0xe0}, + {0x84d9, 0xb4}, + {0x84da, 0x71}, + {0x84db, 0x15}, + {0x84dc, 0x78}, + {0x84dd, 0x4f}, + {0x84de, 0xe6}, + {0x84df, 0xfe}, + {0x84e0, 0x08}, + {0x84e1, 0xe6}, + {0x84e2, 0x78}, + {0x84e3, 0x02}, + {0x84e4, 0xce}, + {0x84e5, 0xc3}, + {0x84e6, 0x13}, + {0x84e7, 0xce}, + {0x84e8, 0x13}, + {0x84e9, 0xd8}, + {0x84ea, 0xf9}, + {0x84eb, 0x79}, + {0x84ec, 0x50}, + {0x84ed, 0xf7}, + {0x84ee, 0xee}, + {0x84ef, 0x19}, + {0x84f0, 0xf7}, + {0x84f1, 0x90}, + {0x84f2, 0x38}, + {0x84f3, 0x15}, + {0x84f4, 0xe0}, + {0x84f5, 0xb4}, + {0x84f6, 0x31}, + {0x84f7, 0x07}, + {0x84f8, 0x78}, + {0x84f9, 0x51}, + {0x84fa, 0x79}, + {0x84fb, 0x51}, + {0x84fc, 0x12}, + {0x84fd, 0x09}, + {0x84fe, 0x5a}, + {0x84ff, 0x90}, + {0x8500, 0x38}, + {0x8501, 0x15}, + {0x8502, 0xe0}, + {0x8503, 0xb4}, + {0x8504, 0x71}, + {0x8505, 0x15}, + {0x8506, 0x78}, + {0x8507, 0x51}, + {0x8508, 0xe6}, + {0x8509, 0xfe}, + {0x850a, 0x08}, + {0x850b, 0xe6}, + {0x850c, 0x78}, + {0x850d, 0x02}, + {0x850e, 0xce}, + {0x850f, 0xc3}, + {0x8510, 0x13}, + {0x8511, 0xce}, + {0x8512, 0x13}, + {0x8513, 0xd8}, + {0x8514, 0xf9}, + {0x8515, 0x79}, + {0x8516, 0x52}, + {0x8517, 0xf7}, + {0x8518, 0xee}, + {0x8519, 0x19}, + {0x851a, 0xf7}, + {0x851b, 0x79}, + {0x851c, 0x4f}, + {0x851d, 0x12}, + {0x851e, 0x09}, + {0x851f, 0x2c}, + {0x8520, 0x09}, + {0x8521, 0x12}, + {0x8522, 0x09}, + {0x8523, 0x2c}, + {0x8524, 0xaf}, + {0x8525, 0x45}, + {0x8526, 0x12}, + {0x8527, 0x08}, + {0x8528, 0xe2}, + {0x8529, 0x7d}, + {0x852a, 0x50}, + {0x852b, 0x12}, + {0x852c, 0x02}, + {0x852d, 0xa0}, + {0x852e, 0x78}, + {0x852f, 0x57}, + {0x8530, 0xa6}, + {0x8531, 0x06}, + {0x8532, 0x08}, + {0x8533, 0xa6}, + {0x8534, 0x07}, + {0x8535, 0xaf}, + {0x8536, 0x43}, + {0x8537, 0x12}, + {0x8538, 0x08}, + {0x8539, 0xe2}, + {0x853a, 0x7d}, + {0x853b, 0x50}, + {0x853c, 0x12}, + {0x853d, 0x02}, + {0x853e, 0xa0}, + {0x853f, 0x78}, + {0x8540, 0x53}, + {0x8541, 0xa6}, + {0x8542, 0x06}, + {0x8543, 0x08}, + {0x8544, 0xa6}, + {0x8545, 0x07}, + {0x8546, 0xaf}, + {0x8547, 0x46}, + {0x8548, 0x78}, + {0x8549, 0x51}, + {0x854a, 0x12}, + {0x854b, 0x08}, + {0x854c, 0xe4}, + {0x854d, 0x7d}, + {0x854e, 0x3c}, + {0x854f, 0x12}, + {0x8550, 0x02}, + {0x8551, 0xa0}, + {0x8552, 0x78}, + {0x8553, 0x59}, + {0x8554, 0xa6}, + {0x8555, 0x06}, + {0x8556, 0x08}, + {0x8557, 0xa6}, + {0x8558, 0x07}, + {0x8559, 0xaf}, + {0x855a, 0x44}, + {0x855b, 0x7e}, + {0x855c, 0x00}, + {0x855d, 0x78}, + {0x855e, 0x51}, + {0x855f, 0x12}, + {0x8560, 0x08}, + {0x8561, 0xe6}, + {0x8562, 0x7d}, + {0x8563, 0x3c}, + {0x8564, 0x12}, + {0x8565, 0x02}, + {0x8566, 0xa0}, + {0x8567, 0x78}, + {0x8568, 0x55}, + {0x8569, 0xa6}, + {0x856a, 0x06}, + {0x856b, 0x08}, + {0x856c, 0xa6}, + {0x856d, 0x07}, + {0x856e, 0xc3}, + {0x856f, 0x78}, + {0x8570, 0x58}, + {0x8571, 0xe6}, + {0x8572, 0x94}, + {0x8573, 0x08}, + {0x8574, 0x18}, + {0x8575, 0xe6}, + {0x8576, 0x94}, + {0x8577, 0x00}, + {0x8578, 0x50}, + {0x8579, 0x05}, + {0x857a, 0x76}, + {0x857b, 0x00}, + {0x857c, 0x08}, + {0x857d, 0x76}, + {0x857e, 0x08}, + {0x857f, 0xc3}, + {0x8580, 0x78}, + {0x8581, 0x5a}, + {0x8582, 0xe6}, + {0x8583, 0x94}, + {0x8584, 0x08}, + {0x8585, 0x18}, + {0x8586, 0xe6}, + {0x8587, 0x94}, + {0x8588, 0x00}, + {0x8589, 0x50}, + {0x858a, 0x05}, + {0x858b, 0x76}, + {0x858c, 0x00}, + {0x858d, 0x08}, + {0x858e, 0x76}, + {0x858f, 0x08}, + {0x8590, 0x78}, + {0x8591, 0x57}, + {0x8592, 0x12}, + {0x8593, 0x09}, + {0x8594, 0x19}, + {0x8595, 0xff}, + {0x8596, 0xd3}, + {0x8597, 0x78}, + {0x8598, 0x54}, + {0x8599, 0xe6}, + {0x859a, 0x9f}, + {0x859b, 0x18}, + {0x859c, 0xe6}, + {0x859d, 0x9e}, + {0x859e, 0x40}, + {0x859f, 0x0e}, + {0x85a0, 0x78}, + {0x85a1, 0x57}, + {0x85a2, 0xe6}, + {0x85a3, 0x13}, + {0x85a4, 0xfe}, + {0x85a5, 0x08}, + {0x85a6, 0xe6}, + {0x85a7, 0x78}, + {0x85a8, 0x54}, + {0x85a9, 0x12}, + {0x85aa, 0x09}, + {0x85ab, 0x4f}, + {0x85ac, 0x80}, + {0x85ad, 0x04}, + {0x85ae, 0x7e}, + {0x85af, 0x00}, + {0x85b0, 0x7f}, + {0x85b1, 0x00}, + {0x85b2, 0x78}, + {0x85b3, 0x5b}, + {0x85b4, 0x12}, + {0x85b5, 0x09}, + {0x85b6, 0x11}, + {0x85b7, 0xff}, + {0x85b8, 0xd3}, + {0x85b9, 0x78}, + {0x85ba, 0x56}, + {0x85bb, 0xe6}, + {0x85bc, 0x9f}, + {0x85bd, 0x18}, + {0x85be, 0xe6}, + {0x85bf, 0x9e}, + {0x85c0, 0x40}, + {0x85c1, 0x0e}, + {0x85c2, 0x78}, + {0x85c3, 0x59}, + {0x85c4, 0xe6}, + {0x85c5, 0x13}, + {0x85c6, 0xfe}, + {0x85c7, 0x08}, + {0x85c8, 0xe6}, + {0x85c9, 0x78}, + {0x85ca, 0x56}, + {0x85cb, 0x12}, + {0x85cc, 0x09}, + {0x85cd, 0x4f}, + {0x85ce, 0x80}, + {0x85cf, 0x04}, + {0x85d0, 0x7e}, + {0x85d1, 0x00}, + {0x85d2, 0x7f}, + {0x85d3, 0x00}, + {0x85d4, 0xe4}, + {0x85d5, 0xfc}, + {0x85d6, 0xfd}, + {0x85d7, 0x78}, + {0x85d8, 0x5f}, + {0x85d9, 0x12}, + {0x85da, 0x04}, + {0x85db, 0x53}, + {0x85dc, 0x78}, + {0x85dd, 0x57}, + {0x85de, 0x12}, + {0x85df, 0x09}, + {0x85e0, 0x19}, + {0x85e1, 0x78}, + {0x85e2, 0x54}, + {0x85e3, 0x26}, + {0x85e4, 0xff}, + {0x85e5, 0xee}, + {0x85e6, 0x18}, + {0x85e7, 0x36}, + {0x85e8, 0xfe}, + {0x85e9, 0x78}, + {0x85ea, 0x63}, + {0x85eb, 0x12}, + {0x85ec, 0x09}, + {0x85ed, 0x11}, + {0x85ee, 0x78}, + {0x85ef, 0x56}, + {0x85f0, 0x26}, + {0x85f1, 0xff}, + {0x85f2, 0xee}, + {0x85f3, 0x18}, + {0x85f4, 0x36}, + {0x85f5, 0xfe}, + {0x85f6, 0xe4}, + {0x85f7, 0xfc}, + {0x85f8, 0xfd}, + {0x85f9, 0x78}, + {0x85fa, 0x67}, + {0x85fb, 0x12}, + {0x85fc, 0x04}, + {0x85fd, 0x53}, + {0x85fe, 0x12}, + {0x85ff, 0x09}, + {0x8600, 0x21}, + {0x8601, 0x78}, + {0x8602, 0x63}, + {0x8603, 0x12}, + {0x8604, 0x04}, + {0x8605, 0x46}, + {0x8606, 0xd3}, + {0x8607, 0x12}, + {0x8608, 0x04}, + {0x8609, 0x12}, + {0x860a, 0x40}, + {0x860b, 0x08}, + {0x860c, 0x12}, + {0x860d, 0x09}, + {0x860e, 0x21}, + {0x860f, 0x78}, + {0x8610, 0x63}, + {0x8611, 0x12}, + {0x8612, 0x04}, + {0x8613, 0x53}, + {0x8614, 0x78}, + {0x8615, 0x51}, + {0x8616, 0x12}, + {0x8617, 0x09}, + {0x8618, 0x23}, + {0x8619, 0x78}, + {0x861a, 0x67}, + {0x861b, 0x12}, + {0x861c, 0x04}, + {0x861d, 0x46}, + {0x861e, 0xd3}, + {0x861f, 0x12}, + {0x8620, 0x04}, + {0x8621, 0x12}, + {0x8622, 0x40}, + {0x8623, 0x0a}, + {0x8624, 0x78}, + {0x8625, 0x51}, + {0x8626, 0x12}, + {0x8627, 0x09}, + {0x8628, 0x23}, + {0x8629, 0x78}, + {0x862a, 0x67}, + {0x862b, 0x12}, + {0x862c, 0x04}, + {0x862d, 0x53}, + {0x862e, 0xe4}, + {0x862f, 0xfd}, + {0x8630, 0x78}, + {0x8631, 0x5e}, + {0x8632, 0x12}, + {0x8633, 0x09}, + {0x8634, 0x3c}, + {0x8635, 0x24}, + {0x8636, 0x01}, + {0x8637, 0x12}, + {0x8638, 0x09}, + {0x8639, 0x05}, + {0x863a, 0x78}, + {0x863b, 0x62}, + {0x863c, 0x12}, + {0x863d, 0x09}, + {0x863e, 0x3c}, + {0x863f, 0x24}, + {0x8640, 0x02}, + {0x8641, 0x12}, + {0x8642, 0x09}, + {0x8643, 0x05}, + {0x8644, 0x78}, + {0x8645, 0x66}, + {0x8646, 0x12}, + {0x8647, 0x09}, + {0x8648, 0x3c}, + {0x8649, 0x24}, + {0x864a, 0x03}, + {0x864b, 0x12}, + {0x864c, 0x09}, + {0x864d, 0x05}, + {0x864e, 0x78}, + {0x864f, 0x6a}, + {0x8650, 0x12}, + {0x8651, 0x09}, + {0x8652, 0x3c}, + {0x8653, 0x24}, + {0x8654, 0x04}, + {0x8655, 0x12}, + {0x8656, 0x09}, + {0x8657, 0x05}, + {0x8658, 0x0d}, + {0x8659, 0xbd}, + {0x865a, 0x05}, + {0x865b, 0xd4}, + {0x865c, 0xc2}, + {0x865d, 0x0e}, + {0x865e, 0xc2}, + {0x865f, 0x06}, + {0x8660, 0x22}, + {0x8661, 0x85}, + {0x8662, 0x08}, + {0x8663, 0x41}, + {0x8664, 0x90}, + {0x8665, 0x30}, + {0x8666, 0x24}, + {0x8667, 0xe0}, + {0x8668, 0xf5}, + {0x8669, 0x3d}, + {0x866a, 0xa3}, + {0x866b, 0xe0}, + {0x866c, 0xf5}, + {0x866d, 0x3e}, + {0x866e, 0xa3}, + {0x866f, 0xe0}, + {0x8670, 0xf5}, + {0x8671, 0x3f}, + {0x8672, 0xa3}, + {0x8673, 0xe0}, + {0x8674, 0xf5}, + {0x8675, 0x40}, + {0x8676, 0xa3}, + {0x8677, 0xe0}, + {0x8678, 0xf5}, + {0x8679, 0x3c}, + {0x867a, 0xd2}, + {0x867b, 0x33}, + {0x867c, 0xe5}, + {0x867d, 0x41}, + {0x867e, 0x12}, + {0x867f, 0x04}, + {0x8680, 0x6b}, + {0x8681, 0x06}, + {0x8682, 0xbe}, + {0x8683, 0x03}, + {0x8684, 0x06}, + {0x8685, 0xc2}, + {0x8686, 0x04}, + {0x8687, 0x06}, + {0x8688, 0xc8}, + {0x8689, 0x07}, + {0x868a, 0x06}, + {0x868b, 0xd1}, + {0x868c, 0x08}, + {0x868d, 0x06}, + {0x868e, 0xe2}, + {0x868f, 0x12}, + {0x8690, 0x06}, + {0x8691, 0xfd}, + {0x8692, 0x18}, + {0x8693, 0x07}, + {0x8694, 0x13}, + {0x8695, 0x19}, + {0x8696, 0x06}, + {0x8697, 0xe8}, + {0x8698, 0x1a}, + {0x8699, 0x06}, + {0x869a, 0xf4}, + {0x869b, 0x1b}, + {0x869c, 0x07}, + {0x869d, 0x37}, + {0x869e, 0x80}, + {0x869f, 0x07}, + {0x86a0, 0x3a}, + {0x86a1, 0x81}, + {0x86a2, 0x07}, + {0x86a3, 0x95}, + {0x86a4, 0x8f}, + {0x86a5, 0x07}, + {0x86a6, 0x84}, + {0x86a7, 0x90}, + {0x86a8, 0x07}, + {0x86a9, 0x95}, + {0x86aa, 0x91}, + {0x86ab, 0x07}, + {0x86ac, 0x95}, + {0x86ad, 0x92}, + {0x86ae, 0x07}, + {0x86af, 0x95}, + {0x86b0, 0x93}, + {0x86b1, 0x07}, + {0x86b2, 0x95}, + {0x86b3, 0x94}, + {0x86b4, 0x07}, + {0x86b5, 0x95}, + {0x86b6, 0x98}, + {0x86b7, 0x07}, + {0x86b8, 0x92}, + {0x86b9, 0x9f}, + {0x86ba, 0x00}, + {0x86bb, 0x00}, + {0x86bc, 0x07}, + {0x86bd, 0xb0}, + {0x86be, 0x12}, + {0x86bf, 0x0a}, + {0x86c0, 0xe8}, + {0x86c1, 0x22}, + {0x86c2, 0x12}, + {0x86c3, 0x0a}, + {0x86c4, 0xe8}, + {0x86c5, 0xd2}, + {0x86c6, 0x03}, + {0x86c7, 0x22}, + {0x86c8, 0xa2}, + {0x86c9, 0x36}, + {0x86ca, 0xe4}, + {0x86cb, 0x33}, + {0x86cc, 0xf5}, + {0x86cd, 0x3c}, + {0x86ce, 0x02}, + {0x86cf, 0x07}, + {0x86d0, 0x95}, + {0x86d1, 0xc2}, + {0x86d2, 0x01}, + {0x86d3, 0xc2}, + {0x86d4, 0x02}, + {0x86d5, 0xc2}, + {0x86d6, 0x03}, + {0x86d7, 0x12}, + {0x86d8, 0x09}, + {0x86d9, 0x64}, + {0x86da, 0x75}, + {0x86db, 0x1e}, + {0x86dc, 0x70}, + {0x86dd, 0xd2}, + {0x86de, 0x34}, + {0x86df, 0x02}, + {0x86e0, 0x07}, + {0x86e1, 0x95}, + {0x86e2, 0x12}, + {0x86e3, 0x04}, + {0x86e4, 0x91}, + {0x86e5, 0x02}, + {0x86e6, 0x07}, + {0x86e7, 0x95}, + {0x86e8, 0x85}, + {0x86e9, 0x40}, + {0x86ea, 0x48}, + {0x86eb, 0x85}, + {0x86ec, 0x3c}, + {0x86ed, 0x49}, + {0x86ee, 0x12}, + {0x86ef, 0x08}, + {0x86f0, 0x4f}, + {0x86f1, 0x02}, + {0x86f2, 0x07}, + {0x86f3, 0x95}, + {0x86f4, 0x85}, + {0x86f5, 0x48}, + {0x86f6, 0x40}, + {0x86f7, 0x85}, + {0x86f8, 0x49}, + {0x86f9, 0x3c}, + {0x86fa, 0x02}, + {0x86fb, 0x07}, + {0x86fc, 0x95}, + {0x86fd, 0xe4}, + {0x86fe, 0xf5}, + {0x86ff, 0x22}, + {0x8700, 0xf5}, + {0x8701, 0x23}, + {0x8702, 0x85}, + {0x8703, 0x40}, + {0x8704, 0x31}, + {0x8705, 0x85}, + {0x8706, 0x3f}, + {0x8707, 0x30}, + {0x8708, 0x85}, + {0x8709, 0x3e}, + {0x870a, 0x2f}, + {0x870b, 0x85}, + {0x870c, 0x3d}, + {0x870d, 0x2e}, + {0x870e, 0x12}, + {0x870f, 0x0a}, + {0x8710, 0xba}, + {0x8711, 0x80}, + {0x8712, 0x1f}, + {0x8713, 0x75}, + {0x8714, 0x22}, + {0x8715, 0x00}, + {0x8716, 0x75}, + {0x8717, 0x23}, + {0x8718, 0x01}, + {0x8719, 0x74}, + {0x871a, 0xff}, + {0x871b, 0xf5}, + {0x871c, 0x2d}, + {0x871d, 0xf5}, + {0x871e, 0x2c}, + {0x871f, 0xf5}, + {0x8720, 0x2b}, + {0x8721, 0xf5}, + {0x8722, 0x2a}, + {0x8723, 0x12}, + {0x8724, 0x0a}, + {0x8725, 0xba}, + {0x8726, 0x85}, + {0x8727, 0x2d}, + {0x8728, 0x40}, + {0x8729, 0x85}, + {0x872a, 0x2c}, + {0x872b, 0x3f}, + {0x872c, 0x85}, + {0x872d, 0x2b}, + {0x872e, 0x3e}, + {0x872f, 0x85}, + {0x8730, 0x2a}, + {0x8731, 0x3d}, + {0x8732, 0xe4}, + {0x8733, 0xf5}, + {0x8734, 0x3c}, + {0x8735, 0x80}, + {0x8736, 0x5e}, + {0x8737, 0x02}, + {0x8738, 0x0b}, + {0x8739, 0x31}, + {0x873a, 0x85}, + {0x873b, 0x3d}, + {0x873c, 0x43}, + {0x873d, 0x85}, + {0x873e, 0x3e}, + {0x873f, 0x44}, + {0x8740, 0xe5}, + {0x8741, 0x45}, + {0x8742, 0xc3}, + {0x8743, 0x13}, + {0x8744, 0xff}, + {0x8745, 0xe5}, + {0x8746, 0x43}, + {0x8747, 0xc3}, + {0x8748, 0x9f}, + {0x8749, 0x50}, + {0x874a, 0x02}, + {0x874b, 0x8f}, + {0x874c, 0x43}, + {0x874d, 0xe5}, + {0x874e, 0x46}, + {0x874f, 0xc3}, + {0x8750, 0x13}, + {0x8751, 0xff}, + {0x8752, 0xe5}, + {0x8753, 0x44}, + {0x8754, 0xc3}, + {0x8755, 0x9f}, + {0x8756, 0x50}, + {0x8757, 0x02}, + {0x8758, 0x8f}, + {0x8759, 0x44}, + {0x875a, 0xe5}, + {0x875b, 0x45}, + {0x875c, 0xc3}, + {0x875d, 0x13}, + {0x875e, 0xff}, + {0x875f, 0xfd}, + {0x8760, 0xe5}, + {0x8761, 0x43}, + {0x8762, 0x90}, + {0x8763, 0x0e}, + {0x8764, 0x7f}, + {0x8765, 0x12}, + {0x8766, 0x0b}, + {0x8767, 0x04}, + {0x8768, 0x40}, + {0x8769, 0x04}, + {0x876a, 0xee}, + {0x876b, 0x9f}, + {0x876c, 0xf5}, + {0x876d, 0x43}, + {0x876e, 0xe5}, + {0x876f, 0x46}, + {0x8770, 0xc3}, + {0x8771, 0x13}, + {0x8772, 0xff}, + {0x8773, 0xfd}, + {0x8774, 0xe5}, + {0x8775, 0x44}, + {0x8776, 0x90}, + {0x8777, 0x0e}, + {0x8778, 0x80}, + {0x8779, 0x12}, + {0x877a, 0x0b}, + {0x877b, 0x04}, + {0x877c, 0x40}, + {0x877d, 0x14}, + {0x877e, 0xee}, + {0x877f, 0x9f}, + {0x8780, 0xf5}, + {0x8781, 0x44}, + {0x8782, 0x80}, + {0x8783, 0x0e}, + {0x8784, 0x85}, + {0x8785, 0x40}, + {0x8786, 0x46}, + {0x8787, 0x85}, + {0x8788, 0x3f}, + {0x8789, 0x45}, + {0x878a, 0x85}, + {0x878b, 0x3e}, + {0x878c, 0x44}, + {0x878d, 0x85}, + {0x878e, 0x3d}, + {0x878f, 0x43}, + {0x8790, 0x80}, + {0x8791, 0x03}, + {0x8792, 0x02}, + {0x8793, 0x04}, + {0x8794, 0x91}, + {0x8795, 0x90}, + {0x8796, 0x30}, + {0x8797, 0x24}, + {0x8798, 0xe5}, + {0x8799, 0x3d}, + {0x879a, 0xf0}, + {0x879b, 0xa3}, + {0x879c, 0xe5}, + {0x879d, 0x3e}, + {0x879e, 0xf0}, + {0x879f, 0xa3}, + {0x87a0, 0xe5}, + {0x87a1, 0x3f}, + {0x87a2, 0xf0}, + {0x87a3, 0xa3}, + {0x87a4, 0xe5}, + {0x87a5, 0x40}, + {0x87a6, 0xf0}, + {0x87a7, 0xa3}, + {0x87a8, 0xe5}, + {0x87a9, 0x3c}, + {0x87aa, 0xf0}, + {0x87ab, 0x90}, + {0x87ac, 0x30}, + {0x87ad, 0x23}, + {0x87ae, 0xe4}, + {0x87af, 0xf0}, + {0x87b0, 0x22}, + {0x87b1, 0xc0}, + {0x87b2, 0xe0}, + {0x87b3, 0xc0}, + {0x87b4, 0x83}, + {0x87b5, 0xc0}, + {0x87b6, 0x82}, + {0x87b7, 0xc0}, + {0x87b8, 0xd0}, + {0x87b9, 0x90}, + {0x87ba, 0x3f}, + {0x87bb, 0x0c}, + {0x87bc, 0xe0}, + {0x87bd, 0xf5}, + {0x87be, 0x32}, + {0x87bf, 0xe5}, + {0x87c0, 0x32}, + {0x87c1, 0x30}, + {0x87c2, 0xe3}, + {0x87c3, 0x4c}, + {0x87c4, 0x30}, + {0x87c5, 0x35}, + {0x87c6, 0x3e}, + {0x87c7, 0x90}, + {0x87c8, 0x60}, + {0x87c9, 0x19}, + {0x87ca, 0xe0}, + {0x87cb, 0xf5}, + {0x87cc, 0x0a}, + {0x87cd, 0xa3}, + {0x87ce, 0xe0}, + {0x87cf, 0xf5}, + {0x87d0, 0x0b}, + {0x87d1, 0x90}, + {0x87d2, 0x60}, + {0x87d3, 0x1d}, + {0x87d4, 0xe0}, + {0x87d5, 0xf5}, + {0x87d6, 0x14}, + {0x87d7, 0xa3}, + {0x87d8, 0xe0}, + {0x87d9, 0xf5}, + {0x87da, 0x15}, + {0x87db, 0x30}, + {0x87dc, 0x01}, + {0x87dd, 0x06}, + {0x87de, 0x30}, + {0x87df, 0x32}, + {0x87e0, 0x03}, + {0x87e1, 0xd3}, + {0x87e2, 0x80}, + {0x87e3, 0x01}, + {0x87e4, 0xc3}, + {0x87e5, 0x92}, + {0x87e6, 0x09}, + {0x87e7, 0x30}, + {0x87e8, 0x02}, + {0x87e9, 0x06}, + {0x87ea, 0x30}, + {0x87eb, 0x32}, + {0x87ec, 0x03}, + {0x87ed, 0xd3}, + {0x87ee, 0x80}, + {0x87ef, 0x01}, + {0x87f0, 0xc3}, + {0x87f1, 0x92}, + {0x87f2, 0x0a}, + {0x87f3, 0x30}, + {0x87f4, 0x32}, + {0x87f5, 0x0c}, + {0x87f6, 0x30}, + {0x87f7, 0x03}, + {0x87f8, 0x09}, + {0x87f9, 0x20}, + {0x87fa, 0x02}, + {0x87fb, 0x06}, + {0x87fc, 0x20}, + {0x87fd, 0x01}, + {0x87fe, 0x03}, + {0x87ff, 0xd3}, + {0x8800, 0x80}, + {0x8801, 0x01}, + {0x8802, 0xc3}, + {0x8803, 0x92}, + {0x8804, 0x0b}, + {0x8805, 0x90}, + {0x8806, 0x30}, + {0x8807, 0x01}, + {0x8808, 0xe0}, + {0x8809, 0x44}, + {0x880a, 0x40}, + {0x880b, 0xf0}, + {0x880c, 0xe0}, + {0x880d, 0x54}, + {0x880e, 0xbf}, + {0x880f, 0xf0}, + {0x8810, 0xe5}, + {0x8811, 0x32}, + {0x8812, 0x30}, + {0x8813, 0xe1}, + {0x8814, 0x14}, + {0x8815, 0x30}, + {0x8816, 0x33}, + {0x8817, 0x11}, + {0x8818, 0x90}, + {0x8819, 0x30}, + {0x881a, 0x22}, + {0x881b, 0xe0}, + {0x881c, 0xf5}, + {0x881d, 0x08}, + {0x881e, 0xe4}, + {0x881f, 0xf0}, + {0x8820, 0x30}, + {0x8821, 0x00}, + {0x8822, 0x03}, + {0x8823, 0xd3}, + {0x8824, 0x80}, + {0x8825, 0x01}, + {0x8826, 0xc3}, + {0x8827, 0x92}, + {0x8828, 0x08}, + {0x8829, 0xe5}, + {0x882a, 0x32}, + {0x882b, 0x30}, + {0x882c, 0xe5}, + {0x882d, 0x12}, + {0x882e, 0x90}, + {0x882f, 0x56}, + {0x8830, 0x90}, + {0x8831, 0xe0}, + {0x8832, 0xf5}, + {0x8833, 0x09}, + {0x8834, 0x30}, + {0x8835, 0x30}, + {0x8836, 0x09}, + {0x8837, 0x30}, + {0x8838, 0x05}, + {0x8839, 0x03}, + {0x883a, 0xd3}, + {0x883b, 0x80}, + {0x883c, 0x01}, + {0x883d, 0xc3}, + {0x883e, 0x92}, + {0x883f, 0x0d}, + {0x8840, 0x90}, + {0x8841, 0x3f}, + {0x8842, 0x0c}, + {0x8843, 0xe5}, + {0x8844, 0x32}, + {0x8845, 0xf0}, + {0x8846, 0xd0}, + {0x8847, 0xd0}, + {0x8848, 0xd0}, + {0x8849, 0x82}, + {0x884a, 0xd0}, + {0x884b, 0x83}, + {0x884c, 0xd0}, + {0x884d, 0xe0}, + {0x884e, 0x32}, + {0x884f, 0x90}, + {0x8850, 0x0e}, + {0x8851, 0x7d}, + {0x8852, 0xe4}, + {0x8853, 0x93}, + {0x8854, 0xfe}, + {0x8855, 0x74}, + {0x8856, 0x01}, + {0x8857, 0x93}, + {0x8858, 0xff}, + {0x8859, 0xc3}, + {0x885a, 0x90}, + {0x885b, 0x0e}, + {0x885c, 0x7b}, + {0x885d, 0x74}, + {0x885e, 0x01}, + {0x885f, 0x93}, + {0x8860, 0x9f}, + {0x8861, 0xff}, + {0x8862, 0xe4}, + {0x8863, 0x93}, + {0x8864, 0x9e}, + {0x8865, 0xfe}, + {0x8866, 0xe4}, + {0x8867, 0x8f}, + {0x8868, 0x3b}, + {0x8869, 0x8e}, + {0x886a, 0x3a}, + {0x886b, 0xf5}, + {0x886c, 0x39}, + {0x886d, 0xf5}, + {0x886e, 0x38}, + {0x886f, 0xab}, + {0x8870, 0x3b}, + {0x8871, 0xaa}, + {0x8872, 0x3a}, + {0x8873, 0xa9}, + {0x8874, 0x39}, + {0x8875, 0xa8}, + {0x8876, 0x38}, + {0x8877, 0xaf}, + {0x8878, 0x49}, + {0x8879, 0xfc}, + {0x887a, 0xfd}, + {0x887b, 0xfe}, + {0x887c, 0x12}, + {0x887d, 0x02}, + {0x887e, 0xf5}, + {0x887f, 0x12}, + {0x8880, 0x0b}, + {0x8881, 0x16}, + {0x8882, 0xe4}, + {0x8883, 0x7b}, + {0x8884, 0xff}, + {0x8885, 0xfa}, + {0x8886, 0xf9}, + {0x8887, 0xf8}, + {0x8888, 0x12}, + {0x8889, 0x03}, + {0x888a, 0x80}, + {0x888b, 0x12}, + {0x888c, 0x0b}, + {0x888d, 0x16}, + {0x888e, 0x90}, + {0x888f, 0x0e}, + {0x8890, 0x69}, + {0x8891, 0xe4}, + {0x8892, 0x12}, + {0x8893, 0x0b}, + {0x8894, 0x2b}, + {0x8895, 0x12}, + {0x8896, 0x0b}, + {0x8897, 0x16}, + {0x8898, 0xe4}, + {0x8899, 0x85}, + {0x889a, 0x48}, + {0x889b, 0x37}, + {0x889c, 0xf5}, + {0x889d, 0x36}, + {0x889e, 0xf5}, + {0x889f, 0x35}, + {0x88a0, 0xf5}, + {0x88a1, 0x34}, + {0x88a2, 0xaf}, + {0x88a3, 0x37}, + {0x88a4, 0xae}, + {0x88a5, 0x36}, + {0x88a6, 0xad}, + {0x88a7, 0x35}, + {0x88a8, 0xac}, + {0x88a9, 0x34}, + {0x88aa, 0xa3}, + {0x88ab, 0x12}, + {0x88ac, 0x0b}, + {0x88ad, 0x2b}, + {0x88ae, 0x8f}, + {0x88af, 0x37}, + {0x88b0, 0x8e}, + {0x88b1, 0x36}, + {0x88b2, 0x8d}, + {0x88b3, 0x35}, + {0x88b4, 0x8c}, + {0x88b5, 0x34}, + {0x88b6, 0xe5}, + {0x88b7, 0x3b}, + {0x88b8, 0x45}, + {0x88b9, 0x37}, + {0x88ba, 0xf5}, + {0x88bb, 0x3b}, + {0x88bc, 0xe5}, + {0x88bd, 0x3a}, + {0x88be, 0x45}, + {0x88bf, 0x36}, + {0x88c0, 0xf5}, + {0x88c1, 0x3a}, + {0x88c2, 0xe5}, + {0x88c3, 0x39}, + {0x88c4, 0x45}, + {0x88c5, 0x35}, + {0x88c6, 0xf5}, + {0x88c7, 0x39}, + {0x88c8, 0xe5}, + {0x88c9, 0x38}, + {0x88ca, 0x45}, + {0x88cb, 0x34}, + {0x88cc, 0xf5}, + {0x88cd, 0x38}, + {0x88ce, 0xe4}, + {0x88cf, 0xf5}, + {0x88d0, 0x22}, + {0x88d1, 0xf5}, + {0x88d2, 0x23}, + {0x88d3, 0x85}, + {0x88d4, 0x3b}, + {0x88d5, 0x31}, + {0x88d6, 0x85}, + {0x88d7, 0x3a}, + {0x88d8, 0x30}, + {0x88d9, 0x85}, + {0x88da, 0x39}, + {0x88db, 0x2f}, + {0x88dc, 0x85}, + {0x88dd, 0x38}, + {0x88de, 0x2e}, + {0x88df, 0x02}, + {0x88e0, 0x0a}, + {0x88e1, 0xba}, + {0x88e2, 0x78}, + {0x88e3, 0x4f}, + {0x88e4, 0x7e}, + {0x88e5, 0x00}, + {0x88e6, 0xe6}, + {0x88e7, 0xfc}, + {0x88e8, 0x08}, + {0x88e9, 0xe6}, + {0x88ea, 0xfd}, + {0x88eb, 0x12}, + {0x88ec, 0x02}, + {0x88ed, 0x8e}, + {0x88ee, 0x7c}, + {0x88ef, 0x00}, + {0x88f0, 0x22}, + {0x88f1, 0xe0}, + {0x88f2, 0xa3}, + {0x88f3, 0xe0}, + {0x88f4, 0x75}, + {0x88f5, 0xf0}, + {0x88f6, 0x02}, + {0x88f7, 0xa4}, + {0x88f8, 0xff}, + {0x88f9, 0xae}, + {0x88fa, 0xf0}, + {0x88fb, 0xc3}, + {0x88fc, 0x08}, + {0x88fd, 0xe6}, + {0x88fe, 0x9f}, + {0x88ff, 0xf6}, + {0x8900, 0x18}, + {0x8901, 0xe6}, + {0x8902, 0x9e}, + {0x8903, 0xf6}, + {0x8904, 0x22}, + {0x8905, 0xff}, + {0x8906, 0xe5}, + {0x8907, 0xf0}, + {0x8908, 0x34}, + {0x8909, 0x60}, + {0x890a, 0x8f}, + {0x890b, 0x82}, + {0x890c, 0xf5}, + {0x890d, 0x83}, + {0x890e, 0xec}, + {0x890f, 0xf0}, + {0x8910, 0x22}, + {0x8911, 0xe4}, + {0x8912, 0xfc}, + {0x8913, 0xfd}, + {0x8914, 0x12}, + {0x8915, 0x04}, + {0x8916, 0x53}, + {0x8917, 0x78}, + {0x8918, 0x59}, + {0x8919, 0xe6}, + {0x891a, 0xc3}, + {0x891b, 0x13}, + {0x891c, 0xfe}, + {0x891d, 0x08}, + {0x891e, 0xe6}, + {0x891f, 0x13}, + {0x8920, 0x22}, + {0x8921, 0x78}, + {0x8922, 0x4f}, + {0x8923, 0xe6}, + {0x8924, 0xfe}, + {0x8925, 0x08}, + {0x8926, 0xe6}, + {0x8927, 0xff}, + {0x8928, 0xe4}, + {0x8929, 0xfc}, + {0x892a, 0xfd}, + {0x892b, 0x22}, + {0x892c, 0xe7}, + {0x892d, 0xc4}, + {0x892e, 0xf8}, + {0x892f, 0x54}, + {0x8930, 0xf0}, + {0x8931, 0xc8}, + {0x8932, 0x68}, + {0x8933, 0xf7}, + {0x8934, 0x09}, + {0x8935, 0xe7}, + {0x8936, 0xc4}, + {0x8937, 0x54}, + {0x8938, 0x0f}, + {0x8939, 0x48}, + {0x893a, 0xf7}, + {0x893b, 0x22}, + {0x893c, 0xe6}, + {0x893d, 0xfc}, + {0x893e, 0xed}, + {0x893f, 0x75}, + {0x8940, 0xf0}, + {0x8941, 0x04}, + {0x8942, 0xa4}, + {0x8943, 0x22}, + {0x8944, 0xe0}, + {0x8945, 0xfe}, + {0x8946, 0xa3}, + {0x8947, 0xe0}, + {0x8948, 0xfd}, + {0x8949, 0xee}, + {0x894a, 0xf6}, + {0x894b, 0xed}, + {0x894c, 0x08}, + {0x894d, 0xf6}, + {0x894e, 0x22}, + {0x894f, 0x13}, + {0x8950, 0xff}, + {0x8951, 0xc3}, + {0x8952, 0xe6}, + {0x8953, 0x9f}, + {0x8954, 0xff}, + {0x8955, 0x18}, + {0x8956, 0xe6}, + {0x8957, 0x9e}, + {0x8958, 0xfe}, + {0x8959, 0x22}, + {0x895a, 0xe6}, + {0x895b, 0xc3}, + {0x895c, 0x13}, + {0x895d, 0xf7}, + {0x895e, 0x08}, + {0x895f, 0xe6}, + {0x8960, 0x13}, + {0x8961, 0x09}, + {0x8962, 0xf7}, + {0x8963, 0x22}, + {0x8964, 0xe4}, + {0x8965, 0xf5}, + {0x8966, 0x49}, + {0x8967, 0x90}, + {0x8968, 0x0e}, + {0x8969, 0x77}, + {0x896a, 0x93}, + {0x896b, 0xff}, + {0x896c, 0xe4}, + {0x896d, 0x8f}, + {0x896e, 0x37}, + {0x896f, 0xf5}, + {0x8970, 0x36}, + {0x8971, 0xf5}, + {0x8972, 0x35}, + {0x8973, 0xf5}, + {0x8974, 0x34}, + {0x8975, 0xaf}, + {0x8976, 0x37}, + {0x8977, 0xae}, + {0x8978, 0x36}, + {0x8979, 0xad}, + {0x897a, 0x35}, + {0x897b, 0xac}, + {0x897c, 0x34}, + {0x897d, 0x90}, + {0x897e, 0x0e}, + {0x897f, 0x6a}, + {0x8980, 0x12}, + {0x8981, 0x0b}, + {0x8982, 0x2b}, + {0x8983, 0x8f}, + {0x8984, 0x37}, + {0x8985, 0x8e}, + {0x8986, 0x36}, + {0x8987, 0x8d}, + {0x8988, 0x35}, + {0x8989, 0x8c}, + {0x898a, 0x34}, + {0x898b, 0x90}, + {0x898c, 0x0e}, + {0x898d, 0x72}, + {0x898e, 0x12}, + {0x898f, 0x04}, + {0x8990, 0x36}, + {0x8991, 0xef}, + {0x8992, 0x45}, + {0x8993, 0x37}, + {0x8994, 0xf5}, + {0x8995, 0x37}, + {0x8996, 0xee}, + {0x8997, 0x45}, + {0x8998, 0x36}, + {0x8999, 0xf5}, + {0x899a, 0x36}, + {0x899b, 0xed}, + {0x899c, 0x45}, + {0x899d, 0x35}, + {0x899e, 0xf5}, + {0x899f, 0x35}, + {0x89a0, 0xec}, + {0x89a1, 0x45}, + {0x89a2, 0x34}, + {0x89a3, 0xf5}, + {0x89a4, 0x34}, + {0x89a5, 0xe4}, + {0x89a6, 0xf5}, + {0x89a7, 0x22}, + {0x89a8, 0xf5}, + {0x89a9, 0x23}, + {0x89aa, 0x85}, + {0x89ab, 0x37}, + {0x89ac, 0x31}, + {0x89ad, 0x85}, + {0x89ae, 0x36}, + {0x89af, 0x30}, + {0x89b0, 0x85}, + {0x89b1, 0x35}, + {0x89b2, 0x2f}, + {0x89b3, 0x85}, + {0x89b4, 0x34}, + {0x89b5, 0x2e}, + {0x89b6, 0x12}, + {0x89b7, 0x0a}, + {0x89b8, 0xba}, + {0x89b9, 0xe4}, + {0x89ba, 0xf5}, + {0x89bb, 0x22}, + {0x89bc, 0xf5}, + {0x89bd, 0x23}, + {0x89be, 0x90}, + {0x89bf, 0x0e}, + {0x89c0, 0x72}, + {0x89c1, 0x12}, + {0x89c2, 0x0b}, + {0x89c3, 0x1f}, + {0x89c4, 0x12}, + {0x89c5, 0x0a}, + {0x89c6, 0xba}, + {0x89c7, 0xe4}, + {0x89c8, 0xf5}, + {0x89c9, 0x22}, + {0x89ca, 0xf5}, + {0x89cb, 0x23}, + {0x89cc, 0x90}, + {0x89cd, 0x0e}, + {0x89ce, 0x6e}, + {0x89cf, 0x12}, + {0x89d0, 0x0b}, + {0x89d1, 0x1f}, + {0x89d2, 0x02}, + {0x89d3, 0x0a}, + {0x89d4, 0xba}, + {0x89d5, 0x75}, + {0x89d6, 0x89}, + {0x89d7, 0x03}, + {0x89d8, 0x75}, + {0x89d9, 0xa8}, + {0x89da, 0x01}, + {0x89db, 0x75}, + {0x89dc, 0xb8}, + {0x89dd, 0x04}, + {0x89de, 0x75}, + {0x89df, 0x34}, + {0x89e0, 0xff}, + {0x89e1, 0x75}, + {0x89e2, 0x35}, + {0x89e3, 0x0e}, + {0x89e4, 0x75}, + {0x89e5, 0x36}, + {0x89e6, 0x15}, + {0x89e7, 0x75}, + {0x89e8, 0x37}, + {0x89e9, 0x0d}, + {0x89ea, 0x12}, + {0x89eb, 0x0a}, + {0x89ec, 0x3e}, + {0x89ed, 0x12}, + {0x89ee, 0x00}, + {0x89ef, 0x09}, + {0x89f0, 0x12}, + {0x89f1, 0x0b}, + {0x89f2, 0x31}, + {0x89f3, 0x12}, + {0x89f4, 0x00}, + {0x89f5, 0x06}, + {0x89f6, 0xd2}, + {0x89f7, 0x00}, + {0x89f8, 0xd2}, + {0x89f9, 0x33}, + {0x89fa, 0xd2}, + {0x89fb, 0xaf}, + {0x89fc, 0x75}, + {0x89fd, 0x34}, + {0x89fe, 0xff}, + {0x89ff, 0x75}, + {0x8a00, 0x35}, + {0x8a01, 0x0e}, + {0x8a02, 0x75}, + {0x8a03, 0x36}, + {0x8a04, 0x49}, + {0x8a05, 0x75}, + {0x8a06, 0x37}, + {0x8a07, 0x03}, + {0x8a08, 0x12}, + {0x8a09, 0x0a}, + {0x8a0a, 0x3e}, + {0x8a0b, 0x30}, + {0x8a0c, 0x08}, + {0x8a0d, 0x09}, + {0x8a0e, 0xc2}, + {0x8a0f, 0x33}, + {0x8a10, 0x12}, + {0x8a11, 0x06}, + {0x8a12, 0x61}, + {0x8a13, 0xc2}, + {0x8a14, 0x08}, + {0x8a15, 0xd2}, + {0x8a16, 0x33}, + {0x8a17, 0x30}, + {0x8a18, 0x09}, + {0x8a19, 0x09}, + {0x8a1a, 0xc2}, + {0x8a1b, 0x35}, + {0x8a1c, 0x12}, + {0x8a1d, 0x00}, + {0x8a1e, 0x0e}, + {0x8a1f, 0xc2}, + {0x8a20, 0x09}, + {0x8a21, 0xd2}, + {0x8a22, 0x35}, + {0x8a23, 0x30}, + {0x8a24, 0x0e}, + {0x8a25, 0x03}, + {0x8a26, 0x12}, + {0x8a27, 0x04}, + {0x8a28, 0x91}, + {0x8a29, 0x30}, + {0x8a2a, 0x34}, + {0x8a2b, 0xdf}, + {0x8a2c, 0x90}, + {0x8a2d, 0x30}, + {0x8a2e, 0x29}, + {0x8a2f, 0xe5}, + {0x8a30, 0x1e}, + {0x8a31, 0xf0}, + {0x8a32, 0xb4}, + {0x8a33, 0x10}, + {0x8a34, 0x05}, + {0x8a35, 0x90}, + {0x8a36, 0x30}, + {0x8a37, 0x23}, + {0x8a38, 0xe4}, + {0x8a39, 0xf0}, + {0x8a3a, 0xc2}, + {0x8a3b, 0x34}, + {0x8a3c, 0x80}, + {0x8a3d, 0xcd}, + {0x8a3e, 0xae}, + {0x8a3f, 0x35}, + {0x8a40, 0xaf}, + {0x8a41, 0x36}, + {0x8a42, 0xe4}, + {0x8a43, 0xfd}, + {0x8a44, 0xed}, + {0x8a45, 0xc3}, + {0x8a46, 0x95}, + {0x8a47, 0x37}, + {0x8a48, 0x50}, + {0x8a49, 0x33}, + {0x8a4a, 0x12}, + {0x8a4b, 0x0b}, + {0x8a4c, 0x78}, + {0x8a4d, 0xe4}, + {0x8a4e, 0x93}, + {0x8a4f, 0xf5}, + {0x8a50, 0x38}, + {0x8a51, 0x74}, + {0x8a52, 0x01}, + {0x8a53, 0x93}, + {0x8a54, 0xf5}, + {0x8a55, 0x39}, + {0x8a56, 0x45}, + {0x8a57, 0x38}, + {0x8a58, 0x60}, + {0x8a59, 0x23}, + {0x8a5a, 0x85}, + {0x8a5b, 0x39}, + {0x8a5c, 0x82}, + {0x8a5d, 0x85}, + {0x8a5e, 0x38}, + {0x8a5f, 0x83}, + {0x8a60, 0xe0}, + {0x8a61, 0xfc}, + {0x8a62, 0x12}, + {0x8a63, 0x0b}, + {0x8a64, 0x78}, + {0x8a65, 0x74}, + {0x8a66, 0x03}, + {0x8a67, 0x93}, + {0x8a68, 0x52}, + {0x8a69, 0x04}, + {0x8a6a, 0x12}, + {0x8a6b, 0x0b}, + {0x8a6c, 0x78}, + {0x8a6d, 0x74}, + {0x8a6e, 0x02}, + {0x8a6f, 0x93}, + {0x8a70, 0x42}, + {0x8a71, 0x04}, + {0x8a72, 0x85}, + {0x8a73, 0x39}, + {0x8a74, 0x82}, + {0x8a75, 0x85}, + {0x8a76, 0x38}, + {0x8a77, 0x83}, + {0x8a78, 0xec}, + {0x8a79, 0xf0}, + {0x8a7a, 0x0d}, + {0x8a7b, 0x80}, + {0x8a7c, 0xc7}, + {0x8a7d, 0x22}, + {0x8a7e, 0x78}, + {0x8a7f, 0xbb}, + {0x8a80, 0xe6}, + {0x8a81, 0xd3}, + {0x8a82, 0x08}, + {0x8a83, 0xff}, + {0x8a84, 0xe6}, + {0x8a85, 0x64}, + {0x8a86, 0x80}, + {0x8a87, 0xf8}, + {0x8a88, 0xef}, + {0x8a89, 0x64}, + {0x8a8a, 0x80}, + {0x8a8b, 0x98}, + {0x8a8c, 0x22}, + {0x8a8d, 0x93}, + {0x8a8e, 0xff}, + {0x8a8f, 0x7e}, + {0x8a90, 0x00}, + {0x8a91, 0xe6}, + {0x8a92, 0xfc}, + {0x8a93, 0x08}, + {0x8a94, 0xe6}, + {0x8a95, 0xfd}, + {0x8a96, 0x12}, + {0x8a97, 0x02}, + {0x8a98, 0x8e}, + {0x8a99, 0x78}, + {0x8a9a, 0xbe}, + {0x8a9b, 0xe6}, + {0x8a9c, 0xfc}, + {0x8a9d, 0x08}, + {0x8a9e, 0xe6}, + {0x8a9f, 0xfd}, + {0x8aa0, 0xd3}, + {0x8aa1, 0xef}, + {0x8aa2, 0x9d}, + {0x8aa3, 0xee}, + {0x8aa4, 0x9c}, + {0x8aa5, 0x22}, + {0x8aa6, 0x78}, + {0x8aa7, 0xba}, + {0x8aa8, 0xd3}, + {0x8aa9, 0xe6}, + {0x8aaa, 0x64}, + {0x8aab, 0x80}, + {0x8aac, 0x94}, + {0x8aad, 0x80}, + {0x8aae, 0x22}, + {0x8aaf, 0x25}, + {0x8ab0, 0xe0}, + {0x8ab1, 0x24}, + {0x8ab2, 0x0a}, + {0x8ab3, 0xf8}, + {0x8ab4, 0xe6}, + {0x8ab5, 0xfe}, + {0x8ab6, 0x08}, + {0x8ab7, 0xe6}, + {0x8ab8, 0xff}, + {0x8ab9, 0x22}, + {0x8aba, 0xa2}, + {0x8abb, 0xaf}, + {0x8abc, 0x92}, + {0x8abd, 0x31}, + {0x8abe, 0xc2}, + {0x8abf, 0xaf}, + {0x8ac0, 0xe5}, + {0x8ac1, 0x23}, + {0x8ac2, 0x45}, + {0x8ac3, 0x22}, + {0x8ac4, 0x90}, + {0x8ac5, 0x0e}, + {0x8ac6, 0x5d}, + {0x8ac7, 0x60}, + {0x8ac8, 0x0b}, + {0x8ac9, 0x12}, + {0x8aca, 0x0b}, + {0x8acb, 0x6d}, + {0x8acc, 0xe0}, + {0x8acd, 0xf5}, + {0x8ace, 0x2c}, + {0x8acf, 0xe0}, + {0x8ad0, 0xf5}, + {0x8ad1, 0x2d}, + {0x8ad2, 0x80}, + {0x8ad3, 0x0f}, + {0x8ad4, 0x12}, + {0x8ad5, 0x0b}, + {0x8ad6, 0x6d}, + {0x8ad7, 0xe5}, + {0x8ad8, 0x30}, + {0x8ad9, 0xf0}, + {0x8ada, 0x90}, + {0x8adb, 0x0e}, + {0x8adc, 0x5f}, + {0x8add, 0x12}, + {0x8ade, 0x0b}, + {0x8adf, 0x6d}, + {0x8ae0, 0xe5}, + {0x8ae1, 0x31}, + {0x8ae2, 0xf0}, + {0x8ae3, 0xa2}, + {0x8ae4, 0x31}, + {0x8ae5, 0x92}, + {0x8ae6, 0xaf}, + {0x8ae7, 0x22}, + {0x8ae8, 0xd2}, + {0x8ae9, 0x01}, + {0x8aea, 0xc2}, + {0x8aeb, 0x02}, + {0x8aec, 0xe4}, + {0x8aed, 0xf5}, + {0x8aee, 0x1f}, + {0x8aef, 0xf5}, + {0x8af0, 0x1e}, + {0x8af1, 0xd2}, + {0x8af2, 0x34}, + {0x8af3, 0xd2}, + {0x8af4, 0x32}, + {0x8af5, 0xd2}, + {0x8af6, 0x35}, + {0x8af7, 0xd2}, + {0x8af8, 0x01}, + {0x8af9, 0xc2}, + {0x8afa, 0x02}, + {0x8afb, 0xf5}, + {0x8afc, 0x1f}, + {0x8afd, 0xf5}, + {0x8afe, 0x1e}, + {0x8aff, 0xd2}, + {0x8b00, 0x34}, + {0x8b01, 0xd2}, + {0x8b02, 0x32}, + {0x8b03, 0x22}, + {0x8b04, 0x2d}, + {0x8b05, 0xfd}, + {0x8b06, 0xe4}, + {0x8b07, 0x33}, + {0x8b08, 0xfc}, + {0x8b09, 0xe4}, + {0x8b0a, 0x93}, + {0x8b0b, 0xfe}, + {0x8b0c, 0xfb}, + {0x8b0d, 0xd3}, + {0x8b0e, 0xed}, + {0x8b0f, 0x9b}, + {0x8b10, 0x74}, + {0x8b11, 0x80}, + {0x8b12, 0xf8}, + {0x8b13, 0x6c}, + {0x8b14, 0x98}, + {0x8b15, 0x22}, + {0x8b16, 0x8f}, + {0x8b17, 0x3b}, + {0x8b18, 0x8e}, + {0x8b19, 0x3a}, + {0x8b1a, 0x8d}, + {0x8b1b, 0x39}, + {0x8b1c, 0x8c}, + {0x8b1d, 0x38}, + {0x8b1e, 0x22}, + {0x8b1f, 0x12}, + {0x8b20, 0x04}, + {0x8b21, 0x36}, + {0x8b22, 0x8f}, + {0x8b23, 0x31}, + {0x8b24, 0x8e}, + {0x8b25, 0x30}, + {0x8b26, 0x8d}, + {0x8b27, 0x2f}, + {0x8b28, 0x8c}, + {0x8b29, 0x2e}, + {0x8b2a, 0x22}, + {0x8b2b, 0x93}, + {0x8b2c, 0xf9}, + {0x8b2d, 0xf8}, + {0x8b2e, 0x02}, + {0x8b2f, 0x04}, + {0x8b30, 0x23}, + {0x8b31, 0x90}, + {0x8b32, 0x0e}, + {0x8b33, 0x81}, + {0x8b34, 0x12}, + {0x8b35, 0x04}, + {0x8b36, 0x36}, + {0x8b37, 0x8f}, + {0x8b38, 0x46}, + {0x8b39, 0x8e}, + {0x8b3a, 0x45}, + {0x8b3b, 0x8d}, + {0x8b3c, 0x44}, + {0x8b3d, 0x8c}, + {0x8b3e, 0x43}, + {0x8b3f, 0xd2}, + {0x8b40, 0x06}, + {0x8b41, 0x30}, + {0x8b42, 0x06}, + {0x8b43, 0x03}, + {0x8b44, 0xd3}, + {0x8b45, 0x80}, + {0x8b46, 0x01}, + {0x8b47, 0xc3}, + {0x8b48, 0x92}, + {0x8b49, 0x0e}, + {0x8b4a, 0x22}, + {0x8b4b, 0xc0}, + {0x8b4c, 0xe0}, + {0x8b4d, 0xc0}, + {0x8b4e, 0x83}, + {0x8b4f, 0xc0}, + {0x8b50, 0x82}, + {0x8b51, 0x90}, + {0x8b52, 0x3f}, + {0x8b53, 0x0d}, + {0x8b54, 0xe0}, + {0x8b55, 0xf5}, + {0x8b56, 0x33}, + {0x8b57, 0xe5}, + {0x8b58, 0x33}, + {0x8b59, 0xf0}, + {0x8b5a, 0xd0}, + {0x8b5b, 0x82}, + {0x8b5c, 0xd0}, + {0x8b5d, 0x83}, + {0x8b5e, 0xd0}, + {0x8b5f, 0xe0}, + {0x8b60, 0x32}, + {0x8b61, 0x78}, + {0x8b62, 0x7f}, + {0x8b63, 0xe4}, + {0x8b64, 0xf6}, + {0x8b65, 0xd8}, + {0x8b66, 0xfd}, + {0x8b67, 0x75}, + {0x8b68, 0x81}, + {0x8b69, 0xca}, + {0x8b6a, 0x02}, + {0x8b6b, 0x09}, + {0x8b6c, 0xd5}, + {0x8b6d, 0xe4}, + {0x8b6e, 0x93}, + {0x8b6f, 0xfe}, + {0x8b70, 0x74}, + {0x8b71, 0x01}, + {0x8b72, 0x93}, + {0x8b73, 0xf5}, + {0x8b74, 0x82}, + {0x8b75, 0x8e}, + {0x8b76, 0x83}, + {0x8b77, 0x22}, + {0x8b78, 0x8f}, + {0x8b79, 0x82}, + {0x8b7a, 0x8e}, + {0x8b7b, 0x83}, + {0x8b7c, 0x75}, + {0x8b7d, 0xf0}, + {0x8b7e, 0x04}, + {0x8b7f, 0xed}, + {0x8b80, 0x02}, + {0x8b81, 0x04}, + {0x8b82, 0x5f}, + {0x8b83, 0x00}, + {0x8b84, 0x00}, + {0x8b85, 0x00}, + {0x8b86, 0x00}, + {0x8b87, 0x00}, + {0x8b88, 0x00}, + {0x8b89, 0x00}, + {0x8b8a, 0x00}, + {0x8b8b, 0x00}, + {0x8b8c, 0x00}, + {0x8b8d, 0x00}, + {0x8b8e, 0x00}, + {0x8b8f, 0x00}, + {0x8b90, 0x00}, + {0x8b91, 0x00}, + {0x8b92, 0x00}, + {0x8b93, 0x00}, + {0x8b94, 0x00}, + {0x8b95, 0x00}, + {0x8b96, 0x00}, + {0x8b97, 0x00}, + {0x8b98, 0x00}, + {0x8b99, 0x00}, + {0x8b9a, 0x00}, + {0x8b9b, 0x00}, + {0x8b9c, 0x00}, + {0x8b9d, 0x00}, + {0x8b9e, 0x00}, + {0x8b9f, 0x00}, + {0x8ba0, 0x00}, + {0x8ba1, 0x00}, + {0x8ba2, 0x00}, + {0x8ba3, 0x00}, + {0x8ba4, 0x00}, + {0x8ba5, 0x00}, + {0x8ba6, 0x00}, + {0x8ba7, 0x00}, + {0x8ba8, 0x00}, + {0x8ba9, 0x00}, + {0x8baa, 0x00}, + {0x8bab, 0x00}, + {0x8bac, 0x00}, + {0x8bad, 0x00}, + {0x8bae, 0x00}, + {0x8baf, 0x00}, + {0x8bb0, 0x00}, + {0x8bb1, 0x00}, + {0x8bb2, 0x00}, + {0x8bb3, 0x00}, + {0x8bb4, 0x00}, + {0x8bb5, 0x00}, + {0x8bb6, 0x00}, + {0x8bb7, 0x00}, + {0x8bb8, 0x00}, + {0x8bb9, 0x00}, + {0x8bba, 0x00}, + {0x8bbb, 0x00}, + {0x8bbc, 0x00}, + {0x8bbd, 0x00}, + {0x8bbe, 0x00}, + {0x8bbf, 0x00}, + {0x8bc0, 0x00}, + {0x8bc1, 0x00}, + {0x8bc2, 0x00}, + {0x8bc3, 0x00}, + {0x8bc4, 0x00}, + {0x8bc5, 0x00}, + {0x8bc6, 0x00}, + {0x8bc7, 0x00}, + {0x8bc8, 0x00}, + {0x8bc9, 0x00}, + {0x8bca, 0x00}, + {0x8bcb, 0x00}, + {0x8bcc, 0x00}, + {0x8bcd, 0x00}, + {0x8bce, 0x00}, + {0x8bcf, 0x00}, + {0x8bd0, 0x00}, + {0x8bd1, 0x00}, + {0x8bd2, 0x00}, + {0x8bd3, 0x00}, + {0x8bd4, 0x00}, + {0x8bd5, 0x00}, + {0x8bd6, 0x00}, + {0x8bd7, 0x00}, + {0x8bd8, 0x00}, + {0x8bd9, 0x00}, + {0x8bda, 0x00}, + {0x8bdb, 0x00}, + {0x8bdc, 0x00}, + {0x8bdd, 0x00}, + {0x8bde, 0x00}, + {0x8bdf, 0x00}, + {0x8be0, 0x00}, + {0x8be1, 0x00}, + {0x8be2, 0x00}, + {0x8be3, 0x00}, + {0x8be4, 0x00}, + {0x8be5, 0x00}, + {0x8be6, 0x00}, + {0x8be7, 0x00}, + {0x8be8, 0x00}, + {0x8be9, 0x00}, + {0x8bea, 0x00}, + {0x8beb, 0x00}, + {0x8bec, 0x00}, + {0x8bed, 0x00}, + {0x8bee, 0x00}, + {0x8bef, 0x00}, + {0x8bf0, 0x00}, + {0x8bf1, 0x00}, + {0x8bf2, 0x00}, + {0x8bf3, 0x00}, + {0x8bf4, 0x00}, + {0x8bf5, 0x00}, + {0x8bf6, 0x00}, + {0x8bf7, 0x00}, + {0x8bf8, 0x00}, + {0x8bf9, 0x00}, + {0x8bfa, 0x00}, + {0x8bfb, 0x00}, + {0x8bfc, 0x00}, + {0x8bfd, 0x00}, + {0x8bfe, 0x00}, + {0x8bff, 0x00}, + {0x8c00, 0x00}, + {0x8c01, 0x00}, + {0x8c02, 0x00}, + {0x8c03, 0x00}, + {0x8c04, 0x00}, + {0x8c05, 0x00}, + {0x8c06, 0x00}, + {0x8c07, 0x00}, + {0x8c08, 0x00}, + {0x8c09, 0x00}, + {0x8c0a, 0x00}, + {0x8c0b, 0x00}, + {0x8c0c, 0x00}, + {0x8c0d, 0x00}, + {0x8c0e, 0x00}, + {0x8c0f, 0x00}, + {0x8c10, 0x00}, + {0x8c11, 0x00}, + {0x8c12, 0x00}, + {0x8c13, 0x00}, + {0x8c14, 0x00}, + {0x8c15, 0x00}, + {0x8c16, 0x00}, + {0x8c17, 0x00}, + {0x8c18, 0x00}, + {0x8c19, 0x00}, + {0x8c1a, 0x00}, + {0x8c1b, 0x00}, + {0x8c1c, 0x00}, + {0x8c1d, 0x00}, + {0x8c1e, 0x00}, + {0x8c1f, 0x00}, + {0x8c20, 0x00}, + {0x8c21, 0x00}, + {0x8c22, 0x00}, + {0x8c23, 0x00}, + {0x8c24, 0x00}, + {0x8c25, 0x00}, + {0x8c26, 0x00}, + {0x8c27, 0x00}, + {0x8c28, 0x00}, + {0x8c29, 0x00}, + {0x8c2a, 0x00}, + {0x8c2b, 0x00}, + {0x8c2c, 0x00}, + {0x8c2d, 0x00}, + {0x8c2e, 0x00}, + {0x8c2f, 0x00}, + {0x8c30, 0x00}, + {0x8c31, 0x00}, + {0x8c32, 0x00}, + {0x8c33, 0x00}, + {0x8c34, 0x00}, + {0x8c35, 0x00}, + {0x8c36, 0x00}, + {0x8c37, 0x00}, + {0x8c38, 0x00}, + {0x8c39, 0x00}, + {0x8c3a, 0x00}, + {0x8c3b, 0x00}, + {0x8c3c, 0x00}, + {0x8c3d, 0x00}, + {0x8c3e, 0x00}, + {0x8c3f, 0x00}, + {0x8c40, 0x00}, + {0x8c41, 0x00}, + {0x8c42, 0x00}, + {0x8c43, 0x00}, + {0x8c44, 0x00}, + {0x8c45, 0x00}, + {0x8c46, 0x00}, + {0x8c47, 0x00}, + {0x8c48, 0x00}, + {0x8c49, 0x00}, + {0x8c4a, 0x00}, + {0x8c4b, 0x00}, + {0x8c4c, 0x00}, + {0x8c4d, 0x00}, + {0x8c4e, 0x00}, + {0x8c4f, 0x00}, + {0x8c50, 0x00}, + {0x8c51, 0x00}, + {0x8c52, 0x00}, + {0x8c53, 0x00}, + {0x8c54, 0x00}, + {0x8c55, 0x00}, + {0x8c56, 0x00}, + {0x8c57, 0x00}, + {0x8c58, 0x00}, + {0x8c59, 0x00}, + {0x8c5a, 0x00}, + {0x8c5b, 0x00}, + {0x8c5c, 0x00}, + {0x8c5d, 0x00}, + {0x8c5e, 0x00}, + {0x8c5f, 0x00}, + {0x8c60, 0x00}, + {0x8c61, 0x00}, + {0x8c62, 0x00}, + {0x8c63, 0x00}, + {0x8c64, 0x00}, + {0x8c65, 0x00}, + {0x8c66, 0x00}, + {0x8c67, 0x00}, + {0x8c68, 0x00}, + {0x8c69, 0x00}, + {0x8c6a, 0x00}, + {0x8c6b, 0x00}, + {0x8c6c, 0x00}, + {0x8c6d, 0x00}, + {0x8c6e, 0x00}, + {0x8c6f, 0x00}, + {0x8c70, 0x00}, + {0x8c71, 0x00}, + {0x8c72, 0x00}, + {0x8c73, 0x00}, + {0x8c74, 0x00}, + {0x8c75, 0x00}, + {0x8c76, 0x00}, + {0x8c77, 0x00}, + {0x8c78, 0x00}, + {0x8c79, 0x00}, + {0x8c7a, 0x00}, + {0x8c7b, 0x00}, + {0x8c7c, 0x00}, + {0x8c7d, 0x00}, + {0x8c7e, 0x00}, + {0x8c7f, 0x00}, + {0x8c80, 0x00}, + {0x8c81, 0x00}, + {0x8c82, 0x00}, + {0x8c83, 0x00}, + {0x8c84, 0x00}, + {0x8c85, 0x00}, + {0x8c86, 0x00}, + {0x8c87, 0x00}, + {0x8c88, 0x00}, + {0x8c89, 0x00}, + {0x8c8a, 0x00}, + {0x8c8b, 0x00}, + {0x8c8c, 0x00}, + {0x8c8d, 0x00}, + {0x8c8e, 0x00}, + {0x8c8f, 0x00}, + {0x8c90, 0x00}, + {0x8c91, 0x00}, + {0x8c92, 0x00}, + {0x8c93, 0x00}, + {0x8c94, 0x00}, + {0x8c95, 0x00}, + {0x8c96, 0x00}, + {0x8c97, 0x00}, + {0x8c98, 0x00}, + {0x8c99, 0x00}, + {0x8c9a, 0x00}, + {0x8c9b, 0x00}, + {0x8c9c, 0x00}, + {0x8c9d, 0x00}, + {0x8c9e, 0x00}, + {0x8c9f, 0x00}, + {0x8ca0, 0x00}, + {0x8ca1, 0x00}, + {0x8ca2, 0x00}, + {0x8ca3, 0x00}, + {0x8ca4, 0x00}, + {0x8ca5, 0x00}, + {0x8ca6, 0x00}, + {0x8ca7, 0x00}, + {0x8ca8, 0x00}, + {0x8ca9, 0x00}, + {0x8caa, 0x00}, + {0x8cab, 0x00}, + {0x8cac, 0x00}, + {0x8cad, 0x00}, + {0x8cae, 0x00}, + {0x8caf, 0x00}, + {0x8cb0, 0x00}, + {0x8cb1, 0x00}, + {0x8cb2, 0x00}, + {0x8cb3, 0x00}, + {0x8cb4, 0x00}, + {0x8cb5, 0x00}, + {0x8cb6, 0x00}, + {0x8cb7, 0x00}, + {0x8cb8, 0x00}, + {0x8cb9, 0x00}, + {0x8cba, 0x00}, + {0x8cbb, 0x00}, + {0x8cbc, 0x00}, + {0x8cbd, 0x00}, + {0x8cbe, 0x00}, + {0x8cbf, 0x00}, + {0x8cc0, 0x00}, + {0x8cc1, 0x00}, + {0x8cc2, 0x00}, + {0x8cc3, 0x00}, + {0x8cc4, 0x00}, + {0x8cc5, 0x00}, + {0x8cc6, 0x00}, + {0x8cc7, 0x00}, + {0x8cc8, 0x00}, + {0x8cc9, 0x00}, + {0x8cca, 0x00}, + {0x8ccb, 0x00}, + {0x8ccc, 0x00}, + {0x8ccd, 0x00}, + {0x8cce, 0x00}, + {0x8ccf, 0x00}, + {0x8cd0, 0x00}, + {0x8cd1, 0x00}, + {0x8cd2, 0x00}, + {0x8cd3, 0x00}, + {0x8cd4, 0x00}, + {0x8cd5, 0x00}, + {0x8cd6, 0x00}, + {0x8cd7, 0x00}, + {0x8cd8, 0x00}, + {0x8cd9, 0x00}, + {0x8cda, 0x00}, + {0x8cdb, 0x00}, + {0x8cdc, 0x00}, + {0x8cdd, 0x00}, + {0x8cde, 0x00}, + {0x8cdf, 0x00}, + {0x8ce0, 0x00}, + {0x8ce1, 0x00}, + {0x8ce2, 0x00}, + {0x8ce3, 0x00}, + {0x8ce4, 0x00}, + {0x8ce5, 0x00}, + {0x8ce6, 0x00}, + {0x8ce7, 0x00}, + {0x8ce8, 0x00}, + {0x8ce9, 0x00}, + {0x8cea, 0x00}, + {0x8ceb, 0x00}, + {0x8cec, 0x00}, + {0x8ced, 0x00}, + {0x8cee, 0x00}, + {0x8cef, 0x00}, + {0x8cf0, 0x00}, + {0x8cf1, 0x00}, + {0x8cf2, 0x00}, + {0x8cf3, 0x00}, + {0x8cf4, 0x00}, + {0x8cf5, 0x00}, + {0x8cf6, 0x00}, + {0x8cf7, 0x00}, + {0x8cf8, 0x00}, + {0x8cf9, 0x00}, + {0x8cfa, 0x00}, + {0x8cfb, 0x00}, + {0x8cfc, 0x00}, + {0x8cfd, 0x00}, + {0x8cfe, 0x00}, + {0x8cff, 0x00}, + {0x8d00, 0x00}, + {0x8d01, 0x00}, + {0x8d02, 0x00}, + {0x8d03, 0x00}, + {0x8d04, 0x00}, + {0x8d05, 0x00}, + {0x8d06, 0x00}, + {0x8d07, 0x00}, + {0x8d08, 0x00}, + {0x8d09, 0x00}, + {0x8d0a, 0x00}, + {0x8d0b, 0x00}, + {0x8d0c, 0x00}, + {0x8d0d, 0x00}, + {0x8d0e, 0x00}, + {0x8d0f, 0x00}, + {0x8d10, 0x00}, + {0x8d11, 0x00}, + {0x8d12, 0x00}, + {0x8d13, 0x00}, + {0x8d14, 0x00}, + {0x8d15, 0x00}, + {0x8d16, 0x00}, + {0x8d17, 0x00}, + {0x8d18, 0x00}, + {0x8d19, 0x00}, + {0x8d1a, 0x00}, + {0x8d1b, 0x00}, + {0x8d1c, 0x00}, + {0x8d1d, 0x00}, + {0x8d1e, 0x00}, + {0x8d1f, 0x00}, + {0x8d20, 0x00}, + {0x8d21, 0x00}, + {0x8d22, 0x00}, + {0x8d23, 0x00}, + {0x8d24, 0x00}, + {0x8d25, 0x00}, + {0x8d26, 0x00}, + {0x8d27, 0x00}, + {0x8d28, 0x00}, + {0x8d29, 0x00}, + {0x8d2a, 0x00}, + {0x8d2b, 0x00}, + {0x8d2c, 0x00}, + {0x8d2d, 0x00}, + {0x8d2e, 0x00}, + {0x8d2f, 0x00}, + {0x8d30, 0x00}, + {0x8d31, 0x00}, + {0x8d32, 0x00}, + {0x8d33, 0x00}, + {0x8d34, 0x00}, + {0x8d35, 0x00}, + {0x8d36, 0x00}, + {0x8d37, 0x00}, + {0x8d38, 0x00}, + {0x8d39, 0x00}, + {0x8d3a, 0x00}, + {0x8d3b, 0x00}, + {0x8d3c, 0x00}, + {0x8d3d, 0x00}, + {0x8d3e, 0x00}, + {0x8d3f, 0x00}, + {0x8d40, 0x00}, + {0x8d41, 0x00}, + {0x8d42, 0x00}, + {0x8d43, 0x00}, + {0x8d44, 0x00}, + {0x8d45, 0x00}, + {0x8d46, 0x00}, + {0x8d47, 0x00}, + {0x8d48, 0x00}, + {0x8d49, 0x00}, + {0x8d4a, 0x00}, + {0x8d4b, 0x00}, + {0x8d4c, 0x00}, + {0x8d4d, 0x00}, + {0x8d4e, 0x00}, + {0x8d4f, 0x00}, + {0x8d50, 0x00}, + {0x8d51, 0x00}, + {0x8d52, 0x00}, + {0x8d53, 0x00}, + {0x8d54, 0x00}, + {0x8d55, 0x00}, + {0x8d56, 0x00}, + {0x8d57, 0x00}, + {0x8d58, 0x00}, + {0x8d59, 0x00}, + {0x8d5a, 0x00}, + {0x8d5b, 0x00}, + {0x8d5c, 0x00}, + {0x8d5d, 0x00}, + {0x8d5e, 0x00}, + {0x8d5f, 0x00}, + {0x8d60, 0x00}, + {0x8d61, 0x00}, + {0x8d62, 0x00}, + {0x8d63, 0x00}, + {0x8d64, 0x00}, + {0x8d65, 0x00}, + {0x8d66, 0x00}, + {0x8d67, 0x00}, + {0x8d68, 0x00}, + {0x8d69, 0x00}, + {0x8d6a, 0x00}, + {0x8d6b, 0x00}, + {0x8d6c, 0x00}, + {0x8d6d, 0x00}, + {0x8d6e, 0x00}, + {0x8d6f, 0x00}, + {0x8d70, 0x00}, + {0x8d71, 0x00}, + {0x8d72, 0x00}, + {0x8d73, 0x00}, + {0x8d74, 0x00}, + {0x8d75, 0x00}, + {0x8d76, 0x00}, + {0x8d77, 0x00}, + {0x8d78, 0x00}, + {0x8d79, 0x00}, + {0x8d7a, 0x00}, + {0x8d7b, 0x00}, + {0x8d7c, 0x00}, + {0x8d7d, 0x00}, + {0x8d7e, 0x00}, + {0x8d7f, 0x00}, + {0x8d80, 0x00}, + {0x8d81, 0x00}, + {0x8d82, 0x00}, + {0x8d83, 0x00}, + {0x8d84, 0x00}, + {0x8d85, 0x00}, + {0x8d86, 0x00}, + {0x8d87, 0x00}, + {0x8d88, 0x00}, + {0x8d89, 0x00}, + {0x8d8a, 0x00}, + {0x8d8b, 0x00}, + {0x8d8c, 0x00}, + {0x8d8d, 0x00}, + {0x8d8e, 0x00}, + {0x8d8f, 0x00}, + {0x8d90, 0x00}, + {0x8d91, 0x00}, + {0x8d92, 0x00}, + {0x8d93, 0x00}, + {0x8d94, 0x00}, + {0x8d95, 0x00}, + {0x8d96, 0x00}, + {0x8d97, 0x00}, + {0x8d98, 0x00}, + {0x8d99, 0x00}, + {0x8d9a, 0x00}, + {0x8d9b, 0x00}, + {0x8d9c, 0x00}, + {0x8d9d, 0x00}, + {0x8d9e, 0x00}, + {0x8d9f, 0x00}, + {0x8da0, 0x00}, + {0x8da1, 0x00}, + {0x8da2, 0x00}, + {0x8da3, 0x00}, + {0x8da4, 0x00}, + {0x8da5, 0x00}, + {0x8da6, 0x00}, + {0x8da7, 0x00}, + {0x8da8, 0x00}, + {0x8da9, 0x00}, + {0x8daa, 0x00}, + {0x8dab, 0x00}, + {0x8dac, 0x00}, + {0x8dad, 0x00}, + {0x8dae, 0x00}, + {0x8daf, 0x00}, + {0x8db0, 0x00}, + {0x8db1, 0x00}, + {0x8db2, 0x00}, + {0x8db3, 0x00}, + {0x8db4, 0x00}, + {0x8db5, 0x00}, + {0x8db6, 0x00}, + {0x8db7, 0x00}, + {0x8db8, 0x00}, + {0x8db9, 0x00}, + {0x8dba, 0x00}, + {0x8dbb, 0x00}, + {0x8dbc, 0x00}, + {0x8dbd, 0x00}, + {0x8dbe, 0x00}, + {0x8dbf, 0x00}, + {0x8dc0, 0x00}, + {0x8dc1, 0x00}, + {0x8dc2, 0x00}, + {0x8dc3, 0x00}, + {0x8dc4, 0x00}, + {0x8dc5, 0x00}, + {0x8dc6, 0x00}, + {0x8dc7, 0x00}, + {0x8dc8, 0x00}, + {0x8dc9, 0x00}, + {0x8dca, 0x00}, + {0x8dcb, 0x00}, + {0x8dcc, 0x00}, + {0x8dcd, 0x00}, + {0x8dce, 0x00}, + {0x8dcf, 0x00}, + {0x8dd0, 0x00}, + {0x8dd1, 0x00}, + {0x8dd2, 0x00}, + {0x8dd3, 0x00}, + {0x8dd4, 0x00}, + {0x8dd5, 0x00}, + {0x8dd6, 0x00}, + {0x8dd7, 0x00}, + {0x8dd8, 0x00}, + {0x8dd9, 0x00}, + {0x8dda, 0x00}, + {0x8ddb, 0x00}, + {0x8ddc, 0x00}, + {0x8ddd, 0x00}, + {0x8dde, 0x00}, + {0x8ddf, 0x00}, + {0x8de0, 0x00}, + {0x8de1, 0x00}, + {0x8de2, 0x00}, + {0x8de3, 0x00}, + {0x8de4, 0x00}, + {0x8de5, 0x00}, + {0x8de6, 0x00}, + {0x8de7, 0x00}, + {0x8de8, 0x00}, + {0x8de9, 0x00}, + {0x8dea, 0x00}, + {0x8deb, 0x00}, + {0x8dec, 0x00}, + {0x8ded, 0x00}, + {0x8dee, 0x00}, + {0x8def, 0x00}, + {0x8df0, 0x00}, + {0x8df1, 0x00}, + {0x8df2, 0x00}, + {0x8df3, 0x00}, + {0x8df4, 0x00}, + {0x8df5, 0x00}, + {0x8df6, 0x00}, + {0x8df7, 0x00}, + {0x8df8, 0x00}, + {0x8df9, 0x00}, + {0x8dfa, 0x00}, + {0x8dfb, 0x00}, + {0x8dfc, 0x00}, + {0x8dfd, 0x00}, + {0x8dfe, 0x00}, + {0x8dff, 0x00}, + {0x8e00, 0x11}, + {0x8e01, 0x04}, + {0x8e02, 0x21}, + {0x8e03, 0x15}, + {0x8e04, 0x12}, + {0x8e05, 0x52}, + {0x8e06, 0x4f}, + {0x8e07, 0x56}, + {0x8e08, 0x54}, + {0x8e09, 0x20}, + {0x8e0a, 0x20}, + {0x8e0b, 0x20}, + {0x8e0c, 0x20}, + {0x8e0d, 0x20}, + {0x8e0e, 0x10}, + {0x8e0f, 0x01}, + {0x8e10, 0x10}, + {0x8e11, 0x00}, + {0x8e12, 0x56}, + {0x8e13, 0x40}, + {0x8e14, 0x1a}, + {0x8e15, 0x30}, + {0x8e16, 0x29}, + {0x8e17, 0x7e}, + {0x8e18, 0x00}, + {0x8e19, 0x30}, + {0x8e1a, 0x04}, + {0x8e1b, 0x20}, + {0x8e1c, 0xdf}, + {0x8e1d, 0x30}, + {0x8e1e, 0x05}, + {0x8e1f, 0x40}, + {0x8e20, 0xbf}, + {0x8e21, 0x50}, + {0x8e22, 0x25}, + {0x8e23, 0x04}, + {0x8e24, 0xfb}, + {0x8e25, 0x50}, + {0x8e26, 0x03}, + {0x8e27, 0x00}, + {0x8e28, 0xfd}, + {0x8e29, 0x50}, + {0x8e2a, 0x27}, + {0x8e2b, 0x01}, + {0x8e2c, 0xfe}, + {0x8e2d, 0x60}, + {0x8e2e, 0x00}, + {0x8e2f, 0x11}, + {0x8e30, 0x00}, + {0x8e31, 0x3f}, + {0x8e32, 0x05}, + {0x8e33, 0x30}, + {0x8e34, 0x00}, + {0x8e35, 0x3f}, + {0x8e36, 0x06}, + {0x8e37, 0x22}, + {0x8e38, 0x00}, + {0x8e39, 0x3f}, + {0x8e3a, 0x01}, + {0x8e3b, 0x29}, + {0x8e3c, 0x00}, + {0x8e3d, 0x3f}, + {0x8e3e, 0x02}, + {0x8e3f, 0x00}, + {0x8e40, 0x00}, + {0x8e41, 0x36}, + {0x8e42, 0x06}, + {0x8e43, 0x07}, + {0x8e44, 0x00}, + {0x8e45, 0x3f}, + {0x8e46, 0x0b}, + {0x8e47, 0x0f}, + {0x8e48, 0xf0}, + {0x8e49, 0x30}, + {0x8e4a, 0x01}, + {0x8e4b, 0x40}, + {0x8e4c, 0xbf}, + {0x8e4d, 0x30}, + {0x8e4e, 0x01}, + {0x8e4f, 0x00}, + {0x8e50, 0xbf}, + {0x8e51, 0x30}, + {0x8e52, 0x29}, + {0x8e53, 0x70}, + {0x8e54, 0x00}, + {0x8e55, 0x3a}, + {0x8e56, 0x00}, + {0x8e57, 0x00}, + {0x8e58, 0xff}, + {0x8e59, 0x3a}, + {0x8e5a, 0x00}, + {0x8e5b, 0x00}, + {0x8e5c, 0xff}, + {0x8e5d, 0x36}, + {0x8e5e, 0x03}, + {0x8e5f, 0x36}, + {0x8e60, 0x02}, + {0x8e61, 0x41}, + {0x8e62, 0x44}, + {0x8e63, 0x58}, + {0x8e64, 0x20}, + {0x8e65, 0x18}, + {0x8e66, 0x10}, + {0x8e67, 0x0a}, + {0x8e68, 0x04}, + {0x8e69, 0x04}, + {0x8e6a, 0x00}, + {0x8e6b, 0x03}, + {0x8e6c, 0xff}, + {0x8e6d, 0x64}, + {0x8e6e, 0x00}, + {0x8e6f, 0x00}, + {0x8e70, 0x80}, + {0x8e71, 0x00}, + {0x8e72, 0x00}, + {0x8e73, 0x00}, + {0x8e74, 0x00}, + {0x8e75, 0x00}, + {0x8e76, 0x00}, + {0x8e77, 0x02}, + {0x8e78, 0x04}, + {0x8e79, 0x06}, + {0x8e7a, 0x00}, + {0x8e7b, 0x03}, + {0x8e7c, 0x98}, + {0x8e7d, 0x00}, + {0x8e7e, 0xcc}, + {0x8e7f, 0x50}, + {0x8e80, 0x3c}, + {0x8e81, 0x28}, + {0x8e82, 0x1e}, + {0x8e83, 0x10}, + {0x8e84, 0x10}, + {0x8e85, 0x00}, + {0x8e86, 0x00}, + {0x8e87, 0x00}, + {0x8e88, 0x6e}, + {0x8e89, 0x06}, + {0x8e8a, 0x05}, + {0x8e8b, 0x00}, + {0x8e8c, 0xa5}, + {0x8e8d, 0x5a}, + {0x3022, 0x00}, + {0x3023, 0x00}, + {0x3024, 0x00}, + {0x3025, 0x00}, + {0x3026, 0x00}, + {0x3027, 0x00}, + {0x3028, 0x00}, + {0x3029, 0xFF}, + {0x3000, 0x00}, +#elif 0 // ddl@rock-chips.com : Touch Focus from OVT + {0x3000,0x20}, +{0x8000,0x02}, +{0x8001,0x0f}, +{0x8002,0xd6}, +{0x8003,0x02}, +{0x8004,0x0a}, +{0x8005,0x39}, +{0x8006,0xc2}, +{0x8007,0x01}, +{0x8008,0x22}, +{0x8009,0x22}, +{0x800a,0x00}, +{0x800b,0x02}, +{0x800c,0x0f}, +{0x800d,0xb2}, +{0x800e,0xe5}, +{0x800f,0x1f}, +{0x8010,0x70}, +{0x8011,0x72}, +{0x8012,0xf5}, +{0x8013,0x1e}, +{0x8014,0xd2}, +{0x8015,0x35}, +{0x8016,0xff}, +{0x8017,0xef}, +{0x8018,0x25}, +{0x8019,0xe0}, +{0x801a,0x24}, +{0x801b,0x4e}, +{0x801c,0xf8}, +{0x801d,0xe4}, +{0x801e,0xf6}, +{0x801f,0x08}, +{0x8020,0xf6}, +{0x8021,0x0f}, +{0x8022,0xbf}, +{0x8023,0x34}, +{0x8024,0xf2}, +{0x8025,0x90}, +{0x8026,0x0e}, +{0x8027,0x93}, +{0x8028,0xe4}, +{0x8029,0x93}, +{0x802a,0xff}, +{0x802b,0xe5}, +{0x802c,0x4b}, +{0x802d,0xc3}, +{0x802e,0x9f}, +{0x802f,0x50}, +{0x8030,0x04}, +{0x8031,0x7f}, +{0x8032,0x05}, +{0x8033,0x80}, +{0x8034,0x02}, +{0x8035,0x7f}, +{0x8036,0xfb}, +{0x8037,0x78}, +{0x8038,0xbd}, +{0x8039,0xa6}, +{0x803a,0x07}, +{0x803b,0x12}, +{0x803c,0x0f}, +{0x803d,0x04}, +{0x803e,0x40}, +{0x803f,0x04}, +{0x8040,0x7f}, +{0x8041,0x03}, +{0x8042,0x80}, +{0x8043,0x02}, +{0x8044,0x7f}, +{0x8045,0x30}, +{0x8046,0x78}, +{0x8047,0xbc}, +{0x8048,0xa6}, +{0x8049,0x07}, +{0x804a,0xe6}, +{0x804b,0x18}, +{0x804c,0xf6}, +{0x804d,0x08}, +{0x804e,0xe6}, +{0x804f,0x78}, +{0x8050,0xb9}, +{0x8051,0xf6}, +{0x8052,0x78}, +{0x8053,0xbc}, +{0x8054,0xe6}, +{0x8055,0x78}, +{0x8056,0xba}, +{0x8057,0xf6}, +{0x8058,0x78}, +{0x8059,0xbf}, +{0x805a,0x76}, +{0x805b,0x33}, +{0x805c,0xe4}, +{0x805d,0x08}, +{0x805e,0xf6}, +{0x805f,0x78}, +{0x8060,0xb8}, +{0x8061,0x76}, +{0x8062,0x01}, +{0x8063,0x75}, +{0x8064,0x4a}, +{0x8065,0x02}, +{0x8066,0x78}, +{0x8067,0xb6}, +{0x8068,0xf6}, +{0x8069,0x08}, +{0x806a,0xf6}, +{0x806b,0x74}, +{0x806c,0xff}, +{0x806d,0x78}, +{0x806e,0xc1}, +{0x806f,0xf6}, +{0x8070,0x08}, +{0x8071,0xf6}, +{0x8072,0x75}, +{0x8073,0x1f}, +{0x8074,0x01}, +{0x8075,0x78}, +{0x8076,0xbc}, +{0x8077,0xe6}, +{0x8078,0x75}, +{0x8079,0xf0}, +{0x807a,0x05}, +{0x807b,0xa4}, +{0x807c,0xf5}, +{0x807d,0x4b}, +{0x807e,0x12}, +{0x807f,0x0a}, +{0x8080,0xff}, +{0x8081,0xc2}, +{0x8082,0x37}, +{0x8083,0x22}, +{0x8084,0x78}, +{0x8085,0xb8}, +{0x8086,0xe6}, +{0x8087,0xd3}, +{0x8088,0x94}, +{0x8089,0x00}, +{0x808a,0x40}, +{0x808b,0x02}, +{0x808c,0x16}, +{0x808d,0x22}, +{0x808e,0xe5}, +{0x808f,0x1f}, +{0x8090,0xb4}, +{0x8091,0x05}, +{0x8092,0x23}, +{0x8093,0xe4}, +{0x8094,0xf5}, +{0x8095,0x1f}, +{0x8096,0xc2}, +{0x8097,0x01}, +{0x8098,0x78}, +{0x8099,0xb6}, +{0x809a,0xe6}, +{0x809b,0xfe}, +{0x809c,0x08}, +{0x809d,0xe6}, +{0x809e,0xff}, +{0x809f,0x78}, +{0x80a0,0x4e}, +{0x80a1,0xa6}, +{0x80a2,0x06}, +{0x80a3,0x08}, +{0x80a4,0xa6}, +{0x80a5,0x07}, +{0x80a6,0xa2}, +{0x80a7,0x37}, +{0x80a8,0xe4}, +{0x80a9,0x33}, +{0x80aa,0xf5}, +{0x80ab,0x3c}, +{0x80ac,0x90}, +{0x80ad,0x30}, +{0x80ae,0x28}, +{0x80af,0xf0}, +{0x80b0,0x75}, +{0x80b1,0x1e}, +{0x80b2,0x10}, +{0x80b3,0xd2}, +{0x80b4,0x35}, +{0x80b5,0x22}, +{0x80b6,0xe5}, +{0x80b7,0x4b}, +{0x80b8,0x75}, +{0x80b9,0xf0}, +{0x80ba,0x05}, +{0x80bb,0x84}, +{0x80bc,0x78}, +{0x80bd,0xbc}, +{0x80be,0xf6}, +{0x80bf,0x90}, +{0x80c0,0x0e}, +{0x80c1,0x8c}, +{0x80c2,0xe4}, +{0x80c3,0x93}, +{0x80c4,0xff}, +{0x80c5,0x25}, +{0x80c6,0xe0}, +{0x80c7,0x24}, +{0x80c8,0x0a}, +{0x80c9,0xf8}, +{0x80ca,0xe6}, +{0x80cb,0xfc}, +{0x80cc,0x08}, +{0x80cd,0xe6}, +{0x80ce,0xfd}, +{0x80cf,0x78}, +{0x80d0,0xbc}, +{0x80d1,0xe6}, +{0x80d2,0x25}, +{0x80d3,0xe0}, +{0x80d4,0x24}, +{0x80d5,0x4e}, +{0x80d6,0xf8}, +{0x80d7,0xa6}, +{0x80d8,0x04}, +{0x80d9,0x08}, +{0x80da,0xa6}, +{0x80db,0x05}, +{0x80dc,0xef}, +{0x80dd,0x12}, +{0x80de,0x0f}, +{0x80df,0x0b}, +{0x80e0,0xd3}, +{0x80e1,0x78}, +{0x80e2,0xb7}, +{0x80e3,0x96}, +{0x80e4,0xee}, +{0x80e5,0x18}, +{0x80e6,0x96}, +{0x80e7,0x40}, +{0x80e8,0x0d}, +{0x80e9,0x78}, +{0x80ea,0xbc}, +{0x80eb,0xe6}, +{0x80ec,0x78}, +{0x80ed,0xb9}, +{0x80ee,0xf6}, +{0x80ef,0x78}, +{0x80f0,0xb6}, +{0x80f1,0xa6}, +{0x80f2,0x06}, +{0x80f3,0x08}, +{0x80f4,0xa6}, +{0x80f5,0x07}, +{0x80f6,0x90}, +{0x80f7,0x0e}, +{0x80f8,0x8c}, +{0x80f9,0xe4}, +{0x80fa,0x93}, +{0x80fb,0x12}, +{0x80fc,0x0f}, +{0x80fd,0x0b}, +{0x80fe,0xc3}, +{0x80ff,0x78}, +{0x8100,0xc2}, +{0x8101,0x96}, +{0x8102,0xee}, +{0x8103,0x18}, +{0x8104,0x96}, +{0x8105,0x50}, +{0x8106,0x0d}, +{0x8107,0x78}, +{0x8108,0xbc}, +{0x8109,0xe6}, +{0x810a,0x78}, +{0x810b,0xba}, +{0x810c,0xf6}, +{0x810d,0x78}, +{0x810e,0xc1}, +{0x810f,0xa6}, +{0x8110,0x06}, +{0x8111,0x08}, +{0x8112,0xa6}, +{0x8113,0x07}, +{0x8114,0x78}, +{0x8115,0xb6}, +{0x8116,0xe6}, +{0x8117,0xfe}, +{0x8118,0x08}, +{0x8119,0xe6}, +{0x811a,0xc3}, +{0x811b,0x78}, +{0x811c,0xc2}, +{0x811d,0x96}, +{0x811e,0xff}, +{0x811f,0xee}, +{0x8120,0x18}, +{0x8121,0x96}, +{0x8122,0x78}, +{0x8123,0xc3}, +{0x8124,0xf6}, +{0x8125,0x08}, +{0x8126,0xa6}, +{0x8127,0x07}, +{0x8128,0x90}, +{0x8129,0x0e}, +{0x812a,0x95}, +{0x812b,0xe4}, +{0x812c,0x18}, +{0x812d,0x12}, +{0x812e,0x0e}, +{0x812f,0xe9}, +{0x8130,0x40}, +{0x8131,0x02}, +{0x8132,0xd2}, +{0x8133,0x37}, +{0x8134,0x78}, +{0x8135,0xbc}, +{0x8136,0xe6}, +{0x8137,0x08}, +{0x8138,0x26}, +{0x8139,0x08}, +{0x813a,0xf6}, +{0x813b,0xe5}, +{0x813c,0x1f}, +{0x813d,0x64}, +{0x813e,0x01}, +{0x813f,0x70}, +{0x8140,0x4a}, +{0x8141,0xe6}, +{0x8142,0xc3}, +{0x8143,0x78}, +{0x8144,0xc0}, +{0x8145,0x12}, +{0x8146,0x0e}, +{0x8147,0xdf}, +{0x8148,0x40}, +{0x8149,0x05}, +{0x814a,0x12}, +{0x814b,0x0e}, +{0x814c,0xda}, +{0x814d,0x40}, +{0x814e,0x39}, +{0x814f,0x12}, +{0x8150,0x0f}, +{0x8151,0x02}, +{0x8152,0x40}, +{0x8153,0x04}, +{0x8154,0x7f}, +{0x8155,0xfe}, +{0x8156,0x80}, +{0x8157,0x02}, +{0x8158,0x7f}, +{0x8159,0x02}, +{0x815a,0x78}, +{0x815b,0xbd}, +{0x815c,0xa6}, +{0x815d,0x07}, +{0x815e,0x78}, +{0x815f,0xb9}, +{0x8160,0xe6}, +{0x8161,0x24}, +{0x8162,0x03}, +{0x8163,0x78}, +{0x8164,0xbf}, +{0x8165,0xf6}, +{0x8166,0x78}, +{0x8167,0xb9}, +{0x8168,0xe6}, +{0x8169,0x24}, +{0x816a,0xfd}, +{0x816b,0x78}, +{0x816c,0xc0}, +{0x816d,0xf6}, +{0x816e,0x12}, +{0x816f,0x0f}, +{0x8170,0x02}, +{0x8171,0x40}, +{0x8172,0x06}, +{0x8173,0x78}, +{0x8174,0xc0}, +{0x8175,0xe6}, +{0x8176,0xff}, +{0x8177,0x80}, +{0x8178,0x04}, +{0x8179,0x78}, +{0x817a,0xbf}, +{0x817b,0xe6}, +{0x817c,0xff}, +{0x817d,0x78}, +{0x817e,0xbe}, +{0x817f,0xa6}, +{0x8180,0x07}, +{0x8181,0x75}, +{0x8182,0x1f}, +{0x8183,0x02}, +{0x8184,0x78}, +{0x8185,0xb8}, +{0x8186,0x76}, +{0x8187,0x01}, +{0x8188,0x02}, +{0x8189,0x02}, +{0x818a,0x4a}, +{0x818b,0xe5}, +{0x818c,0x1f}, +{0x818d,0x64}, +{0x818e,0x02}, +{0x818f,0x60}, +{0x8190,0x03}, +{0x8191,0x02}, +{0x8192,0x02}, +{0x8193,0x2a}, +{0x8194,0x78}, +{0x8195,0xbe}, +{0x8196,0xe6}, +{0x8197,0xff}, +{0x8198,0xc3}, +{0x8199,0x78}, +{0x819a,0xc0}, +{0x819b,0x12}, +{0x819c,0x0e}, +{0x819d,0xe0}, +{0x819e,0x40}, +{0x819f,0x08}, +{0x81a0,0x12}, +{0x81a1,0x0e}, +{0x81a2,0xda}, +{0x81a3,0x50}, +{0x81a4,0x03}, +{0x81a5,0x02}, +{0x81a6,0x02}, +{0x81a7,0x28}, +{0x81a8,0x12}, +{0x81a9,0x0f}, +{0x81aa,0x02}, +{0x81ab,0x40}, +{0x81ac,0x04}, +{0x81ad,0x7f}, +{0x81ae,0xff}, +{0x81af,0x80}, +{0x81b0,0x02}, +{0x81b1,0x7f}, +{0x81b2,0x01}, +{0x81b3,0x78}, +{0x81b4,0xbd}, +{0x81b5,0xa6}, +{0x81b6,0x07}, +{0x81b7,0x78}, +{0x81b8,0xb9}, +{0x81b9,0xe6}, +{0x81ba,0x04}, +{0x81bb,0x78}, +{0x81bc,0xbf}, +{0x81bd,0xf6}, +{0x81be,0x78}, +{0x81bf,0xb9}, +{0x81c0,0xe6}, +{0x81c1,0x14}, +{0x81c2,0x78}, +{0x81c3,0xc0}, +{0x81c4,0xf6}, +{0x81c5,0x18}, +{0x81c6,0x12}, +{0x81c7,0x0f}, +{0x81c8,0x04}, +{0x81c9,0x40}, +{0x81ca,0x04}, +{0x81cb,0xe6}, +{0x81cc,0xff}, +{0x81cd,0x80}, +{0x81ce,0x02}, +{0x81cf,0x7f}, +{0x81d0,0x00}, +{0x81d1,0x78}, +{0x81d2,0xbf}, +{0x81d3,0xa6}, +{0x81d4,0x07}, +{0x81d5,0xd3}, +{0x81d6,0x08}, +{0x81d7,0xe6}, +{0x81d8,0x64}, +{0x81d9,0x80}, +{0x81da,0x94}, +{0x81db,0x80}, +{0x81dc,0x40}, +{0x81dd,0x04}, +{0x81de,0xe6}, +{0x81df,0xff}, +{0x81e0,0x80}, +{0x81e1,0x02}, +{0x81e2,0x7f}, +{0x81e3,0x00}, +{0x81e4,0x78}, +{0x81e5,0xc0}, +{0x81e6,0xa6}, +{0x81e7,0x07}, +{0x81e8,0xc3}, +{0x81e9,0x18}, +{0x81ea,0xe6}, +{0x81eb,0x64}, +{0x81ec,0x80}, +{0x81ed,0x94}, +{0x81ee,0xb3}, +{0x81ef,0x50}, +{0x81f0,0x04}, +{0x81f1,0xe6}, +{0x81f2,0xff}, +{0x81f3,0x80}, +{0x81f4,0x02}, +{0x81f5,0x7f}, +{0x81f6,0x33}, +{0x81f7,0x78}, +{0x81f8,0xbf}, +{0x81f9,0xa6}, +{0x81fa,0x07}, +{0x81fb,0xc3}, +{0x81fc,0x08}, +{0x81fd,0xe6}, +{0x81fe,0x64}, +{0x81ff,0x80}, +{0x8200,0x94}, +{0x8201,0xb3}, +{0x8202,0x50}, +{0x8203,0x04}, +{0x8204,0xe6}, +{0x8205,0xff}, +{0x8206,0x80}, +{0x8207,0x02}, +{0x8208,0x7f}, +{0x8209,0x33}, +{0x820a,0x78}, +{0x820b,0xc0}, +{0x820c,0xa6}, +{0x820d,0x07}, +{0x820e,0x12}, +{0x820f,0x0f}, +{0x8210,0x02}, +{0x8211,0x40}, +{0x8212,0x06}, +{0x8213,0x78}, +{0x8214,0xc0}, +{0x8215,0xe6}, +{0x8216,0xff}, +{0x8217,0x80}, +{0x8218,0x04}, +{0x8219,0x78}, +{0x821a,0xbf}, +{0x821b,0xe6}, +{0x821c,0xff}, +{0x821d,0x78}, +{0x821e,0xbe}, +{0x821f,0xa6}, +{0x8220,0x07}, +{0x8221,0x75}, +{0x8222,0x1f}, +{0x8223,0x03}, +{0x8224,0x78}, +{0x8225,0xb8}, +{0x8226,0x76}, +{0x8227,0x01}, +{0x8228,0x80}, +{0x8229,0x20}, +{0x822a,0xe5}, +{0x822b,0x1f}, +{0x822c,0x64}, +{0x822d,0x03}, +{0x822e,0x70}, +{0x822f,0x26}, +{0x8230,0x78}, +{0x8231,0xbe}, +{0x8232,0xe6}, +{0x8233,0xff}, +{0x8234,0xc3}, +{0x8235,0x78}, +{0x8236,0xc0}, +{0x8237,0x12}, +{0x8238,0x0e}, +{0x8239,0xe0}, +{0x823a,0x40}, +{0x823b,0x05}, +{0x823c,0x12}, +{0x823d,0x0e}, +{0x823e,0xda}, +{0x823f,0x40}, +{0x8240,0x09}, +{0x8241,0x78}, +{0x8242,0xb9}, +{0x8243,0xe6}, +{0x8244,0x78}, +{0x8245,0xbe}, +{0x8246,0xf6}, +{0x8247,0x75}, +{0x8248,0x1f}, +{0x8249,0x04}, +{0x824a,0x78}, +{0x824b,0xbe}, +{0x824c,0xe6}, +{0x824d,0x75}, +{0x824e,0xf0}, +{0x824f,0x05}, +{0x8250,0xa4}, +{0x8251,0xf5}, +{0x8252,0x4b}, +{0x8253,0x02}, +{0x8254,0x0a}, +{0x8255,0xff}, +{0x8256,0xe5}, +{0x8257,0x1f}, +{0x8258,0xb4}, +{0x8259,0x04}, +{0x825a,0x10}, +{0x825b,0x90}, +{0x825c,0x0e}, +{0x825d,0x94}, +{0x825e,0xe4}, +{0x825f,0x78}, +{0x8260,0xc3}, +{0x8261,0x12}, +{0x8262,0x0e}, +{0x8263,0xe9}, +{0x8264,0x40}, +{0x8265,0x02}, +{0x8266,0xd2}, +{0x8267,0x37}, +{0x8268,0x75}, +{0x8269,0x1f}, +{0x826a,0x05}, +{0x826b,0x22}, +{0x826c,0x30}, +{0x826d,0x01}, +{0x826e,0x03}, +{0x826f,0x02}, +{0x8270,0x04}, +{0x8271,0xc0}, +{0x8272,0x30}, +{0x8273,0x02}, +{0x8274,0x03}, +{0x8275,0x02}, +{0x8276,0x04}, +{0x8277,0xc0}, +{0x8278,0x90}, +{0x8279,0x51}, +{0x827a,0xa5}, +{0x827b,0xe0}, +{0x827c,0x78}, +{0x827d,0x93}, +{0x827e,0xf6}, +{0x827f,0xa3}, +{0x8280,0xe0}, +{0x8281,0x08}, +{0x8282,0xf6}, +{0x8283,0xa3}, +{0x8284,0xe0}, +{0x8285,0x08}, +{0x8286,0xf6}, +{0x8287,0xe5}, +{0x8288,0x1f}, +{0x8289,0x70}, +{0x828a,0x3c}, +{0x828b,0x75}, +{0x828c,0x1e}, +{0x828d,0x20}, +{0x828e,0xd2}, +{0x828f,0x35}, +{0x8290,0x12}, +{0x8291,0x0c}, +{0x8292,0x7a}, +{0x8293,0x78}, +{0x8294,0x7e}, +{0x8295,0xa6}, +{0x8296,0x06}, +{0x8297,0x08}, +{0x8298,0xa6}, +{0x8299,0x07}, +{0x829a,0x78}, +{0x829b,0x8b}, +{0x829c,0xa6}, +{0x829d,0x09}, +{0x829e,0x18}, +{0x829f,0x76}, +{0x82a0,0x01}, +{0x82a1,0x12}, +{0x82a2,0x0c}, +{0x82a3,0x5b}, +{0x82a4,0x78}, +{0x82a5,0x4e}, +{0x82a6,0xa6}, +{0x82a7,0x06}, +{0x82a8,0x08}, +{0x82a9,0xa6}, +{0x82aa,0x07}, +{0x82ab,0x78}, +{0x82ac,0x8b}, +{0x82ad,0xe6}, +{0x82ae,0x78}, +{0x82af,0x6e}, +{0x82b0,0xf6}, +{0x82b1,0x75}, +{0x82b2,0x1f}, +{0x82b3,0x01}, +{0x82b4,0x78}, +{0x82b5,0x93}, +{0x82b6,0xe6}, +{0x82b7,0x78}, +{0x82b8,0x90}, +{0x82b9,0xf6}, +{0x82ba,0x78}, +{0x82bb,0x94}, +{0x82bc,0xe6}, +{0x82bd,0x78}, +{0x82be,0x91}, +{0x82bf,0xf6}, +{0x82c0,0x78}, +{0x82c1,0x95}, +{0x82c2,0xe6}, +{0x82c3,0x78}, +{0x82c4,0x92}, +{0x82c5,0xf6}, +{0x82c6,0x22}, +{0x82c7,0x79}, +{0x82c8,0x90}, +{0x82c9,0xe7}, +{0x82ca,0xd3}, +{0x82cb,0x78}, +{0x82cc,0x93}, +{0x82cd,0x96}, +{0x82ce,0x40}, +{0x82cf,0x05}, +{0x82d0,0xe7}, +{0x82d1,0x96}, +{0x82d2,0xff}, +{0x82d3,0x80}, +{0x82d4,0x08}, +{0x82d5,0xc3}, +{0x82d6,0x79}, +{0x82d7,0x93}, +{0x82d8,0xe7}, +{0x82d9,0x78}, +{0x82da,0x90}, +{0x82db,0x96}, +{0x82dc,0xff}, +{0x82dd,0x78}, +{0x82de,0x88}, +{0x82df,0x76}, +{0x82e0,0x00}, +{0x82e1,0x08}, +{0x82e2,0xa6}, +{0x82e3,0x07}, +{0x82e4,0x79}, +{0x82e5,0x91}, +{0x82e6,0xe7}, +{0x82e7,0xd3}, +{0x82e8,0x78}, +{0x82e9,0x94}, +{0x82ea,0x96}, +{0x82eb,0x40}, +{0x82ec,0x05}, +{0x82ed,0xe7}, +{0x82ee,0x96}, +{0x82ef,0xff}, +{0x82f0,0x80}, +{0x82f1,0x08}, +{0x82f2,0xc3}, +{0x82f3,0x79}, +{0x82f4,0x94}, +{0x82f5,0xe7}, +{0x82f6,0x78}, +{0x82f7,0x91}, +{0x82f8,0x96}, +{0x82f9,0xff}, +{0x82fa,0x12}, +{0x82fb,0x0c}, +{0x82fc,0x8e}, +{0x82fd,0x79}, +{0x82fe,0x92}, +{0x82ff,0xe7}, +{0x8300,0xd3}, +{0x8301,0x78}, +{0x8302,0x95}, +{0x8303,0x96}, +{0x8304,0x40}, +{0x8305,0x05}, +{0x8306,0xe7}, +{0x8307,0x96}, +{0x8308,0xff}, +{0x8309,0x80}, +{0x830a,0x08}, +{0x830b,0xc3}, +{0x830c,0x79}, +{0x830d,0x95}, +{0x830e,0xe7}, +{0x830f,0x78}, +{0x8310,0x92}, +{0x8311,0x96}, +{0x8312,0xff}, +{0x8313,0x12}, +{0x8314,0x0c}, +{0x8315,0x8e}, +{0x8316,0x12}, +{0x8317,0x0c}, +{0x8318,0x5b}, +{0x8319,0x78}, +{0x831a,0x8a}, +{0x831b,0xe6}, +{0x831c,0x25}, +{0x831d,0xe0}, +{0x831e,0x24}, +{0x831f,0x4e}, +{0x8320,0xf8}, +{0x8321,0xa6}, +{0x8322,0x06}, +{0x8323,0x08}, +{0x8324,0xa6}, +{0x8325,0x07}, +{0x8326,0x78}, +{0x8327,0x8a}, +{0x8328,0xe6}, +{0x8329,0x24}, +{0x832a,0x6e}, +{0x832b,0xf8}, +{0x832c,0xa6}, +{0x832d,0x09}, +{0x832e,0x78}, +{0x832f,0x8a}, +{0x8330,0xe6}, +{0x8331,0x24}, +{0x8332,0x01}, +{0x8333,0xff}, +{0x8334,0xe4}, +{0x8335,0x33}, +{0x8336,0xfe}, +{0x8337,0xd3}, +{0x8338,0xef}, +{0x8339,0x94}, +{0x833a,0x0f}, +{0x833b,0xee}, +{0x833c,0x64}, +{0x833d,0x80}, +{0x833e,0x94}, +{0x833f,0x80}, +{0x8340,0x40}, +{0x8341,0x04}, +{0x8342,0x7f}, +{0x8343,0x00}, +{0x8344,0x80}, +{0x8345,0x05}, +{0x8346,0x78}, +{0x8347,0x8a}, +{0x8348,0xe6}, +{0x8349,0x04}, +{0x834a,0xff}, +{0x834b,0x78}, +{0x834c,0x8a}, +{0x834d,0xa6}, +{0x834e,0x07}, +{0x834f,0xe5}, +{0x8350,0x1f}, +{0x8351,0xb4}, +{0x8352,0x01}, +{0x8353,0x0a}, +{0x8354,0xe6}, +{0x8355,0x60}, +{0x8356,0x03}, +{0x8357,0x02}, +{0x8358,0x04}, +{0x8359,0xc0}, +{0x835a,0x75}, +{0x835b,0x1f}, +{0x835c,0x02}, +{0x835d,0x22}, +{0x835e,0x12}, +{0x835f,0x0c}, +{0x8360,0x7a}, +{0x8361,0x78}, +{0x8362,0x80}, +{0x8363,0xa6}, +{0x8364,0x06}, +{0x8365,0x08}, +{0x8366,0xa6}, +{0x8367,0x07}, +{0x8368,0x12}, +{0x8369,0x0c}, +{0x836a,0x7a}, +{0x836b,0x78}, +{0x836c,0x82}, +{0x836d,0xa6}, +{0x836e,0x06}, +{0x836f,0x08}, +{0x8370,0xa6}, +{0x8371,0x07}, +{0x8372,0x78}, +{0x8373,0x6e}, +{0x8374,0xe6}, +{0x8375,0x78}, +{0x8376,0x8c}, +{0x8377,0xf6}, +{0x8378,0x78}, +{0x8379,0x6e}, +{0x837a,0xe6}, +{0x837b,0x78}, +{0x837c,0x8d}, +{0x837d,0xf6}, +{0x837e,0x7f}, +{0x837f,0x01}, +{0x8380,0xef}, +{0x8381,0x25}, +{0x8382,0xe0}, +{0x8383,0x24}, +{0x8384,0x4f}, +{0x8385,0xf9}, +{0x8386,0xc3}, +{0x8387,0x78}, +{0x8388,0x81}, +{0x8389,0xe6}, +{0x838a,0x97}, +{0x838b,0x18}, +{0x838c,0xe6}, +{0x838d,0x19}, +{0x838e,0x97}, +{0x838f,0x50}, +{0x8390,0x0a}, +{0x8391,0x12}, +{0x8392,0x0c}, +{0x8393,0x82}, +{0x8394,0x78}, +{0x8395,0x80}, +{0x8396,0xa6}, +{0x8397,0x04}, +{0x8398,0x08}, +{0x8399,0xa6}, +{0x839a,0x05}, +{0x839b,0x74}, +{0x839c,0x6e}, +{0x839d,0x2f}, +{0x839e,0xf9}, +{0x839f,0x78}, +{0x83a0,0x8c}, +{0x83a1,0xe6}, +{0x83a2,0xc3}, +{0x83a3,0x97}, +{0x83a4,0x50}, +{0x83a5,0x08}, +{0x83a6,0x74}, +{0x83a7,0x6e}, +{0x83a8,0x2f}, +{0x83a9,0xf8}, +{0x83aa,0xe6}, +{0x83ab,0x78}, +{0x83ac,0x8c}, +{0x83ad,0xf6}, +{0x83ae,0xef}, +{0x83af,0x25}, +{0x83b0,0xe0}, +{0x83b1,0x24}, +{0x83b2,0x4f}, +{0x83b3,0xf9}, +{0x83b4,0xd3}, +{0x83b5,0x78}, +{0x83b6,0x83}, +{0x83b7,0xe6}, +{0x83b8,0x97}, +{0x83b9,0x18}, +{0x83ba,0xe6}, +{0x83bb,0x19}, +{0x83bc,0x97}, +{0x83bd,0x40}, +{0x83be,0x0a}, +{0x83bf,0x12}, +{0x83c0,0x0c}, +{0x83c1,0x82}, +{0x83c2,0x78}, +{0x83c3,0x82}, +{0x83c4,0xa6}, +{0x83c5,0x04}, +{0x83c6,0x08}, +{0x83c7,0xa6}, +{0x83c8,0x05}, +{0x83c9,0x74}, +{0x83ca,0x6e}, +{0x83cb,0x2f}, +{0x83cc,0xf9}, +{0x83cd,0x78}, +{0x83ce,0x8d}, +{0x83cf,0xe6}, +{0x83d0,0xd3}, +{0x83d1,0x97}, +{0x83d2,0x40}, +{0x83d3,0x08}, +{0x83d4,0x74}, +{0x83d5,0x6e}, +{0x83d6,0x2f}, +{0x83d7,0xf8}, +{0x83d8,0xe6}, +{0x83d9,0x78}, +{0x83da,0x8d}, +{0x83db,0xf6}, +{0x83dc,0x0f}, +{0x83dd,0xef}, +{0x83de,0x64}, +{0x83df,0x10}, +{0x83e0,0x70}, +{0x83e1,0x9e}, +{0x83e2,0xc3}, +{0x83e3,0x79}, +{0x83e4,0x81}, +{0x83e5,0xe7}, +{0x83e6,0x78}, +{0x83e7,0x83}, +{0x83e8,0x96}, +{0x83e9,0xff}, +{0x83ea,0x19}, +{0x83eb,0xe7}, +{0x83ec,0x18}, +{0x83ed,0x96}, +{0x83ee,0x78}, +{0x83ef,0x84}, +{0x83f0,0xf6}, +{0x83f1,0x08}, +{0x83f2,0xa6}, +{0x83f3,0x07}, +{0x83f4,0xc3}, +{0x83f5,0x79}, +{0x83f6,0x8c}, +{0x83f7,0xe7}, +{0x83f8,0x78}, +{0x83f9,0x8d}, +{0x83fa,0x96}, +{0x83fb,0x08}, +{0x83fc,0xf6}, +{0x83fd,0xd3}, +{0x83fe,0x79}, +{0x83ff,0x81}, +{0x8400,0xe7}, +{0x8401,0x78}, +{0x8402,0x7f}, +{0x8403,0x96}, +{0x8404,0x19}, +{0x8405,0xe7}, +{0x8406,0x18}, +{0x8407,0x96}, +{0x8408,0x40}, +{0x8409,0x05}, +{0x840a,0x09}, +{0x840b,0xe7}, +{0x840c,0x08}, +{0x840d,0x80}, +{0x840e,0x06}, +{0x840f,0xc3}, +{0x8410,0x79}, +{0x8411,0x7f}, +{0x8412,0xe7}, +{0x8413,0x78}, +{0x8414,0x81}, +{0x8415,0x96}, +{0x8416,0xff}, +{0x8417,0x19}, +{0x8418,0xe7}, +{0x8419,0x18}, +{0x841a,0x96}, +{0x841b,0xfe}, +{0x841c,0x78}, +{0x841d,0x86}, +{0x841e,0xa6}, +{0x841f,0x06}, +{0x8420,0x08}, +{0x8421,0xa6}, +{0x8422,0x07}, +{0x8423,0x79}, +{0x8424,0x8c}, +{0x8425,0xe7}, +{0x8426,0xd3}, +{0x8427,0x78}, +{0x8428,0x8b}, +{0x8429,0x96}, +{0x842a,0x40}, +{0x842b,0x05}, +{0x842c,0xe7}, +{0x842d,0x96}, +{0x842e,0xff}, +{0x842f,0x80}, +{0x8430,0x08}, +{0x8431,0xc3}, +{0x8432,0x79}, +{0x8433,0x8b}, +{0x8434,0xe7}, +{0x8435,0x78}, +{0x8436,0x8c}, +{0x8437,0x96}, +{0x8438,0xff}, +{0x8439,0x78}, +{0x843a,0x8f}, +{0x843b,0xa6}, +{0x843c,0x07}, +{0x843d,0xe5}, +{0x843e,0x1f}, +{0x843f,0x64}, +{0x8440,0x02}, +{0x8441,0x70}, +{0x8442,0x69}, +{0x8443,0x90}, +{0x8444,0x0e}, +{0x8445,0x91}, +{0x8446,0x93}, +{0x8447,0xff}, +{0x8448,0x18}, +{0x8449,0xe6}, +{0x844a,0xc3}, +{0x844b,0x9f}, +{0x844c,0x50}, +{0x844d,0x72}, +{0x844e,0x12}, +{0x844f,0x0c}, +{0x8450,0x4a}, +{0x8451,0x12}, +{0x8452,0x0c}, +{0x8453,0x2f}, +{0x8454,0x90}, +{0x8455,0x0e}, +{0x8456,0x8e}, +{0x8457,0x12}, +{0x8458,0x0c}, +{0x8459,0x38}, +{0x845a,0x78}, +{0x845b,0x80}, +{0x845c,0x12}, +{0x845d,0x0c}, +{0x845e,0x6b}, +{0x845f,0x7b}, +{0x8460,0x04}, +{0x8461,0x12}, +{0x8462,0x0c}, +{0x8463,0x1d}, +{0x8464,0xc3}, +{0x8465,0x12}, +{0x8466,0x06}, +{0x8467,0x45}, +{0x8468,0x50}, +{0x8469,0x56}, +{0x846a,0x90}, +{0x846b,0x0e}, +{0x846c,0x92}, +{0x846d,0xe4}, +{0x846e,0x93}, +{0x846f,0xff}, +{0x8470,0x78}, +{0x8471,0x8f}, +{0x8472,0xe6}, +{0x8473,0x9f}, +{0x8474,0x40}, +{0x8475,0x02}, +{0x8476,0x80}, +{0x8477,0x11}, +{0x8478,0x90}, +{0x8479,0x0e}, +{0x847a,0x90}, +{0x847b,0xe4}, +{0x847c,0x93}, +{0x847d,0xff}, +{0x847e,0xd3}, +{0x847f,0x78}, +{0x8480,0x89}, +{0x8481,0xe6}, +{0x8482,0x9f}, +{0x8483,0x18}, +{0x8484,0xe6}, +{0x8485,0x94}, +{0x8486,0x00}, +{0x8487,0x40}, +{0x8488,0x03}, +{0x8489,0x75}, +{0x848a,0x1f}, +{0x848b,0x05}, +{0x848c,0x12}, +{0x848d,0x0c}, +{0x848e,0x4a}, +{0x848f,0x12}, +{0x8490,0x0c}, +{0x8491,0x2f}, +{0x8492,0x90}, +{0x8493,0x0e}, +{0x8494,0x8f}, +{0x8495,0x12}, +{0x8496,0x0c}, +{0x8497,0x38}, +{0x8498,0x78}, +{0x8499,0x7e}, +{0x849a,0x12}, +{0x849b,0x0c}, +{0x849c,0x6b}, +{0x849d,0x7b}, +{0x849e,0x40}, +{0x849f,0x12}, +{0x84a0,0x0c}, +{0x84a1,0x1d}, +{0x84a2,0xd3}, +{0x84a3,0x12}, +{0x84a4,0x06}, +{0x84a5,0x45}, +{0x84a6,0x40}, +{0x84a7,0x18}, +{0x84a8,0x75}, +{0x84a9,0x1f}, +{0x84aa,0x05}, +{0x84ab,0x22}, +{0x84ac,0xe5}, +{0x84ad,0x1f}, +{0x84ae,0xb4}, +{0x84af,0x05}, +{0x84b0,0x0f}, +{0x84b1,0xd2}, +{0x84b2,0x01}, +{0x84b3,0xc2}, +{0x84b4,0x02}, +{0x84b5,0xe4}, +{0x84b6,0xf5}, +{0x84b7,0x1f}, +{0x84b8,0xf5}, +{0x84b9,0x1e}, +{0x84ba,0xd2}, +{0x84bb,0x35}, +{0x84bc,0xd2}, +{0x84bd,0x33}, +{0x84be,0xd2}, +{0x84bf,0x36}, +{0x84c0,0x22}, +{0x84c1,0xef}, +{0x84c2,0x8d}, +{0x84c3,0xf0}, +{0x84c4,0xa4}, +{0x84c5,0xa8}, +{0x84c6,0xf0}, +{0x84c7,0xcf}, +{0x84c8,0x8c}, +{0x84c9,0xf0}, +{0x84ca,0xa4}, +{0x84cb,0x28}, +{0x84cc,0xce}, +{0x84cd,0x8d}, +{0x84ce,0xf0}, +{0x84cf,0xa4}, +{0x84d0,0x2e}, +{0x84d1,0xfe}, +{0x84d2,0x22}, +{0x84d3,0xbc}, +{0x84d4,0x00}, +{0x84d5,0x0b}, +{0x84d6,0xbe}, +{0x84d7,0x00}, +{0x84d8,0x29}, +{0x84d9,0xef}, +{0x84da,0x8d}, +{0x84db,0xf0}, +{0x84dc,0x84}, +{0x84dd,0xff}, +{0x84de,0xad}, +{0x84df,0xf0}, +{0x84e0,0x22}, +{0x84e1,0xe4}, +{0x84e2,0xcc}, +{0x84e3,0xf8}, +{0x84e4,0x75}, +{0x84e5,0xf0}, +{0x84e6,0x08}, +{0x84e7,0xef}, +{0x84e8,0x2f}, +{0x84e9,0xff}, +{0x84ea,0xee}, +{0x84eb,0x33}, +{0x84ec,0xfe}, +{0x84ed,0xec}, +{0x84ee,0x33}, +{0x84ef,0xfc}, +{0x84f0,0xee}, +{0x84f1,0x9d}, +{0x84f2,0xec}, +{0x84f3,0x98}, +{0x84f4,0x40}, +{0x84f5,0x05}, +{0x84f6,0xfc}, +{0x84f7,0xee}, +{0x84f8,0x9d}, +{0x84f9,0xfe}, +{0x84fa,0x0f}, +{0x84fb,0xd5}, +{0x84fc,0xf0}, +{0x84fd,0xe9}, +{0x84fe,0xe4}, +{0x84ff,0xce}, +{0x8500,0xfd}, +{0x8501,0x22}, +{0x8502,0xed}, +{0x8503,0xf8}, +{0x8504,0xf5}, +{0x8505,0xf0}, +{0x8506,0xee}, +{0x8507,0x84}, +{0x8508,0x20}, +{0x8509,0xd2}, +{0x850a,0x1c}, +{0x850b,0xfe}, +{0x850c,0xad}, +{0x850d,0xf0}, +{0x850e,0x75}, +{0x850f,0xf0}, +{0x8510,0x08}, +{0x8511,0xef}, +{0x8512,0x2f}, +{0x8513,0xff}, +{0x8514,0xed}, +{0x8515,0x33}, +{0x8516,0xfd}, +{0x8517,0x40}, +{0x8518,0x07}, +{0x8519,0x98}, +{0x851a,0x50}, +{0x851b,0x06}, +{0x851c,0xd5}, +{0x851d,0xf0}, +{0x851e,0xf2}, +{0x851f,0x22}, +{0x8520,0xc3}, +{0x8521,0x98}, +{0x8522,0xfd}, +{0x8523,0x0f}, +{0x8524,0xd5}, +{0x8525,0xf0}, +{0x8526,0xea}, +{0x8527,0x22}, +{0x8528,0xe8}, +{0x8529,0x8f}, +{0x852a,0xf0}, +{0x852b,0xa4}, +{0x852c,0xcc}, +{0x852d,0x8b}, +{0x852e,0xf0}, +{0x852f,0xa4}, +{0x8530,0x2c}, +{0x8531,0xfc}, +{0x8532,0xe9}, +{0x8533,0x8e}, +{0x8534,0xf0}, +{0x8535,0xa4}, +{0x8536,0x2c}, +{0x8537,0xfc}, +{0x8538,0x8a}, +{0x8539,0xf0}, +{0x853a,0xed}, +{0x853b,0xa4}, +{0x853c,0x2c}, +{0x853d,0xfc}, +{0x853e,0xea}, +{0x853f,0x8e}, +{0x8540,0xf0}, +{0x8541,0xa4}, +{0x8542,0xcd}, +{0x8543,0xa8}, +{0x8544,0xf0}, +{0x8545,0x8b}, +{0x8546,0xf0}, +{0x8547,0xa4}, +{0x8548,0x2d}, +{0x8549,0xcc}, +{0x854a,0x38}, +{0x854b,0x25}, +{0x854c,0xf0}, +{0x854d,0xfd}, +{0x854e,0xe9}, +{0x854f,0x8f}, +{0x8550,0xf0}, +{0x8551,0xa4}, +{0x8552,0x2c}, +{0x8553,0xcd}, +{0x8554,0x35}, +{0x8555,0xf0}, +{0x8556,0xfc}, +{0x8557,0xeb}, +{0x8558,0x8e}, +{0x8559,0xf0}, +{0x855a,0xa4}, +{0x855b,0xfe}, +{0x855c,0xa9}, +{0x855d,0xf0}, +{0x855e,0xeb}, +{0x855f,0x8f}, +{0x8560,0xf0}, +{0x8561,0xa4}, +{0x8562,0xcf}, +{0x8563,0xc5}, +{0x8564,0xf0}, +{0x8565,0x2e}, +{0x8566,0xcd}, +{0x8567,0x39}, +{0x8568,0xfe}, +{0x8569,0xe4}, +{0x856a,0x3c}, +{0x856b,0xfc}, +{0x856c,0xea}, +{0x856d,0xa4}, +{0x856e,0x2d}, +{0x856f,0xce}, +{0x8570,0x35}, +{0x8571,0xf0}, +{0x8572,0xfd}, +{0x8573,0xe4}, +{0x8574,0x3c}, +{0x8575,0xfc}, +{0x8576,0x22}, +{0x8577,0x75}, +{0x8578,0xf0}, +{0x8579,0x08}, +{0x857a,0x75}, +{0x857b,0x82}, +{0x857c,0x00}, +{0x857d,0xef}, +{0x857e,0x2f}, +{0x857f,0xff}, +{0x8580,0xee}, +{0x8581,0x33}, +{0x8582,0xfe}, +{0x8583,0xcd}, +{0x8584,0x33}, +{0x8585,0xcd}, +{0x8586,0xcc}, +{0x8587,0x33}, +{0x8588,0xcc}, +{0x8589,0xc5}, +{0x858a,0x82}, +{0x858b,0x33}, +{0x858c,0xc5}, +{0x858d,0x82}, +{0x858e,0x9b}, +{0x858f,0xed}, +{0x8590,0x9a}, +{0x8591,0xec}, +{0x8592,0x99}, +{0x8593,0xe5}, +{0x8594,0x82}, +{0x8595,0x98}, +{0x8596,0x40}, +{0x8597,0x0c}, +{0x8598,0xf5}, +{0x8599,0x82}, +{0x859a,0xee}, +{0x859b,0x9b}, +{0x859c,0xfe}, +{0x859d,0xed}, +{0x859e,0x9a}, +{0x859f,0xfd}, +{0x85a0,0xec}, +{0x85a1,0x99}, +{0x85a2,0xfc}, +{0x85a3,0x0f}, +{0x85a4,0xd5}, +{0x85a5,0xf0}, +{0x85a6,0xd6}, +{0x85a7,0xe4}, +{0x85a8,0xce}, +{0x85a9,0xfb}, +{0x85aa,0xe4}, +{0x85ab,0xcd}, +{0x85ac,0xfa}, +{0x85ad,0xe4}, +{0x85ae,0xcc}, +{0x85af,0xf9}, +{0x85b0,0xa8}, +{0x85b1,0x82}, +{0x85b2,0x22}, +{0x85b3,0xb8}, +{0x85b4,0x00}, +{0x85b5,0xc1}, +{0x85b6,0xb9}, +{0x85b7,0x00}, +{0x85b8,0x59}, +{0x85b9,0xba}, +{0x85ba,0x00}, +{0x85bb,0x2d}, +{0x85bc,0xec}, +{0x85bd,0x8b}, +{0x85be,0xf0}, +{0x85bf,0x84}, +{0x85c0,0xcf}, +{0x85c1,0xce}, +{0x85c2,0xcd}, +{0x85c3,0xfc}, +{0x85c4,0xe5}, +{0x85c5,0xf0}, +{0x85c6,0xcb}, +{0x85c7,0xf9}, +{0x85c8,0x78}, +{0x85c9,0x18}, +{0x85ca,0xef}, +{0x85cb,0x2f}, +{0x85cc,0xff}, +{0x85cd,0xee}, +{0x85ce,0x33}, +{0x85cf,0xfe}, +{0x85d0,0xed}, +{0x85d1,0x33}, +{0x85d2,0xfd}, +{0x85d3,0xec}, +{0x85d4,0x33}, +{0x85d5,0xfc}, +{0x85d6,0xeb}, +{0x85d7,0x33}, +{0x85d8,0xfb}, +{0x85d9,0x10}, +{0x85da,0xd7}, +{0x85db,0x03}, +{0x85dc,0x99}, +{0x85dd,0x40}, +{0x85de,0x04}, +{0x85df,0xeb}, +{0x85e0,0x99}, +{0x85e1,0xfb}, +{0x85e2,0x0f}, +{0x85e3,0xd8}, +{0x85e4,0xe5}, +{0x85e5,0xe4}, +{0x85e6,0xf9}, +{0x85e7,0xfa}, +{0x85e8,0x22}, +{0x85e9,0x78}, +{0x85ea,0x18}, +{0x85eb,0xef}, +{0x85ec,0x2f}, +{0x85ed,0xff}, +{0x85ee,0xee}, +{0x85ef,0x33}, +{0x85f0,0xfe}, +{0x85f1,0xed}, +{0x85f2,0x33}, +{0x85f3,0xfd}, +{0x85f4,0xec}, +{0x85f5,0x33}, +{0x85f6,0xfc}, +{0x85f7,0xc9}, +{0x85f8,0x33}, +{0x85f9,0xc9}, +{0x85fa,0x10}, +{0x85fb,0xd7}, +{0x85fc,0x05}, +{0x85fd,0x9b}, +{0x85fe,0xe9}, +{0x85ff,0x9a}, +{0x8600,0x40}, +{0x8601,0x07}, +{0x8602,0xec}, +{0x8603,0x9b}, +{0x8604,0xfc}, +{0x8605,0xe9}, +{0x8606,0x9a}, +{0x8607,0xf9}, +{0x8608,0x0f}, +{0x8609,0xd8}, +{0x860a,0xe0}, +{0x860b,0xe4}, +{0x860c,0xc9}, +{0x860d,0xfa}, +{0x860e,0xe4}, +{0x860f,0xcc}, +{0x8610,0xfb}, +{0x8611,0x22}, +{0x8612,0x75}, +{0x8613,0xf0}, +{0x8614,0x10}, +{0x8615,0xef}, +{0x8616,0x2f}, +{0x8617,0xff}, +{0x8618,0xee}, +{0x8619,0x33}, +{0x861a,0xfe}, +{0x861b,0xed}, +{0x861c,0x33}, +{0x861d,0xfd}, +{0x861e,0xcc}, +{0x861f,0x33}, +{0x8620,0xcc}, +{0x8621,0xc8}, +{0x8622,0x33}, +{0x8623,0xc8}, +{0x8624,0x10}, +{0x8625,0xd7}, +{0x8626,0x07}, +{0x8627,0x9b}, +{0x8628,0xec}, +{0x8629,0x9a}, +{0x862a,0xe8}, +{0x862b,0x99}, +{0x862c,0x40}, +{0x862d,0x0a}, +{0x862e,0xed}, +{0x862f,0x9b}, +{0x8630,0xfd}, +{0x8631,0xec}, +{0x8632,0x9a}, +{0x8633,0xfc}, +{0x8634,0xe8}, +{0x8635,0x99}, +{0x8636,0xf8}, +{0x8637,0x0f}, +{0x8638,0xd5}, +{0x8639,0xf0}, +{0x863a,0xda}, +{0x863b,0xe4}, +{0x863c,0xcd}, +{0x863d,0xfb}, +{0x863e,0xe4}, +{0x863f,0xcc}, +{0x8640,0xfa}, +{0x8641,0xe4}, +{0x8642,0xc8}, +{0x8643,0xf9}, +{0x8644,0x22}, +{0x8645,0xeb}, +{0x8646,0x9f}, +{0x8647,0xf5}, +{0x8648,0xf0}, +{0x8649,0xea}, +{0x864a,0x9e}, +{0x864b,0x42}, +{0x864c,0xf0}, +{0x864d,0xe9}, +{0x864e,0x9d}, +{0x864f,0x42}, +{0x8650,0xf0}, +{0x8651,0xe8}, +{0x8652,0x9c}, +{0x8653,0x45}, +{0x8654,0xf0}, +{0x8655,0x22}, +{0x8656,0xe8}, +{0x8657,0x60}, +{0x8658,0x0f}, +{0x8659,0xec}, +{0x865a,0xc3}, +{0x865b,0x13}, +{0x865c,0xfc}, +{0x865d,0xed}, +{0x865e,0x13}, +{0x865f,0xfd}, +{0x8660,0xee}, +{0x8661,0x13}, +{0x8662,0xfe}, +{0x8663,0xef}, +{0x8664,0x13}, +{0x8665,0xff}, +{0x8666,0xd8}, +{0x8667,0xf1}, +{0x8668,0x22}, +{0x8669,0xe8}, +{0x866a,0x60}, +{0x866b,0x0f}, +{0x866c,0xef}, +{0x866d,0xc3}, +{0x866e,0x33}, +{0x866f,0xff}, +{0x8670,0xee}, +{0x8671,0x33}, +{0x8672,0xfe}, +{0x8673,0xed}, +{0x8674,0x33}, +{0x8675,0xfd}, +{0x8676,0xec}, +{0x8677,0x33}, +{0x8678,0xfc}, +{0x8679,0xd8}, +{0x867a,0xf1}, +{0x867b,0x22}, +{0x867c,0xe4}, +{0x867d,0x93}, +{0x867e,0xfc}, +{0x867f,0x74}, +{0x8680,0x01}, +{0x8681,0x93}, +{0x8682,0xfd}, +{0x8683,0x74}, +{0x8684,0x02}, +{0x8685,0x93}, +{0x8686,0xfe}, +{0x8687,0x74}, +{0x8688,0x03}, +{0x8689,0x93}, +{0x868a,0xff}, +{0x868b,0x22}, +{0x868c,0xe6}, +{0x868d,0xfb}, +{0x868e,0x08}, +{0x868f,0xe6}, +{0x8690,0xf9}, +{0x8691,0x08}, +{0x8692,0xe6}, +{0x8693,0xfa}, +{0x8694,0x08}, +{0x8695,0xe6}, +{0x8696,0xcb}, +{0x8697,0xf8}, +{0x8698,0x22}, +{0x8699,0xec}, +{0x869a,0xf6}, +{0x869b,0x08}, +{0x869c,0xed}, +{0x869d,0xf6}, +{0x869e,0x08}, +{0x869f,0xee}, +{0x86a0,0xf6}, +{0x86a1,0x08}, +{0x86a2,0xef}, +{0x86a3,0xf6}, +{0x86a4,0x22}, +{0x86a5,0xa4}, +{0x86a6,0x25}, +{0x86a7,0x82}, +{0x86a8,0xf5}, +{0x86a9,0x82}, +{0x86aa,0xe5}, +{0x86ab,0xf0}, +{0x86ac,0x35}, +{0x86ad,0x83}, +{0x86ae,0xf5}, +{0x86af,0x83}, +{0x86b0,0x22}, +{0x86b1,0xd0}, +{0x86b2,0x83}, +{0x86b3,0xd0}, +{0x86b4,0x82}, +{0x86b5,0xf8}, +{0x86b6,0xe4}, +{0x86b7,0x93}, +{0x86b8,0x70}, +{0x86b9,0x12}, +{0x86ba,0x74}, +{0x86bb,0x01}, +{0x86bc,0x93}, +{0x86bd,0x70}, +{0x86be,0x0d}, +{0x86bf,0xa3}, +{0x86c0,0xa3}, +{0x86c1,0x93}, +{0x86c2,0xf8}, +{0x86c3,0x74}, +{0x86c4,0x01}, +{0x86c5,0x93}, +{0x86c6,0xf5}, +{0x86c7,0x82}, +{0x86c8,0x88}, +{0x86c9,0x83}, +{0x86ca,0xe4}, +{0x86cb,0x73}, +{0x86cc,0x74}, +{0x86cd,0x02}, +{0x86ce,0x93}, +{0x86cf,0x68}, +{0x86d0,0x60}, +{0x86d1,0xef}, +{0x86d2,0xa3}, +{0x86d3,0xa3}, +{0x86d4,0xa3}, +{0x86d5,0x80}, +{0x86d6,0xdf}, +{0x86d7,0x90}, +{0x86d8,0x38}, +{0x86d9,0x04}, +{0x86da,0x78}, +{0x86db,0x52}, +{0x86dc,0x12}, +{0x86dd,0x0b}, +{0x86de,0xfd}, +{0x86df,0x90}, +{0x86e0,0x38}, +{0x86e1,0x00}, +{0x86e2,0xe0}, +{0x86e3,0xfe}, +{0x86e4,0xa3}, +{0x86e5,0xe0}, +{0x86e6,0xfd}, +{0x86e7,0xed}, +{0x86e8,0xff}, +{0x86e9,0xc3}, +{0x86ea,0x12}, +{0x86eb,0x0b}, +{0x86ec,0x9e}, +{0x86ed,0x90}, +{0x86ee,0x38}, +{0x86ef,0x10}, +{0x86f0,0x12}, +{0x86f1,0x0b}, +{0x86f2,0x92}, +{0x86f3,0x90}, +{0x86f4,0x38}, +{0x86f5,0x06}, +{0x86f6,0x78}, +{0x86f7,0x54}, +{0x86f8,0x12}, +{0x86f9,0x0b}, +{0x86fa,0xfd}, +{0x86fb,0x90}, +{0x86fc,0x38}, +{0x86fd,0x02}, +{0x86fe,0xe0}, +{0x86ff,0xfe}, +{0x8700,0xa3}, +{0x8701,0xe0}, +{0x8702,0xfd}, +{0x8703,0xed}, +{0x8704,0xff}, +{0x8705,0xc3}, +{0x8706,0x12}, +{0x8707,0x0b}, +{0x8708,0x9e}, +{0x8709,0x90}, +{0x870a,0x38}, +{0x870b,0x12}, +{0x870c,0x12}, +{0x870d,0x0b}, +{0x870e,0x92}, +{0x870f,0xa3}, +{0x8710,0xe0}, +{0x8711,0xb4}, +{0x8712,0x31}, +{0x8713,0x07}, +{0x8714,0x78}, +{0x8715,0x52}, +{0x8716,0x79}, +{0x8717,0x52}, +{0x8718,0x12}, +{0x8719,0x0c}, +{0x871a,0x13}, +{0x871b,0x90}, +{0x871c,0x38}, +{0x871d,0x14}, +{0x871e,0xe0}, +{0x871f,0xb4}, +{0x8720,0x71}, +{0x8721,0x15}, +{0x8722,0x78}, +{0x8723,0x52}, +{0x8724,0xe6}, +{0x8725,0xfe}, +{0x8726,0x08}, +{0x8727,0xe6}, +{0x8728,0x78}, +{0x8729,0x02}, +{0x872a,0xce}, +{0x872b,0xc3}, +{0x872c,0x13}, +{0x872d,0xce}, +{0x872e,0x13}, +{0x872f,0xd8}, +{0x8730,0xf9}, +{0x8731,0x79}, +{0x8732,0x53}, +{0x8733,0xf7}, +{0x8734,0xee}, +{0x8735,0x19}, +{0x8736,0xf7}, +{0x8737,0x90}, +{0x8738,0x38}, +{0x8739,0x15}, +{0x873a,0xe0}, +{0x873b,0xb4}, +{0x873c,0x31}, +{0x873d,0x07}, +{0x873e,0x78}, +{0x873f,0x54}, +{0x8740,0x79}, +{0x8741,0x54}, +{0x8742,0x12}, +{0x8743,0x0c}, +{0x8744,0x13}, +{0x8745,0x90}, +{0x8746,0x38}, +{0x8747,0x15}, +{0x8748,0xe0}, +{0x8749,0xb4}, +{0x874a,0x71}, +{0x874b,0x15}, +{0x874c,0x78}, +{0x874d,0x54}, +{0x874e,0xe6}, +{0x874f,0xfe}, +{0x8750,0x08}, +{0x8751,0xe6}, +{0x8752,0x78}, +{0x8753,0x02}, +{0x8754,0xce}, +{0x8755,0xc3}, +{0x8756,0x13}, +{0x8757,0xce}, +{0x8758,0x13}, +{0x8759,0xd8}, +{0x875a,0xf9}, +{0x875b,0x79}, +{0x875c,0x55}, +{0x875d,0xf7}, +{0x875e,0xee}, +{0x875f,0x19}, +{0x8760,0xf7}, +{0x8761,0x79}, +{0x8762,0x52}, +{0x8763,0x12}, +{0x8764,0x0b}, +{0x8765,0xd9}, +{0x8766,0x09}, +{0x8767,0x12}, +{0x8768,0x0b}, +{0x8769,0xd9}, +{0x876a,0xaf}, +{0x876b,0x47}, +{0x876c,0x12}, +{0x876d,0x0b}, +{0x876e,0xb2}, +{0x876f,0xe5}, +{0x8770,0x44}, +{0x8771,0xfb}, +{0x8772,0x7a}, +{0x8773,0x00}, +{0x8774,0xfd}, +{0x8775,0x7c}, +{0x8776,0x00}, +{0x8777,0x12}, +{0x8778,0x04}, +{0x8779,0xd3}, +{0x877a,0x78}, +{0x877b,0x5a}, +{0x877c,0xa6}, +{0x877d,0x06}, +{0x877e,0x08}, +{0x877f,0xa6}, +{0x8780,0x07}, +{0x8781,0xaf}, +{0x8782,0x45}, +{0x8783,0x12}, +{0x8784,0x0b}, +{0x8785,0xb2}, +{0x8786,0xad}, +{0x8787,0x03}, +{0x8788,0x7c}, +{0x8789,0x00}, +{0x878a,0x12}, +{0x878b,0x04}, +{0x878c,0xd3}, +{0x878d,0x78}, +{0x878e,0x56}, +{0x878f,0xa6}, +{0x8790,0x06}, +{0x8791,0x08}, +{0x8792,0xa6}, +{0x8793,0x07}, +{0x8794,0xaf}, +{0x8795,0x48}, +{0x8796,0x78}, +{0x8797,0x54}, +{0x8798,0x12}, +{0x8799,0x0b}, +{0x879a,0xb4}, +{0x879b,0xe5}, +{0x879c,0x43}, +{0x879d,0xfb}, +{0x879e,0xfd}, +{0x879f,0x7c}, +{0x87a0,0x00}, +{0x87a1,0x12}, +{0x87a2,0x04}, +{0x87a3,0xd3}, +{0x87a4,0x78}, +{0x87a5,0x5c}, +{0x87a6,0xa6}, +{0x87a7,0x06}, +{0x87a8,0x08}, +{0x87a9,0xa6}, +{0x87aa,0x07}, +{0x87ab,0xaf}, +{0x87ac,0x46}, +{0x87ad,0x7e}, +{0x87ae,0x00}, +{0x87af,0x78}, +{0x87b0,0x54}, +{0x87b1,0x12}, +{0x87b2,0x0b}, +{0x87b3,0xb6}, +{0x87b4,0xad}, +{0x87b5,0x03}, +{0x87b6,0x7c}, +{0x87b7,0x00}, +{0x87b8,0x12}, +{0x87b9,0x04}, +{0x87ba,0xd3}, +{0x87bb,0x78}, +{0x87bc,0x58}, +{0x87bd,0xa6}, +{0x87be,0x06}, +{0x87bf,0x08}, +{0x87c0,0xa6}, +{0x87c1,0x07}, +{0x87c2,0xc3}, +{0x87c3,0x78}, +{0x87c4,0x5b}, +{0x87c5,0xe6}, +{0x87c6,0x94}, +{0x87c7,0x08}, +{0x87c8,0x18}, +{0x87c9,0xe6}, +{0x87ca,0x94}, +{0x87cb,0x00}, +{0x87cc,0x50}, +{0x87cd,0x05}, +{0x87ce,0x76}, +{0x87cf,0x00}, +{0x87d0,0x08}, +{0x87d1,0x76}, +{0x87d2,0x08}, +{0x87d3,0xc3}, +{0x87d4,0x78}, +{0x87d5,0x5d}, +{0x87d6,0xe6}, +{0x87d7,0x94}, +{0x87d8,0x08}, +{0x87d9,0x18}, +{0x87da,0xe6}, +{0x87db,0x94}, +{0x87dc,0x00}, +{0x87dd,0x50}, +{0x87de,0x05}, +{0x87df,0x76}, +{0x87e0,0x00}, +{0x87e1,0x08}, +{0x87e2,0x76}, +{0x87e3,0x08}, +{0x87e4,0x78}, +{0x87e5,0x5a}, +{0x87e6,0x12}, +{0x87e7,0x0b}, +{0x87e8,0xc6}, +{0x87e9,0xff}, +{0x87ea,0xd3}, +{0x87eb,0x78}, +{0x87ec,0x57}, +{0x87ed,0xe6}, +{0x87ee,0x9f}, +{0x87ef,0x18}, +{0x87f0,0xe6}, +{0x87f1,0x9e}, +{0x87f2,0x40}, +{0x87f3,0x0e}, +{0x87f4,0x78}, +{0x87f5,0x5a}, +{0x87f6,0xe6}, +{0x87f7,0x13}, +{0x87f8,0xfe}, +{0x87f9,0x08}, +{0x87fa,0xe6}, +{0x87fb,0x78}, +{0x87fc,0x57}, +{0x87fd,0x12}, +{0x87fe,0x0c}, +{0x87ff,0x08}, +{0x8800,0x80}, +{0x8801,0x04}, +{0x8802,0x7e}, +{0x8803,0x00}, +{0x8804,0x7f}, +{0x8805,0x00}, +{0x8806,0x78}, +{0x8807,0x5e}, +{0x8808,0x12}, +{0x8809,0x0b}, +{0x880a,0xbe}, +{0x880b,0xff}, +{0x880c,0xd3}, +{0x880d,0x78}, +{0x880e,0x59}, +{0x880f,0xe6}, +{0x8810,0x9f}, +{0x8811,0x18}, +{0x8812,0xe6}, +{0x8813,0x9e}, +{0x8814,0x40}, +{0x8815,0x0e}, +{0x8816,0x78}, +{0x8817,0x5c}, +{0x8818,0xe6}, +{0x8819,0x13}, +{0x881a,0xfe}, +{0x881b,0x08}, +{0x881c,0xe6}, +{0x881d,0x78}, +{0x881e,0x59}, +{0x881f,0x12}, +{0x8820,0x0c}, +{0x8821,0x08}, +{0x8822,0x80}, +{0x8823,0x04}, +{0x8824,0x7e}, +{0x8825,0x00}, +{0x8826,0x7f}, +{0x8827,0x00}, +{0x8828,0xe4}, +{0x8829,0xfc}, +{0x882a,0xfd}, +{0x882b,0x78}, +{0x882c,0x62}, +{0x882d,0x12}, +{0x882e,0x06}, +{0x882f,0x99}, +{0x8830,0x78}, +{0x8831,0x5a}, +{0x8832,0x12}, +{0x8833,0x0b}, +{0x8834,0xc6}, +{0x8835,0x78}, +{0x8836,0x57}, +{0x8837,0x26}, +{0x8838,0xff}, +{0x8839,0xee}, +{0x883a,0x18}, +{0x883b,0x36}, +{0x883c,0xfe}, +{0x883d,0x78}, +{0x883e,0x66}, +{0x883f,0x12}, +{0x8840,0x0b}, +{0x8841,0xbe}, +{0x8842,0x78}, +{0x8843,0x59}, +{0x8844,0x26}, +{0x8845,0xff}, +{0x8846,0xee}, +{0x8847,0x18}, +{0x8848,0x36}, +{0x8849,0xfe}, +{0x884a,0xe4}, +{0x884b,0xfc}, +{0x884c,0xfd}, +{0x884d,0x78}, +{0x884e,0x6a}, +{0x884f,0x12}, +{0x8850,0x06}, +{0x8851,0x99}, +{0x8852,0x12}, +{0x8853,0x0b}, +{0x8854,0xce}, +{0x8855,0x78}, +{0x8856,0x66}, +{0x8857,0x12}, +{0x8858,0x06}, +{0x8859,0x8c}, +{0x885a,0xd3}, +{0x885b,0x12}, +{0x885c,0x06}, +{0x885d,0x45}, +{0x885e,0x40}, +{0x885f,0x08}, +{0x8860,0x12}, +{0x8861,0x0b}, +{0x8862,0xce}, +{0x8863,0x78}, +{0x8864,0x66}, +{0x8865,0x12}, +{0x8866,0x06}, +{0x8867,0x99}, +{0x8868,0x78}, +{0x8869,0x54}, +{0x886a,0x12}, +{0x886b,0x0b}, +{0x886c,0xd0}, +{0x886d,0x78}, +{0x886e,0x6a}, +{0x886f,0x12}, +{0x8870,0x06}, +{0x8871,0x8c}, +{0x8872,0xd3}, +{0x8873,0x12}, +{0x8874,0x06}, +{0x8875,0x45}, +{0x8876,0x40}, +{0x8877,0x0a}, +{0x8878,0x78}, +{0x8879,0x54}, +{0x887a,0x12}, +{0x887b,0x0b}, +{0x887c,0xd0}, +{0x887d,0x78}, +{0x887e,0x6a}, +{0x887f,0x12}, +{0x8880,0x06}, +{0x8881,0x99}, +{0x8882,0x78}, +{0x8883,0x61}, +{0x8884,0xe6}, +{0x8885,0x90}, +{0x8886,0x60}, +{0x8887,0x01}, +{0x8888,0xf0}, +{0x8889,0x78}, +{0x888a,0x65}, +{0x888b,0xe6}, +{0x888c,0xa3}, +{0x888d,0xf0}, +{0x888e,0x78}, +{0x888f,0x69}, +{0x8890,0xe6}, +{0x8891,0xa3}, +{0x8892,0xf0}, +{0x8893,0x78}, +{0x8894,0x55}, +{0x8895,0xe6}, +{0x8896,0xa3}, +{0x8897,0xf0}, +{0x8898,0x7d}, +{0x8899,0x01}, +{0x889a,0x78}, +{0x889b,0x61}, +{0x889c,0x12}, +{0x889d,0x0b}, +{0x889e,0xe9}, +{0x889f,0x24}, +{0x88a0,0x01}, +{0x88a1,0x12}, +{0x88a2,0x0b}, +{0x88a3,0xa6}, +{0x88a4,0x78}, +{0x88a5,0x65}, +{0x88a6,0x12}, +{0x88a7,0x0b}, +{0x88a8,0xe9}, +{0x88a9,0x24}, +{0x88aa,0x02}, +{0x88ab,0x12}, +{0x88ac,0x0b}, +{0x88ad,0xa6}, +{0x88ae,0x78}, +{0x88af,0x69}, +{0x88b0,0x12}, +{0x88b1,0x0b}, +{0x88b2,0xe9}, +{0x88b3,0x24}, +{0x88b4,0x03}, +{0x88b5,0x12}, +{0x88b6,0x0b}, +{0x88b7,0xa6}, +{0x88b8,0x78}, +{0x88b9,0x6d}, +{0x88ba,0x12}, +{0x88bb,0x0b}, +{0x88bc,0xe9}, +{0x88bd,0x24}, +{0x88be,0x04}, +{0x88bf,0x12}, +{0x88c0,0x0b}, +{0x88c1,0xa6}, +{0x88c2,0x0d}, +{0x88c3,0xbd}, +{0x88c4,0x05}, +{0x88c5,0xd4}, +{0x88c6,0xc2}, +{0x88c7,0x0e}, +{0x88c8,0xc2}, +{0x88c9,0x06}, +{0x88ca,0x22}, +{0x88cb,0x85}, +{0x88cc,0x08}, +{0x88cd,0x41}, +{0x88ce,0x90}, +{0x88cf,0x30}, +{0x88d0,0x24}, +{0x88d1,0xe0}, +{0x88d2,0xf5}, +{0x88d3,0x3d}, +{0x88d4,0xa3}, +{0x88d5,0xe0}, +{0x88d6,0xf5}, +{0x88d7,0x3e}, +{0x88d8,0xa3}, +{0x88d9,0xe0}, +{0x88da,0xf5}, +{0x88db,0x3f}, +{0x88dc,0xa3}, +{0x88dd,0xe0}, +{0x88de,0xf5}, +{0x88df,0x40}, +{0x88e0,0xa3}, +{0x88e1,0xe0}, +{0x88e2,0xf5}, +{0x88e3,0x3c}, +{0x88e4,0xd2}, +{0x88e5,0x34}, +{0x88e6,0xe5}, +{0x88e7,0x41}, +{0x88e8,0x12}, +{0x88e9,0x06}, +{0x88ea,0xb1}, +{0x88eb,0x09}, +{0x88ec,0x31}, +{0x88ed,0x03}, +{0x88ee,0x09}, +{0x88ef,0x35}, +{0x88f0,0x04}, +{0x88f1,0x09}, +{0x88f2,0x3b}, +{0x88f3,0x05}, +{0x88f4,0x09}, +{0x88f5,0x3e}, +{0x88f6,0x06}, +{0x88f7,0x09}, +{0x88f8,0x41}, +{0x88f9,0x07}, +{0x88fa,0x09}, +{0x88fb,0x4a}, +{0x88fc,0x08}, +{0x88fd,0x09}, +{0x88fe,0x5b}, +{0x88ff,0x12}, +{0x8900,0x09}, +{0x8901,0x73}, +{0x8902,0x18}, +{0x8903,0x09}, +{0x8904,0x89}, +{0x8905,0x19}, +{0x8906,0x09}, +{0x8907,0x5e}, +{0x8908,0x1a}, +{0x8909,0x09}, +{0x890a,0x6a}, +{0x890b,0x1b}, +{0x890c,0x09}, +{0x890d,0xad}, +{0x890e,0x80}, +{0x890f,0x09}, +{0x8910,0xb2}, +{0x8911,0x81}, +{0x8912,0x0a}, +{0x8913,0x1d}, +{0x8914,0x8f}, +{0x8915,0x0a}, +{0x8916,0x09}, +{0x8917,0x90}, +{0x8918,0x0a}, +{0x8919,0x1d}, +{0x891a,0x91}, +{0x891b,0x0a}, +{0x891c,0x1d}, +{0x891d,0x92}, +{0x891e,0x0a}, +{0x891f,0x1d}, +{0x8920,0x93}, +{0x8921,0x0a}, +{0x8922,0x1d}, +{0x8923,0x94}, +{0x8924,0x0a}, +{0x8925,0x1d}, +{0x8926,0x98}, +{0x8927,0x0a}, +{0x8928,0x17}, +{0x8929,0x9f}, +{0x892a,0x0a}, +{0x892b,0x1a}, +{0x892c,0xec}, +{0x892d,0x00}, +{0x892e,0x00}, +{0x892f,0x0a}, +{0x8930,0x38}, +{0x8931,0x12}, +{0x8932,0x0f}, +{0x8933,0x74}, +{0x8934,0x22}, +{0x8935,0x12}, +{0x8936,0x0f}, +{0x8937,0x74}, +{0x8938,0xd2}, +{0x8939,0x03}, +{0x893a,0x22}, +{0x893b,0xd2}, +{0x893c,0x03}, +{0x893d,0x22}, +{0x893e,0xc2}, +{0x893f,0x03}, +{0x8940,0x22}, +{0x8941,0xa2}, +{0x8942,0x37}, +{0x8943,0xe4}, +{0x8944,0x33}, +{0x8945,0xf5}, +{0x8946,0x3c}, +{0x8947,0x02}, +{0x8948,0x0a}, +{0x8949,0x1d}, +{0x894a,0xc2}, +{0x894b,0x01}, +{0x894c,0xc2}, +{0x894d,0x02}, +{0x894e,0xc2}, +{0x894f,0x03}, +{0x8950,0x12}, +{0x8951,0x0d}, +{0x8952,0x0d}, +{0x8953,0x75}, +{0x8954,0x1e}, +{0x8955,0x70}, +{0x8956,0xd2}, +{0x8957,0x35}, +{0x8958,0x02}, +{0x8959,0x0a}, +{0x895a,0x1d}, +{0x895b,0x02}, +{0x895c,0x0a}, +{0x895d,0x04}, +{0x895e,0x85}, +{0x895f,0x40}, +{0x8960,0x4a}, +{0x8961,0x85}, +{0x8962,0x3c}, +{0x8963,0x4b}, +{0x8964,0x12}, +{0x8965,0x0a}, +{0x8966,0xff}, +{0x8967,0x02}, +{0x8968,0x0a}, +{0x8969,0x1d}, +{0x896a,0x85}, +{0x896b,0x4a}, +{0x896c,0x40}, +{0x896d,0x85}, +{0x896e,0x4b}, +{0x896f,0x3c}, +{0x8970,0x02}, +{0x8971,0x0a}, +{0x8972,0x1d}, +{0x8973,0xe4}, +{0x8974,0xf5}, +{0x8975,0x22}, +{0x8976,0xf5}, +{0x8977,0x23}, +{0x8978,0x85}, +{0x8979,0x40}, +{0x897a,0x31}, +{0x897b,0x85}, +{0x897c,0x3f}, +{0x897d,0x30}, +{0x897e,0x85}, +{0x897f,0x3e}, +{0x8980,0x2f}, +{0x8981,0x85}, +{0x8982,0x3d}, +{0x8983,0x2e}, +{0x8984,0x12}, +{0x8985,0x0f}, +{0x8986,0x46}, +{0x8987,0x80}, +{0x8988,0x1f}, +{0x8989,0x75}, +{0x898a,0x22}, +{0x898b,0x00}, +{0x898c,0x75}, +{0x898d,0x23}, +{0x898e,0x01}, +{0x898f,0x74}, +{0x8990,0xff}, +{0x8991,0xf5}, +{0x8992,0x2d}, +{0x8993,0xf5}, +{0x8994,0x2c}, +{0x8995,0xf5}, +{0x8996,0x2b}, +{0x8997,0xf5}, +{0x8998,0x2a}, +{0x8999,0x12}, +{0x899a,0x0f}, +{0x899b,0x46}, +{0x899c,0x85}, +{0x899d,0x2d}, +{0x899e,0x40}, +{0x899f,0x85}, +{0x89a0,0x2c}, +{0x89a1,0x3f}, +{0x89a2,0x85}, +{0x89a3,0x2b}, +{0x89a4,0x3e}, +{0x89a5,0x85}, +{0x89a6,0x2a}, +{0x89a7,0x3d}, +{0x89a8,0xe4}, +{0x89a9,0xf5}, +{0x89aa,0x3c}, +{0x89ab,0x80}, +{0x89ac,0x70}, +{0x89ad,0x12}, +{0x89ae,0x0f}, +{0x89af,0x16}, +{0x89b0,0x80}, +{0x89b1,0x6b}, +{0x89b2,0x85}, +{0x89b3,0x3d}, +{0x89b4,0x45}, +{0x89b5,0x85}, +{0x89b6,0x3e}, +{0x89b7,0x46}, +{0x89b8,0xe5}, +{0x89b9,0x47}, +{0x89ba,0xc3}, +{0x89bb,0x13}, +{0x89bc,0xff}, +{0x89bd,0xe5}, +{0x89be,0x45}, +{0x89bf,0xc3}, +{0x89c0,0x9f}, +{0x89c1,0x50}, +{0x89c2,0x02}, +{0x89c3,0x8f}, +{0x89c4,0x45}, +{0x89c5,0xe5}, +{0x89c6,0x48}, +{0x89c7,0xc3}, +{0x89c8,0x13}, +{0x89c9,0xff}, +{0x89ca,0xe5}, +{0x89cb,0x46}, +{0x89cc,0xc3}, +{0x89cd,0x9f}, +{0x89ce,0x50}, +{0x89cf,0x02}, +{0x89d0,0x8f}, +{0x89d1,0x46}, +{0x89d2,0xe5}, +{0x89d3,0x47}, +{0x89d4,0xc3}, +{0x89d5,0x13}, +{0x89d6,0xff}, +{0x89d7,0xfd}, +{0x89d8,0xe5}, +{0x89d9,0x45}, +{0x89da,0x2d}, +{0x89db,0xfd}, +{0x89dc,0xe4}, +{0x89dd,0x33}, +{0x89de,0xfc}, +{0x89df,0xe5}, +{0x89e0,0x44}, +{0x89e1,0x12}, +{0x89e2,0x0f}, +{0x89e3,0x90}, +{0x89e4,0x40}, +{0x89e5,0x05}, +{0x89e6,0xe5}, +{0x89e7,0x44}, +{0x89e8,0x9f}, +{0x89e9,0xf5}, +{0x89ea,0x45}, +{0x89eb,0xe5}, +{0x89ec,0x48}, +{0x89ed,0xc3}, +{0x89ee,0x13}, +{0x89ef,0xff}, +{0x89f0,0xfd}, +{0x89f1,0xe5}, +{0x89f2,0x46}, +{0x89f3,0x2d}, +{0x89f4,0xfd}, +{0x89f5,0xe4}, +{0x89f6,0x33}, +{0x89f7,0xfc}, +{0x89f8,0xe5}, +{0x89f9,0x43}, +{0x89fa,0x12}, +{0x89fb,0x0f}, +{0x89fc,0x90}, +{0x89fd,0x40}, +{0x89fe,0x05}, +{0x89ff,0xe5}, +{0x8a00,0x43}, +{0x8a01,0x9f}, +{0x8a02,0xf5}, +{0x8a03,0x46}, +{0x8a04,0x12}, +{0x8a05,0x06}, +{0x8a06,0xd7}, +{0x8a07,0x80}, +{0x8a08,0x14}, +{0x8a09,0x85}, +{0x8a0a,0x40}, +{0x8a0b,0x48}, +{0x8a0c,0x85}, +{0x8a0d,0x3f}, +{0x8a0e,0x47}, +{0x8a0f,0x85}, +{0x8a10,0x3e}, +{0x8a11,0x46}, +{0x8a12,0x85}, +{0x8a13,0x3d}, +{0x8a14,0x45}, +{0x8a15,0x80}, +{0x8a16,0x06}, +{0x8a17,0x02}, +{0x8a18,0x06}, +{0x8a19,0xd7}, +{0x8a1a,0x12}, +{0x8a1b,0x0d}, +{0x8a1c,0x7e}, +{0x8a1d,0x90}, +{0x8a1e,0x30}, +{0x8a1f,0x24}, +{0x8a20,0xe5}, +{0x8a21,0x3d}, +{0x8a22,0xf0}, +{0x8a23,0xa3}, +{0x8a24,0xe5}, +{0x8a25,0x3e}, +{0x8a26,0xf0}, +{0x8a27,0xa3}, +{0x8a28,0xe5}, +{0x8a29,0x3f}, +{0x8a2a,0xf0}, +{0x8a2b,0xa3}, +{0x8a2c,0xe5}, +{0x8a2d,0x40}, +{0x8a2e,0xf0}, +{0x8a2f,0xa3}, +{0x8a30,0xe5}, +{0x8a31,0x3c}, +{0x8a32,0xf0}, +{0x8a33,0x90}, +{0x8a34,0x30}, +{0x8a35,0x23}, +{0x8a36,0xe4}, +{0x8a37,0xf0}, +{0x8a38,0x22}, +{0x8a39,0xc0}, +{0x8a3a,0xe0}, +{0x8a3b,0xc0}, +{0x8a3c,0x83}, +{0x8a3d,0xc0}, +{0x8a3e,0x82}, +{0x8a3f,0xc0}, +{0x8a40,0xd0}, +{0x8a41,0x90}, +{0x8a42,0x3f}, +{0x8a43,0x0c}, +{0x8a44,0xe0}, +{0x8a45,0xf5}, +{0x8a46,0x32}, +{0x8a47,0xe5}, +{0x8a48,0x32}, +{0x8a49,0x30}, +{0x8a4a,0xe3}, +{0x8a4b,0x74}, +{0x8a4c,0x30}, +{0x8a4d,0x36}, +{0x8a4e,0x66}, +{0x8a4f,0x90}, +{0x8a50,0x60}, +{0x8a51,0x19}, +{0x8a52,0xe0}, +{0x8a53,0xf5}, +{0x8a54,0x0a}, +{0x8a55,0xa3}, +{0x8a56,0xe0}, +{0x8a57,0xf5}, +{0x8a58,0x0b}, +{0x8a59,0x90}, +{0x8a5a,0x60}, +{0x8a5b,0x1d}, +{0x8a5c,0xe0}, +{0x8a5d,0xf5}, +{0x8a5e,0x14}, +{0x8a5f,0xa3}, +{0x8a60,0xe0}, +{0x8a61,0xf5}, +{0x8a62,0x15}, +{0x8a63,0x90}, +{0x8a64,0x60}, +{0x8a65,0x21}, +{0x8a66,0xe0}, +{0x8a67,0xf5}, +{0x8a68,0x0c}, +{0x8a69,0xa3}, +{0x8a6a,0xe0}, +{0x8a6b,0xf5}, +{0x8a6c,0x0d}, +{0x8a6d,0x90}, +{0x8a6e,0x60}, +{0x8a6f,0x29}, +{0x8a70,0xe0}, +{0x8a71,0xf5}, +{0x8a72,0x0e}, +{0x8a73,0xa3}, +{0x8a74,0xe0}, +{0x8a75,0xf5}, +{0x8a76,0x0f}, +{0x8a77,0x90}, +{0x8a78,0x60}, +{0x8a79,0x31}, +{0x8a7a,0xe0}, +{0x8a7b,0xf5}, +{0x8a7c,0x10}, +{0x8a7d,0xa3}, +{0x8a7e,0xe0}, +{0x8a7f,0xf5}, +{0x8a80,0x11}, +{0x8a81,0x90}, +{0x8a82,0x60}, +{0x8a83,0x39}, +{0x8a84,0xe0}, +{0x8a85,0xf5}, +{0x8a86,0x12}, +{0x8a87,0xa3}, +{0x8a88,0xe0}, +{0x8a89,0xf5}, +{0x8a8a,0x13}, +{0x8a8b,0x30}, +{0x8a8c,0x01}, +{0x8a8d,0x06}, +{0x8a8e,0x30}, +{0x8a8f,0x33}, +{0x8a90,0x03}, +{0x8a91,0xd3}, +{0x8a92,0x80}, +{0x8a93,0x01}, +{0x8a94,0xc3}, +{0x8a95,0x92}, +{0x8a96,0x09}, +{0x8a97,0x30}, +{0x8a98,0x02}, +{0x8a99,0x06}, +{0x8a9a,0x30}, +{0x8a9b,0x33}, +{0x8a9c,0x03}, +{0x8a9d,0xd3}, +{0x8a9e,0x80}, +{0x8a9f,0x01}, +{0x8aa0,0xc3}, +{0x8aa1,0x92}, +{0x8aa2,0x0a}, +{0x8aa3,0x30}, +{0x8aa4,0x33}, +{0x8aa5,0x0c}, +{0x8aa6,0x30}, +{0x8aa7,0x03}, +{0x8aa8,0x09}, +{0x8aa9,0x20}, +{0x8aaa,0x02}, +{0x8aab,0x06}, +{0x8aac,0x20}, +{0x8aad,0x01}, +{0x8aae,0x03}, +{0x8aaf,0xd3}, +{0x8ab0,0x80}, +{0x8ab1,0x01}, +{0x8ab2,0xc3}, +{0x8ab3,0x92}, +{0x8ab4,0x0b}, +{0x8ab5,0x90}, +{0x8ab6,0x30}, +{0x8ab7,0x01}, +{0x8ab8,0xe0}, +{0x8ab9,0x44}, +{0x8aba,0x40}, +{0x8abb,0xf0}, +{0x8abc,0xe0}, +{0x8abd,0x54}, +{0x8abe,0xbf}, +{0x8abf,0xf0}, +{0x8ac0,0xe5}, +{0x8ac1,0x32}, +{0x8ac2,0x30}, +{0x8ac3,0xe1}, +{0x8ac4,0x14}, +{0x8ac5,0x30}, +{0x8ac6,0x34}, +{0x8ac7,0x11}, +{0x8ac8,0x90}, +{0x8ac9,0x30}, +{0x8aca,0x22}, +{0x8acb,0xe0}, +{0x8acc,0xf5}, +{0x8acd,0x08}, +{0x8ace,0xe4}, +{0x8acf,0xf0}, +{0x8ad0,0x30}, +{0x8ad1,0x00}, +{0x8ad2,0x03}, +{0x8ad3,0xd3}, +{0x8ad4,0x80}, +{0x8ad5,0x01}, +{0x8ad6,0xc3}, +{0x8ad7,0x92}, +{0x8ad8,0x08}, +{0x8ad9,0xe5}, +{0x8ada,0x32}, +{0x8adb,0x30}, +{0x8adc,0xe5}, +{0x8add,0x12}, +{0x8ade,0x90}, +{0x8adf,0x56}, +{0x8ae0,0xa1}, +{0x8ae1,0xe0}, +{0x8ae2,0xf5}, +{0x8ae3,0x09}, +{0x8ae4,0x30}, +{0x8ae5,0x31}, +{0x8ae6,0x09}, +{0x8ae7,0x30}, +{0x8ae8,0x05}, +{0x8ae9,0x03}, +{0x8aea,0xd3}, +{0x8aeb,0x80}, +{0x8aec,0x01}, +{0x8aed,0xc3}, +{0x8aee,0x92}, +{0x8aef,0x0d}, +{0x8af0,0x90}, +{0x8af1,0x3f}, +{0x8af2,0x0c}, +{0x8af3,0xe5}, +{0x8af4,0x32}, +{0x8af5,0xf0}, +{0x8af6,0xd0}, +{0x8af7,0xd0}, +{0x8af8,0xd0}, +{0x8af9,0x82}, +{0x8afa,0xd0}, +{0x8afb,0x83}, +{0x8afc,0xd0}, +{0x8afd,0xe0}, +{0x8afe,0x32}, +{0x8aff,0x90}, +{0x8b00,0x0e}, +{0x8b01,0x7e}, +{0x8b02,0xe4}, +{0x8b03,0x93}, +{0x8b04,0xfe}, +{0x8b05,0x74}, +{0x8b06,0x01}, +{0x8b07,0x93}, +{0x8b08,0xff}, +{0x8b09,0xc3}, +{0x8b0a,0x90}, +{0x8b0b,0x0e}, +{0x8b0c,0x7c}, +{0x8b0d,0x74}, +{0x8b0e,0x01}, +{0x8b0f,0x93}, +{0x8b10,0x9f}, +{0x8b11,0xff}, +{0x8b12,0xe4}, +{0x8b13,0x93}, +{0x8b14,0x9e}, +{0x8b15,0xfe}, +{0x8b16,0xe4}, +{0x8b17,0x8f}, +{0x8b18,0x3b}, +{0x8b19,0x8e}, +{0x8b1a,0x3a}, +{0x8b1b,0xf5}, +{0x8b1c,0x39}, +{0x8b1d,0xf5}, +{0x8b1e,0x38}, +{0x8b1f,0xab}, +{0x8b20,0x3b}, +{0x8b21,0xaa}, +{0x8b22,0x3a}, +{0x8b23,0xa9}, +{0x8b24,0x39}, +{0x8b25,0xa8}, +{0x8b26,0x38}, +{0x8b27,0xaf}, +{0x8b28,0x4b}, +{0x8b29,0xfc}, +{0x8b2a,0xfd}, +{0x8b2b,0xfe}, +{0x8b2c,0x12}, +{0x8b2d,0x05}, +{0x8b2e,0x28}, +{0x8b2f,0x12}, +{0x8b30,0x0d}, +{0x8b31,0xe1}, +{0x8b32,0xe4}, +{0x8b33,0x7b}, +{0x8b34,0xff}, +{0x8b35,0xfa}, +{0x8b36,0xf9}, +{0x8b37,0xf8}, +{0x8b38,0x12}, +{0x8b39,0x05}, +{0x8b3a,0xb3}, +{0x8b3b,0x12}, +{0x8b3c,0x0d}, +{0x8b3d,0xe1}, +{0x8b3e,0x90}, +{0x8b3f,0x0e}, +{0x8b40,0x69}, +{0x8b41,0xe4}, +{0x8b42,0x12}, +{0x8b43,0x0d}, +{0x8b44,0xf6}, +{0x8b45,0x12}, +{0x8b46,0x0d}, +{0x8b47,0xe1}, +{0x8b48,0xe4}, +{0x8b49,0x85}, +{0x8b4a,0x4a}, +{0x8b4b,0x37}, +{0x8b4c,0xf5}, +{0x8b4d,0x36}, +{0x8b4e,0xf5}, +{0x8b4f,0x35}, +{0x8b50,0xf5}, +{0x8b51,0x34}, +{0x8b52,0xaf}, +{0x8b53,0x37}, +{0x8b54,0xae}, +{0x8b55,0x36}, +{0x8b56,0xad}, +{0x8b57,0x35}, +{0x8b58,0xac}, +{0x8b59,0x34}, +{0x8b5a,0xa3}, +{0x8b5b,0x12}, +{0x8b5c,0x0d}, +{0x8b5d,0xf6}, +{0x8b5e,0x8f}, +{0x8b5f,0x37}, +{0x8b60,0x8e}, +{0x8b61,0x36}, +{0x8b62,0x8d}, +{0x8b63,0x35}, +{0x8b64,0x8c}, +{0x8b65,0x34}, +{0x8b66,0xe5}, +{0x8b67,0x3b}, +{0x8b68,0x45}, +{0x8b69,0x37}, +{0x8b6a,0xf5}, +{0x8b6b,0x3b}, +{0x8b6c,0xe5}, +{0x8b6d,0x3a}, +{0x8b6e,0x45}, +{0x8b6f,0x36}, +{0x8b70,0xf5}, +{0x8b71,0x3a}, +{0x8b72,0xe5}, +{0x8b73,0x39}, +{0x8b74,0x45}, +{0x8b75,0x35}, +{0x8b76,0xf5}, +{0x8b77,0x39}, +{0x8b78,0xe5}, +{0x8b79,0x38}, +{0x8b7a,0x45}, +{0x8b7b,0x34}, +{0x8b7c,0xf5}, +{0x8b7d,0x38}, +{0x8b7e,0xe4}, +{0x8b7f,0xf5}, +{0x8b80,0x22}, +{0x8b81,0xf5}, +{0x8b82,0x23}, +{0x8b83,0x85}, +{0x8b84,0x3b}, +{0x8b85,0x31}, +{0x8b86,0x85}, +{0x8b87,0x3a}, +{0x8b88,0x30}, +{0x8b89,0x85}, +{0x8b8a,0x39}, +{0x8b8b,0x2f}, +{0x8b8c,0x85}, +{0x8b8d,0x38}, +{0x8b8e,0x2e}, +{0x8b8f,0x02}, +{0x8b90,0x0f}, +{0x8b91,0x46}, +{0x8b92,0xe0}, +{0x8b93,0xa3}, +{0x8b94,0xe0}, +{0x8b95,0x75}, +{0x8b96,0xf0}, +{0x8b97,0x02}, +{0x8b98,0xa4}, +{0x8b99,0xff}, +{0x8b9a,0xae}, +{0x8b9b,0xf0}, +{0x8b9c,0xc3}, +{0x8b9d,0x08}, +{0x8b9e,0xe6}, +{0x8b9f,0x9f}, +{0x8ba0,0xf6}, +{0x8ba1,0x18}, +{0x8ba2,0xe6}, +{0x8ba3,0x9e}, +{0x8ba4,0xf6}, +{0x8ba5,0x22}, +{0x8ba6,0xff}, +{0x8ba7,0xe5}, +{0x8ba8,0xf0}, +{0x8ba9,0x34}, +{0x8baa,0x60}, +{0x8bab,0x8f}, +{0x8bac,0x82}, +{0x8bad,0xf5}, +{0x8bae,0x83}, +{0x8baf,0xec}, +{0x8bb0,0xf0}, +{0x8bb1,0x22}, +{0x8bb2,0x78}, +{0x8bb3,0x52}, +{0x8bb4,0x7e}, +{0x8bb5,0x00}, +{0x8bb6,0xe6}, +{0x8bb7,0xfc}, +{0x8bb8,0x08}, +{0x8bb9,0xe6}, +{0x8bba,0xfd}, +{0x8bbb,0x02}, +{0x8bbc,0x04}, +{0x8bbd,0xc1}, +{0x8bbe,0xe4}, +{0x8bbf,0xfc}, +{0x8bc0,0xfd}, +{0x8bc1,0x12}, +{0x8bc2,0x06}, +{0x8bc3,0x99}, +{0x8bc4,0x78}, +{0x8bc5,0x5c}, +{0x8bc6,0xe6}, +{0x8bc7,0xc3}, +{0x8bc8,0x13}, +{0x8bc9,0xfe}, +{0x8bca,0x08}, +{0x8bcb,0xe6}, +{0x8bcc,0x13}, +{0x8bcd,0x22}, +{0x8bce,0x78}, +{0x8bcf,0x52}, +{0x8bd0,0xe6}, +{0x8bd1,0xfe}, +{0x8bd2,0x08}, +{0x8bd3,0xe6}, +{0x8bd4,0xff}, +{0x8bd5,0xe4}, +{0x8bd6,0xfc}, +{0x8bd7,0xfd}, +{0x8bd8,0x22}, +{0x8bd9,0xe7}, +{0x8bda,0xc4}, +{0x8bdb,0xf8}, +{0x8bdc,0x54}, +{0x8bdd,0xf0}, +{0x8bde,0xc8}, +{0x8bdf,0x68}, +{0x8be0,0xf7}, +{0x8be1,0x09}, +{0x8be2,0xe7}, +{0x8be3,0xc4}, +{0x8be4,0x54}, +{0x8be5,0x0f}, +{0x8be6,0x48}, +{0x8be7,0xf7}, +{0x8be8,0x22}, +{0x8be9,0xe6}, +{0x8bea,0xfc}, +{0x8beb,0xed}, +{0x8bec,0x75}, +{0x8bed,0xf0}, +{0x8bee,0x04}, +{0x8bef,0xa4}, +{0x8bf0,0x22}, +{0x8bf1,0x12}, +{0x8bf2,0x06}, +{0x8bf3,0x7c}, +{0x8bf4,0x8f}, +{0x8bf5,0x48}, +{0x8bf6,0x8e}, +{0x8bf7,0x47}, +{0x8bf8,0x8d}, +{0x8bf9,0x46}, +{0x8bfa,0x8c}, +{0x8bfb,0x45}, +{0x8bfc,0x22}, +{0x8bfd,0xe0}, +{0x8bfe,0xfe}, +{0x8bff,0xa3}, +{0x8c00,0xe0}, +{0x8c01,0xfd}, +{0x8c02,0xee}, +{0x8c03,0xf6}, +{0x8c04,0xed}, +{0x8c05,0x08}, +{0x8c06,0xf6}, +{0x8c07,0x22}, +{0x8c08,0x13}, +{0x8c09,0xff}, +{0x8c0a,0xc3}, +{0x8c0b,0xe6}, +{0x8c0c,0x9f}, +{0x8c0d,0xff}, +{0x8c0e,0x18}, +{0x8c0f,0xe6}, +{0x8c10,0x9e}, +{0x8c11,0xfe}, +{0x8c12,0x22}, +{0x8c13,0xe6}, +{0x8c14,0xc3}, +{0x8c15,0x13}, +{0x8c16,0xf7}, +{0x8c17,0x08}, +{0x8c18,0xe6}, +{0x8c19,0x13}, +{0x8c1a,0x09}, +{0x8c1b,0xf7}, +{0x8c1c,0x22}, +{0x8c1d,0xad}, +{0x8c1e,0x39}, +{0x8c1f,0xac}, +{0x8c20,0x38}, +{0x8c21,0xfa}, +{0x8c22,0xf9}, +{0x8c23,0xf8}, +{0x8c24,0x12}, +{0x8c25,0x05}, +{0x8c26,0x28}, +{0x8c27,0x8f}, +{0x8c28,0x3b}, +{0x8c29,0x8e}, +{0x8c2a,0x3a}, +{0x8c2b,0x8d}, +{0x8c2c,0x39}, +{0x8c2d,0x8c}, +{0x8c2e,0x38}, +{0x8c2f,0xab}, +{0x8c30,0x37}, +{0x8c31,0xaa}, +{0x8c32,0x36}, +{0x8c33,0xa9}, +{0x8c34,0x35}, +{0x8c35,0xa8}, +{0x8c36,0x34}, +{0x8c37,0x22}, +{0x8c38,0x93}, +{0x8c39,0xff}, +{0x8c3a,0xe4}, +{0x8c3b,0xfc}, +{0x8c3c,0xfd}, +{0x8c3d,0xfe}, +{0x8c3e,0x12}, +{0x8c3f,0x05}, +{0x8c40,0x28}, +{0x8c41,0x8f}, +{0x8c42,0x37}, +{0x8c43,0x8e}, +{0x8c44,0x36}, +{0x8c45,0x8d}, +{0x8c46,0x35}, +{0x8c47,0x8c}, +{0x8c48,0x34}, +{0x8c49,0x22}, +{0x8c4a,0x78}, +{0x8c4b,0x84}, +{0x8c4c,0xe6}, +{0x8c4d,0xfe}, +{0x8c4e,0x08}, +{0x8c4f,0xe6}, +{0x8c50,0xff}, +{0x8c51,0xe4}, +{0x8c52,0x8f}, +{0x8c53,0x37}, +{0x8c54,0x8e}, +{0x8c55,0x36}, +{0x8c56,0xf5}, +{0x8c57,0x35}, +{0x8c58,0xf5}, +{0x8c59,0x34}, +{0x8c5a,0x22}, +{0x8c5b,0x90}, +{0x8c5c,0x0e}, +{0x8c5d,0x8c}, +{0x8c5e,0xe4}, +{0x8c5f,0x93}, +{0x8c60,0x25}, +{0x8c61,0xe0}, +{0x8c62,0x24}, +{0x8c63,0x0a}, +{0x8c64,0xf8}, +{0x8c65,0xe6}, +{0x8c66,0xfe}, +{0x8c67,0x08}, +{0x8c68,0xe6}, +{0x8c69,0xff}, +{0x8c6a,0x22}, +{0x8c6b,0xe6}, +{0x8c6c,0xfe}, +{0x8c6d,0x08}, +{0x8c6e,0xe6}, +{0x8c6f,0xff}, +{0x8c70,0xe4}, +{0x8c71,0x8f}, +{0x8c72,0x3b}, +{0x8c73,0x8e}, +{0x8c74,0x3a}, +{0x8c75,0xf5}, +{0x8c76,0x39}, +{0x8c77,0xf5}, +{0x8c78,0x38}, +{0x8c79,0x22}, +{0x8c7a,0x78}, +{0x8c7b,0x4e}, +{0x8c7c,0xe6}, +{0x8c7d,0xfe}, +{0x8c7e,0x08}, +{0x8c7f,0xe6}, +{0x8c80,0xff}, +{0x8c81,0x22}, +{0x8c82,0xef}, +{0x8c83,0x25}, +{0x8c84,0xe0}, +{0x8c85,0x24}, +{0x8c86,0x4e}, +{0x8c87,0xf8}, +{0x8c88,0xe6}, +{0x8c89,0xfc}, +{0x8c8a,0x08}, +{0x8c8b,0xe6}, +{0x8c8c,0xfd}, +{0x8c8d,0x22}, +{0x8c8e,0x78}, +{0x8c8f,0x89}, +{0x8c90,0xef}, +{0x8c91,0x26}, +{0x8c92,0xf6}, +{0x8c93,0x18}, +{0x8c94,0xe4}, +{0x8c95,0x36}, +{0x8c96,0xf6}, +{0x8c97,0x22}, +{0x8c98,0x75}, +{0x8c99,0x89}, +{0x8c9a,0x03}, +{0x8c9b,0x75}, +{0x8c9c,0xa8}, +{0x8c9d,0x01}, +{0x8c9e,0x75}, +{0x8c9f,0xb8}, +{0x8ca0,0x04}, +{0x8ca1,0x75}, +{0x8ca2,0x34}, +{0x8ca3,0xff}, +{0x8ca4,0x75}, +{0x8ca5,0x35}, +{0x8ca6,0x0e}, +{0x8ca7,0x75}, +{0x8ca8,0x36}, +{0x8ca9,0x15}, +{0x8caa,0x75}, +{0x8cab,0x37}, +{0x8cac,0x0d}, +{0x8cad,0x12}, +{0x8cae,0x0e}, +{0x8caf,0x9a}, +{0x8cb0,0x12}, +{0x8cb1,0x00}, +{0x8cb2,0x09}, +{0x8cb3,0x12}, +{0x8cb4,0x0f}, +{0x8cb5,0x16}, +{0x8cb6,0x12}, +{0x8cb7,0x00}, +{0x8cb8,0x06}, +{0x8cb9,0xd2}, +{0x8cba,0x00}, +{0x8cbb,0xd2}, +{0x8cbc,0x34}, +{0x8cbd,0xd2}, +{0x8cbe,0xaf}, +{0x8cbf,0x75}, +{0x8cc0,0x34}, +{0x8cc1,0xff}, +{0x8cc2,0x75}, +{0x8cc3,0x35}, +{0x8cc4,0x0e}, +{0x8cc5,0x75}, +{0x8cc6,0x36}, +{0x8cc7,0x49}, +{0x8cc8,0x75}, +{0x8cc9,0x37}, +{0x8cca,0x03}, +{0x8ccb,0x12}, +{0x8ccc,0x0e}, +{0x8ccd,0x9a}, +{0x8cce,0x30}, +{0x8ccf,0x08}, +{0x8cd0,0x09}, +{0x8cd1,0xc2}, +{0x8cd2,0x34}, +{0x8cd3,0x12}, +{0x8cd4,0x08}, +{0x8cd5,0xcb}, +{0x8cd6,0xc2}, +{0x8cd7,0x08}, +{0x8cd8,0xd2}, +{0x8cd9,0x34}, +{0x8cda,0x30}, +{0x8cdb,0x0b}, +{0x8cdc,0x09}, +{0x8cdd,0xc2}, +{0x8cde,0x36}, +{0x8cdf,0x12}, +{0x8ce0,0x02}, +{0x8ce1,0x6c}, +{0x8ce2,0xc2}, +{0x8ce3,0x0b}, +{0x8ce4,0xd2}, +{0x8ce5,0x36}, +{0x8ce6,0x30}, +{0x8ce7,0x09}, +{0x8ce8,0x09}, +{0x8ce9,0xc2}, +{0x8cea,0x36}, +{0x8ceb,0x12}, +{0x8cec,0x00}, +{0x8ced,0x0e}, +{0x8cee,0xc2}, +{0x8cef,0x09}, +{0x8cf0,0xd2}, +{0x8cf1,0x36}, +{0x8cf2,0x30}, +{0x8cf3,0x0e}, +{0x8cf4,0x03}, +{0x8cf5,0x12}, +{0x8cf6,0x06}, +{0x8cf7,0xd7}, +{0x8cf8,0x30}, +{0x8cf9,0x35}, +{0x8cfa,0xd3}, +{0x8cfb,0x90}, +{0x8cfc,0x30}, +{0x8cfd,0x29}, +{0x8cfe,0xe5}, +{0x8cff,0x1e}, +{0x8d00,0xf0}, +{0x8d01,0xb4}, +{0x8d02,0x10}, +{0x8d03,0x05}, +{0x8d04,0x90}, +{0x8d05,0x30}, +{0x8d06,0x23}, +{0x8d07,0xe4}, +{0x8d08,0xf0}, +{0x8d09,0xc2}, +{0x8d0a,0x35}, +{0x8d0b,0x80}, +{0x8d0c,0xc1}, +{0x8d0d,0xe4}, +{0x8d0e,0xf5}, +{0x8d0f,0x4b}, +{0x8d10,0x90}, +{0x8d11,0x0e}, +{0x8d12,0x7a}, +{0x8d13,0x93}, +{0x8d14,0xff}, +{0x8d15,0xe4}, +{0x8d16,0x8f}, +{0x8d17,0x37}, +{0x8d18,0xf5}, +{0x8d19,0x36}, +{0x8d1a,0xf5}, +{0x8d1b,0x35}, +{0x8d1c,0xf5}, +{0x8d1d,0x34}, +{0x8d1e,0xaf}, +{0x8d1f,0x37}, +{0x8d20,0xae}, +{0x8d21,0x36}, +{0x8d22,0xad}, +{0x8d23,0x35}, +{0x8d24,0xac}, +{0x8d25,0x34}, +{0x8d26,0x90}, +{0x8d27,0x0e}, +{0x8d28,0x6a}, +{0x8d29,0x12}, +{0x8d2a,0x0d}, +{0x8d2b,0xf6}, +{0x8d2c,0x8f}, +{0x8d2d,0x37}, +{0x8d2e,0x8e}, +{0x8d2f,0x36}, +{0x8d30,0x8d}, +{0x8d31,0x35}, +{0x8d32,0x8c}, +{0x8d33,0x34}, +{0x8d34,0x90}, +{0x8d35,0x0e}, +{0x8d36,0x72}, +{0x8d37,0x12}, +{0x8d38,0x06}, +{0x8d39,0x7c}, +{0x8d3a,0xef}, +{0x8d3b,0x45}, +{0x8d3c,0x37}, +{0x8d3d,0xf5}, +{0x8d3e,0x37}, +{0x8d3f,0xee}, +{0x8d40,0x45}, +{0x8d41,0x36}, +{0x8d42,0xf5}, +{0x8d43,0x36}, +{0x8d44,0xed}, +{0x8d45,0x45}, +{0x8d46,0x35}, +{0x8d47,0xf5}, +{0x8d48,0x35}, +{0x8d49,0xec}, +{0x8d4a,0x45}, +{0x8d4b,0x34}, +{0x8d4c,0xf5}, +{0x8d4d,0x34}, +{0x8d4e,0xe4}, +{0x8d4f,0xf5}, +{0x8d50,0x22}, +{0x8d51,0xf5}, +{0x8d52,0x23}, +{0x8d53,0x85}, +{0x8d54,0x37}, +{0x8d55,0x31}, +{0x8d56,0x85}, +{0x8d57,0x36}, +{0x8d58,0x30}, +{0x8d59,0x85}, +{0x8d5a,0x35}, +{0x8d5b,0x2f}, +{0x8d5c,0x85}, +{0x8d5d,0x34}, +{0x8d5e,0x2e}, +{0x8d5f,0x12}, +{0x8d60,0x0f}, +{0x8d61,0x46}, +{0x8d62,0xe4}, +{0x8d63,0xf5}, +{0x8d64,0x22}, +{0x8d65,0xf5}, +{0x8d66,0x23}, +{0x8d67,0x90}, +{0x8d68,0x0e}, +{0x8d69,0x72}, +{0x8d6a,0x12}, +{0x8d6b,0x0d}, +{0x8d6c,0xea}, +{0x8d6d,0x12}, +{0x8d6e,0x0f}, +{0x8d6f,0x46}, +{0x8d70,0xe4}, +{0x8d71,0xf5}, +{0x8d72,0x22}, +{0x8d73,0xf5}, +{0x8d74,0x23}, +{0x8d75,0x90}, +{0x8d76,0x0e}, +{0x8d77,0x6e}, +{0x8d78,0x12}, +{0x8d79,0x0d}, +{0x8d7a,0xea}, +{0x8d7b,0x02}, +{0x8d7c,0x0f}, +{0x8d7d,0x46}, +{0x8d7e,0xe5}, +{0x8d7f,0x40}, +{0x8d80,0x24}, +{0x8d81,0xf2}, +{0x8d82,0xf5}, +{0x8d83,0x37}, +{0x8d84,0xe5}, +{0x8d85,0x3f}, +{0x8d86,0x34}, +{0x8d87,0x43}, +{0x8d88,0xf5}, +{0x8d89,0x36}, +{0x8d8a,0xe5}, +{0x8d8b,0x3e}, +{0x8d8c,0x34}, +{0x8d8d,0xa2}, +{0x8d8e,0xf5}, +{0x8d8f,0x35}, +{0x8d90,0xe5}, +{0x8d91,0x3d}, +{0x8d92,0x34}, +{0x8d93,0x28}, +{0x8d94,0xf5}, +{0x8d95,0x34}, +{0x8d96,0xe5}, +{0x8d97,0x37}, +{0x8d98,0xff}, +{0x8d99,0xe4}, +{0x8d9a,0xfe}, +{0x8d9b,0xfd}, +{0x8d9c,0xfc}, +{0x8d9d,0x78}, +{0x8d9e,0x18}, +{0x8d9f,0x12}, +{0x8da0,0x06}, +{0x8da1,0x69}, +{0x8da2,0x8f}, +{0x8da3,0x40}, +{0x8da4,0x8e}, +{0x8da5,0x3f}, +{0x8da6,0x8d}, +{0x8da7,0x3e}, +{0x8da8,0x8c}, +{0x8da9,0x3d}, +{0x8daa,0xe5}, +{0x8dab,0x37}, +{0x8dac,0x54}, +{0x8dad,0xa0}, +{0x8dae,0xff}, +{0x8daf,0xe5}, +{0x8db0,0x36}, +{0x8db1,0xfe}, +{0x8db2,0xe4}, +{0x8db3,0xfd}, +{0x8db4,0xfc}, +{0x8db5,0x78}, +{0x8db6,0x07}, +{0x8db7,0x12}, +{0x8db8,0x06}, +{0x8db9,0x56}, +{0x8dba,0x78}, +{0x8dbb,0x10}, +{0x8dbc,0x12}, +{0x8dbd,0x0f}, +{0x8dbe,0x9a}, +{0x8dbf,0xe4}, +{0x8dc0,0xff}, +{0x8dc1,0xfe}, +{0x8dc2,0xe5}, +{0x8dc3,0x35}, +{0x8dc4,0xfd}, +{0x8dc5,0xe4}, +{0x8dc6,0xfc}, +{0x8dc7,0x78}, +{0x8dc8,0x0e}, +{0x8dc9,0x12}, +{0x8dca,0x06}, +{0x8dcb,0x56}, +{0x8dcc,0x12}, +{0x8dcd,0x0f}, +{0x8dce,0x9d}, +{0x8dcf,0xe4}, +{0x8dd0,0xff}, +{0x8dd1,0xfe}, +{0x8dd2,0xfd}, +{0x8dd3,0xe5}, +{0x8dd4,0x34}, +{0x8dd5,0xfc}, +{0x8dd6,0x78}, +{0x8dd7,0x18}, +{0x8dd8,0x12}, +{0x8dd9,0x06}, +{0x8dda,0x56}, +{0x8ddb,0x78}, +{0x8ddc,0x08}, +{0x8ddd,0x12}, +{0x8dde,0x0f}, +{0x8ddf,0x9a}, +{0x8de0,0x22}, +{0x8de1,0x8f}, +{0x8de2,0x3b}, +{0x8de3,0x8e}, +{0x8de4,0x3a}, +{0x8de5,0x8d}, +{0x8de6,0x39}, +{0x8de7,0x8c}, +{0x8de8,0x38}, +{0x8de9,0x22}, +{0x8dea,0x12}, +{0x8deb,0x06}, +{0x8dec,0x7c}, +{0x8ded,0x8f}, +{0x8dee,0x31}, +{0x8def,0x8e}, +{0x8df0,0x30}, +{0x8df1,0x8d}, +{0x8df2,0x2f}, +{0x8df3,0x8c}, +{0x8df4,0x2e}, +{0x8df5,0x22}, +{0x8df6,0x93}, +{0x8df7,0xf9}, +{0x8df8,0xf8}, +{0x8df9,0x02}, +{0x8dfa,0x06}, +{0x8dfb,0x69}, +{0x8dfc,0x00}, +{0x8dfd,0x00}, +{0x8dfe,0x00}, +{0x8dff,0x00}, +{0x8e00,0x12}, +{0x8e01,0x01}, +{0x8e02,0x17}, +{0x8e03,0x08}, +{0x8e04,0x31}, +{0x8e05,0x15}, +{0x8e06,0x53}, +{0x8e07,0x54}, +{0x8e08,0x44}, +{0x8e09,0x20}, +{0x8e0a,0x20}, +{0x8e0b,0x20}, +{0x8e0c,0x20}, +{0x8e0d,0x20}, +{0x8e0e,0x13}, +{0x8e0f,0x01}, +{0x8e10,0x10}, +{0x8e11,0x01}, +{0x8e12,0x56}, +{0x8e13,0x40}, +{0x8e14,0x1a}, +{0x8e15,0x30}, +{0x8e16,0x29}, +{0x8e17,0x7e}, +{0x8e18,0x00}, +{0x8e19,0x30}, +{0x8e1a,0x04}, +{0x8e1b,0x20}, +{0x8e1c,0xdf}, +{0x8e1d,0x30}, +{0x8e1e,0x05}, +{0x8e1f,0x40}, +{0x8e20,0xbf}, +{0x8e21,0x50}, +{0x8e22,0x03}, +{0x8e23,0x00}, +{0x8e24,0xfd}, +{0x8e25,0x50}, +{0x8e26,0x27}, +{0x8e27,0x01}, +{0x8e28,0xfe}, +{0x8e29,0x60}, +{0x8e2a,0x00}, +{0x8e2b,0x11}, +{0x8e2c,0x00}, +{0x8e2d,0x3f}, +{0x8e2e,0x05}, +{0x8e2f,0x30}, +{0x8e30,0x00}, +{0x8e31,0x3f}, +{0x8e32,0x06}, +{0x8e33,0x22}, +{0x8e34,0x00}, +{0x8e35,0x3f}, +{0x8e36,0x01}, +{0x8e37,0x2a}, +{0x8e38,0x00}, +{0x8e39,0x3f}, +{0x8e3a,0x02}, +{0x8e3b,0x00}, +{0x8e3c,0x00}, +{0x8e3d,0x36}, +{0x8e3e,0x06}, +{0x8e3f,0x07}, +{0x8e40,0x00}, +{0x8e41,0x3f}, +{0x8e42,0x0b}, +{0x8e43,0x0f}, +{0x8e44,0xf0}, +{0x8e45,0x00}, +{0x8e46,0x00}, +{0x8e47,0x00}, +{0x8e48,0x00}, +{0x8e49,0x30}, +{0x8e4a,0x01}, +{0x8e4b,0x40}, +{0x8e4c,0xbf}, +{0x8e4d,0x30}, +{0x8e4e,0x01}, +{0x8e4f,0x00}, +{0x8e50,0xbf}, +{0x8e51,0x30}, +{0x8e52,0x29}, +{0x8e53,0x70}, +{0x8e54,0x00}, +{0x8e55,0x3a}, +{0x8e56,0x00}, +{0x8e57,0x00}, +{0x8e58,0xff}, +{0x8e59,0x3a}, +{0x8e5a,0x00}, +{0x8e5b,0x00}, +{0x8e5c,0xff}, +{0x8e5d,0x36}, +{0x8e5e,0x03}, +{0x8e5f,0x36}, +{0x8e60,0x02}, +{0x8e61,0x41}, +{0x8e62,0x44}, +{0x8e63,0x58}, +{0x8e64,0x20}, +{0x8e65,0x18}, +{0x8e66,0x10}, +{0x8e67,0x0a}, +{0x8e68,0x04}, +{0x8e69,0x04}, +{0x8e6a,0x00}, +{0x8e6b,0x03}, +{0x8e6c,0xff}, +{0x8e6d,0x64}, +{0x8e6e,0x00}, +{0x8e6f,0x00}, +{0x8e70,0x80}, +{0x8e71,0x00}, +{0x8e72,0x00}, +{0x8e73,0x00}, +{0x8e74,0x00}, +{0x8e75,0x00}, +{0x8e76,0x00}, +{0x8e77,0x02}, +{0x8e78,0x04}, +{0x8e79,0x06}, +{0x8e7a,0x06}, +{0x8e7b,0x00}, +{0x8e7c,0x02}, +{0x8e7d,0x60},//CC +{0x8e7e,0x00}, +{0x8e7f,0x70}, +{0x8e80,0x50}, +{0x8e81,0x3c}, +{0x8e82,0x28}, +{0x8e83,0x1e}, +{0x8e84,0x10}, +{0x8e85,0x10}, +{0x8e86,0x50}, +{0x8e87,0x2d}, +{0x8e88,0x28}, +{0x8e89,0x16}, +{0x8e8a,0x10}, +{0x8e8b,0x10}, +{0x8e8c,0x02}, +{0x8e8d,0x00}, +{0x8e8e,0x10}, +{0x8e8f,0x0c}, +{0x8e90,0x10}, +{0x8e91,0x04}, +{0x8e92,0x0c}, +{0x8e93,0x6e}, +{0x8e94,0x0a}, +{0x8e95,0x05}, +{0x8e96,0x00}, +{0x8e97,0xa5}, +{0x8e98,0x5a}, +{0x8e99,0x00}, +{0x8e9a,0xae}, +{0x8e9b,0x35}, +{0x8e9c,0xaf}, +{0x8e9d,0x36}, +{0x8e9e,0xe4}, +{0x8e9f,0xfd}, +{0x8ea0,0xed}, +{0x8ea1,0xc3}, +{0x8ea2,0x95}, +{0x8ea3,0x37}, +{0x8ea4,0x50}, +{0x8ea5,0x33}, +{0x8ea6,0x12}, +{0x8ea7,0x0f}, +{0x8ea8,0xe2}, +{0x8ea9,0xe4}, +{0x8eaa,0x93}, +{0x8eab,0xf5}, +{0x8eac,0x38}, +{0x8ead,0x74}, +{0x8eae,0x01}, +{0x8eaf,0x93}, +{0x8eb0,0xf5}, +{0x8eb1,0x39}, +{0x8eb2,0x45}, +{0x8eb3,0x38}, +{0x8eb4,0x60}, +{0x8eb5,0x23}, +{0x8eb6,0x85}, +{0x8eb7,0x39}, +{0x8eb8,0x82}, +{0x8eb9,0x85}, +{0x8eba,0x38}, +{0x8ebb,0x83}, +{0x8ebc,0xe0}, +{0x8ebd,0xfc}, +{0x8ebe,0x12}, +{0x8ebf,0x0f}, +{0x8ec0,0xe2}, +{0x8ec1,0x74}, +{0x8ec2,0x03}, +{0x8ec3,0x93}, +{0x8ec4,0x52}, +{0x8ec5,0x04}, +{0x8ec6,0x12}, +{0x8ec7,0x0f}, +{0x8ec8,0xe2}, +{0x8ec9,0x74}, +{0x8eca,0x02}, +{0x8ecb,0x93}, +{0x8ecc,0x42}, +{0x8ecd,0x04}, +{0x8ece,0x85}, +{0x8ecf,0x39}, +{0x8ed0,0x82}, +{0x8ed1,0x85}, +{0x8ed2,0x38}, +{0x8ed3,0x83}, +{0x8ed4,0xec}, +{0x8ed5,0xf0}, +{0x8ed6,0x0d}, +{0x8ed7,0x80}, +{0x8ed8,0xc7}, +{0x8ed9,0x22}, +{0x8eda,0x78}, +{0x8edb,0xbe}, +{0x8edc,0xe6}, +{0x8edd,0xd3}, +{0x8ede,0x08}, +{0x8edf,0xff}, +{0x8ee0,0xe6}, +{0x8ee1,0x64}, +{0x8ee2,0x80}, +{0x8ee3,0xf8}, +{0x8ee4,0xef}, +{0x8ee5,0x64}, +{0x8ee6,0x80}, +{0x8ee7,0x98}, +{0x8ee8,0x22}, +{0x8ee9,0x93}, +{0x8eea,0xff}, +{0x8eeb,0x7e}, +{0x8eec,0x00}, +{0x8eed,0xe6}, +{0x8eee,0xfc}, +{0x8eef,0x08}, +{0x8ef0,0xe6}, +{0x8ef1,0xfd}, +{0x8ef2,0x12}, +{0x8ef3,0x04}, +{0x8ef4,0xc1}, +{0x8ef5,0x78}, +{0x8ef6,0xc1}, +{0x8ef7,0xe6}, +{0x8ef8,0xfc}, +{0x8ef9,0x08}, +{0x8efa,0xe6}, +{0x8efb,0xfd}, +{0x8efc,0xd3}, +{0x8efd,0xef}, +{0x8efe,0x9d}, +{0x8eff,0xee}, +{0x8f00,0x9c}, +{0x8f01,0x22}, +{0x8f02,0x78}, +{0x8f03,0xbd}, +{0x8f04,0xd3}, +{0x8f05,0xe6}, +{0x8f06,0x64}, +{0x8f07,0x80}, +{0x8f08,0x94}, +{0x8f09,0x80}, +{0x8f0a,0x22}, +{0x8f0b,0x25}, +{0x8f0c,0xe0}, +{0x8f0d,0x24}, +{0x8f0e,0x0a}, +{0x8f0f,0xf8}, +{0x8f10,0xe6}, +{0x8f11,0xfe}, +{0x8f12,0x08}, +{0x8f13,0xe6}, +{0x8f14,0xff}, +{0x8f15,0x22}, +{0x8f16,0xe5}, +{0x8f17,0x3c}, +{0x8f18,0xd3}, +{0x8f19,0x94}, +{0x8f1a,0x00}, +{0x8f1b,0x40}, +{0x8f1c,0x0b}, +{0x8f1d,0x90}, +{0x8f1e,0x0e}, +{0x8f1f,0x88}, +{0x8f20,0x12}, +{0x8f21,0x0b}, +{0x8f22,0xf1}, +{0x8f23,0x90}, +{0x8f24,0x0e}, +{0x8f25,0x86}, +{0x8f26,0x80}, +{0x8f27,0x09}, +{0x8f28,0x90}, +{0x8f29,0x0e}, +{0x8f2a,0x82}, +{0x8f2b,0x12}, +{0x8f2c,0x0b}, +{0x8f2d,0xf1}, +{0x8f2e,0x90}, +{0x8f2f,0x0e}, +{0x8f30,0x80}, +{0x8f31,0xe4}, +{0x8f32,0x93}, +{0x8f33,0xf5}, +{0x8f34,0x44}, +{0x8f35,0xa3}, +{0x8f36,0xe4}, +{0x8f37,0x93}, +{0x8f38,0xf5}, +{0x8f39,0x43}, +{0x8f3a,0xd2}, +{0x8f3b,0x06}, +{0x8f3c,0x30}, +{0x8f3d,0x06}, +{0x8f3e,0x03}, +{0x8f3f,0xd3}, +{0x8f40,0x80}, +{0x8f41,0x01}, +{0x8f42,0xc3}, +{0x8f43,0x92}, +{0x8f44,0x0e}, +{0x8f45,0x22}, +{0x8f46,0xa2}, +{0x8f47,0xaf}, +{0x8f48,0x92}, +{0x8f49,0x32}, +{0x8f4a,0xc2}, +{0x8f4b,0xaf}, +{0x8f4c,0xe5}, +{0x8f4d,0x23}, +{0x8f4e,0x45}, +{0x8f4f,0x22}, +{0x8f50,0x90}, +{0x8f51,0x0e}, +{0x8f52,0x5d}, +{0x8f53,0x60}, +{0x8f54,0x0e}, +{0x8f55,0x12}, +{0x8f56,0x0f}, +{0x8f57,0xcb}, +{0x8f58,0xe0}, +{0x8f59,0xf5}, +{0x8f5a,0x2c}, +{0x8f5b,0x12}, +{0x8f5c,0x0f}, +{0x8f5d,0xc8}, +{0x8f5e,0xe0}, +{0x8f5f,0xf5}, +{0x8f60,0x2d}, +{0x8f61,0x80}, +{0x8f62,0x0c}, +{0x8f63,0x12}, +{0x8f64,0x0f}, +{0x8f65,0xcb}, +{0x8f66,0xe5}, +{0x8f67,0x30}, +{0x8f68,0xf0}, +{0x8f69,0x12}, +{0x8f6a,0x0f}, +{0x8f6b,0xc8}, +{0x8f6c,0xe5}, +{0x8f6d,0x31}, +{0x8f6e,0xf0}, +{0x8f6f,0xa2}, +{0x8f70,0x32}, +{0x8f71,0x92}, +{0x8f72,0xaf}, +{0x8f73,0x22}, +{0x8f74,0xd2}, +{0x8f75,0x01}, +{0x8f76,0xc2}, +{0x8f77,0x02}, +{0x8f78,0xe4}, +{0x8f79,0xf5}, +{0x8f7a,0x1f}, +{0x8f7b,0xf5}, +{0x8f7c,0x1e}, +{0x8f7d,0xd2}, +{0x8f7e,0x35}, +{0x8f7f,0xd2}, +{0x8f80,0x33}, +{0x8f81,0xd2}, +{0x8f82,0x36}, +{0x8f83,0xd2}, +{0x8f84,0x01}, +{0x8f85,0xc2}, +{0x8f86,0x02}, +{0x8f87,0xf5}, +{0x8f88,0x1f}, +{0x8f89,0xf5}, +{0x8f8a,0x1e}, +{0x8f8b,0xd2}, +{0x8f8c,0x35}, +{0x8f8d,0xd2}, +{0x8f8e,0x33}, +{0x8f8f,0x22}, +{0x8f90,0xfb}, +{0x8f91,0xd3}, +{0x8f92,0xed}, +{0x8f93,0x9b}, +{0x8f94,0x74}, +{0x8f95,0x80}, +{0x8f96,0xf8}, +{0x8f97,0x6c}, +{0x8f98,0x98}, +{0x8f99,0x22}, +{0x8f9a,0x12}, +{0x8f9b,0x06}, +{0x8f9c,0x69}, +{0x8f9d,0xe5}, +{0x8f9e,0x40}, +{0x8f9f,0x2f}, +{0x8fa0,0xf5}, +{0x8fa1,0x40}, +{0x8fa2,0xe5}, +{0x8fa3,0x3f}, +{0x8fa4,0x3e}, +{0x8fa5,0xf5}, +{0x8fa6,0x3f}, +{0x8fa7,0xe5}, +{0x8fa8,0x3e}, +{0x8fa9,0x3d}, +{0x8faa,0xf5}, +{0x8fab,0x3e}, +{0x8fac,0xe5}, +{0x8fad,0x3d}, +{0x8fae,0x3c}, +{0x8faf,0xf5}, +{0x8fb0,0x3d}, +{0x8fb1,0x22}, +{0x8fb2,0xc0}, +{0x8fb3,0xe0}, +{0x8fb4,0xc0}, +{0x8fb5,0x83}, +{0x8fb6,0xc0}, +{0x8fb7,0x82}, +{0x8fb8,0x90}, +{0x8fb9,0x3f}, +{0x8fba,0x0d}, +{0x8fbb,0xe0}, +{0x8fbc,0xf5}, +{0x8fbd,0x33}, +{0x8fbe,0xe5}, +{0x8fbf,0x33}, +{0x8fc0,0xf0}, +{0x8fc1,0xd0}, +{0x8fc2,0x82}, +{0x8fc3,0xd0}, +{0x8fc4,0x83}, +{0x8fc5,0xd0}, +{0x8fc6,0xe0}, +{0x8fc7,0x32}, +{0x8fc8,0x90}, +{0x8fc9,0x0e}, +{0x8fca,0x5f}, +{0x8fcb,0xe4}, +{0x8fcc,0x93}, +{0x8fcd,0xfe}, +{0x8fce,0x74}, +{0x8fcf,0x01}, +{0x8fd0,0x93}, +{0x8fd1,0xf5}, +{0x8fd2,0x82}, +{0x8fd3,0x8e}, +{0x8fd4,0x83}, +{0x8fd5,0x22}, +{0x8fd6,0x78}, +{0x8fd7,0x7f}, +{0x8fd8,0xe4}, +{0x8fd9,0xf6}, +{0x8fda,0xd8}, +{0x8fdb,0xfd}, +{0x8fdc,0x75}, +{0x8fdd,0x81}, +{0x8fde,0xcd}, +{0x8fdf,0x02}, +{0x8fe0,0x0c}, +{0x8fe1,0x98}, +{0x8fe2,0x8f}, +{0x8fe3,0x82}, +{0x8fe4,0x8e}, +{0x8fe5,0x83}, +{0x8fe6,0x75}, +{0x8fe7,0xf0}, +{0x8fe8,0x04}, +{0x8fe9,0xed}, +{0x8fea,0x02}, +{0x8feb,0x06}, +{0x8fec,0xa5}, +{0x3022,0x00}, +{0x3023,0x00}, +{0x3024,0x00}, +{0x3025,0x00}, +{0x3026,0x00}, +{0x3027,0x00}, +{0x3028,0x00}, +{0x3029,0x7F}, +{0x3000,0x00}, +#elif 1 // ddl@rock-chips.com : 2012/12/10 Continues Focus from OVT +{0x3000,0x20}, +{0x8000,0x02}, +{0x8001,0x0f}, +{0x8002,0xd6}, +{0x8003,0x02}, +{0x8004,0x0a}, +{0x8005,0x39}, +{0x8006,0xc2}, +{0x8007,0x01}, +{0x8008,0x22}, +{0x8009,0x22}, +{0x800a,0x00}, +{0x800b,0x02}, +{0x800c,0x0f}, +{0x800d,0xb2}, +{0x800e,0xe5}, +{0x800f,0x1f}, +{0x8010,0x70}, +{0x8011,0x72}, +{0x8012,0xf5}, +{0x8013,0x1e}, +{0x8014,0xd2}, +{0x8015,0x35}, +{0x8016,0xff}, +{0x8017,0xef}, +{0x8018,0x25}, +{0x8019,0xe0}, +{0x801a,0x24}, +{0x801b,0x4e}, +{0x801c,0xf8}, +{0x801d,0xe4}, +{0x801e,0xf6}, +{0x801f,0x08}, +{0x8020,0xf6}, +{0x8021,0x0f}, +{0x8022,0xbf}, +{0x8023,0x34}, +{0x8024,0xf2}, +{0x8025,0x90}, +{0x8026,0x0e}, +{0x8027,0x93}, +{0x8028,0xe4}, +{0x8029,0x93}, +{0x802a,0xff}, +{0x802b,0xe5}, +{0x802c,0x4b}, +{0x802d,0xc3}, +{0x802e,0x9f}, +{0x802f,0x50}, +{0x8030,0x04}, +{0x8031,0x7f}, +{0x8032,0x05}, +{0x8033,0x80}, +{0x8034,0x02}, +{0x8035,0x7f}, +{0x8036,0xfb}, +{0x8037,0x78}, +{0x8038,0xbd}, +{0x8039,0xa6}, +{0x803a,0x07}, +{0x803b,0x12}, +{0x803c,0x0f}, +{0x803d,0x04}, +{0x803e,0x40}, +{0x803f,0x04}, +{0x8040,0x7f}, +{0x8041,0x03}, +{0x8042,0x80}, +{0x8043,0x02}, +{0x8044,0x7f}, +{0x8045,0x30}, +{0x8046,0x78}, +{0x8047,0xbc}, +{0x8048,0xa6}, +{0x8049,0x07}, +{0x804a,0xe6}, +{0x804b,0x18}, +{0x804c,0xf6}, +{0x804d,0x08}, +{0x804e,0xe6}, +{0x804f,0x78}, +{0x8050,0xb9}, +{0x8051,0xf6}, +{0x8052,0x78}, +{0x8053,0xbc}, +{0x8054,0xe6}, +{0x8055,0x78}, +{0x8056,0xba}, +{0x8057,0xf6}, +{0x8058,0x78}, +{0x8059,0xbf}, +{0x805a,0x76}, +{0x805b,0x33}, +{0x805c,0xe4}, +{0x805d,0x08}, +{0x805e,0xf6}, +{0x805f,0x78}, +{0x8060,0xb8}, +{0x8061,0x76}, +{0x8062,0x01}, +{0x8063,0x75}, +{0x8064,0x4a}, +{0x8065,0x02}, +{0x8066,0x78}, +{0x8067,0xb6}, +{0x8068,0xf6}, +{0x8069,0x08}, +{0x806a,0xf6}, +{0x806b,0x74}, +{0x806c,0xff}, +{0x806d,0x78}, +{0x806e,0xc1}, +{0x806f,0xf6}, +{0x8070,0x08}, +{0x8071,0xf6}, +{0x8072,0x75}, +{0x8073,0x1f}, +{0x8074,0x01}, +{0x8075,0x78}, +{0x8076,0xbc}, +{0x8077,0xe6}, +{0x8078,0x75}, +{0x8079,0xf0}, +{0x807a,0x05}, +{0x807b,0xa4}, +{0x807c,0xf5}, +{0x807d,0x4b}, +{0x807e,0x12}, +{0x807f,0x0a}, +{0x8080,0xff}, +{0x8081,0xc2}, +{0x8082,0x37}, +{0x8083,0x22}, +{0x8084,0x78}, +{0x8085,0xb8}, +{0x8086,0xe6}, +{0x8087,0xd3}, +{0x8088,0x94}, +{0x8089,0x00}, +{0x808a,0x40}, +{0x808b,0x02}, +{0x808c,0x16}, +{0x808d,0x22}, +{0x808e,0xe5}, +{0x808f,0x1f}, +{0x8090,0xb4}, +{0x8091,0x05}, +{0x8092,0x23}, +{0x8093,0xe4}, +{0x8094,0xf5}, +{0x8095,0x1f}, +{0x8096,0xc2}, +{0x8097,0x01}, +{0x8098,0x78}, +{0x8099,0xb6}, +{0x809a,0xe6}, +{0x809b,0xfe}, +{0x809c,0x08}, +{0x809d,0xe6}, +{0x809e,0xff}, +{0x809f,0x78}, +{0x80a0,0x4e}, +{0x80a1,0xa6}, +{0x80a2,0x06}, +{0x80a3,0x08}, +{0x80a4,0xa6}, +{0x80a5,0x07}, +{0x80a6,0xa2}, +{0x80a7,0x37}, +{0x80a8,0xe4}, +{0x80a9,0x33}, +{0x80aa,0xf5}, +{0x80ab,0x3c}, +{0x80ac,0x90}, +{0x80ad,0x30}, +{0x80ae,0x28}, +{0x80af,0xf0}, +{0x80b0,0x75}, +{0x80b1,0x1e}, +{0x80b2,0x10}, +{0x80b3,0xd2}, +{0x80b4,0x35}, +{0x80b5,0x22}, +{0x80b6,0xe5}, +{0x80b7,0x4b}, +{0x80b8,0x75}, +{0x80b9,0xf0}, +{0x80ba,0x05}, +{0x80bb,0x84}, +{0x80bc,0x78}, +{0x80bd,0xbc}, +{0x80be,0xf6}, +{0x80bf,0x90}, +{0x80c0,0x0e}, +{0x80c1,0x8c}, +{0x80c2,0xe4}, +{0x80c3,0x93}, +{0x80c4,0xff}, +{0x80c5,0x25}, +{0x80c6,0xe0}, +{0x80c7,0x24}, +{0x80c8,0x0a}, +{0x80c9,0xf8}, +{0x80ca,0xe6}, +{0x80cb,0xfc}, +{0x80cc,0x08}, +{0x80cd,0xe6}, +{0x80ce,0xfd}, +{0x80cf,0x78}, +{0x80d0,0xbc}, +{0x80d1,0xe6}, +{0x80d2,0x25}, +{0x80d3,0xe0}, +{0x80d4,0x24}, +{0x80d5,0x4e}, +{0x80d6,0xf8}, +{0x80d7,0xa6}, +{0x80d8,0x04}, +{0x80d9,0x08}, +{0x80da,0xa6}, +{0x80db,0x05}, +{0x80dc,0xef}, +{0x80dd,0x12}, +{0x80de,0x0f}, +{0x80df,0x0b}, +{0x80e0,0xd3}, +{0x80e1,0x78}, +{0x80e2,0xb7}, +{0x80e3,0x96}, +{0x80e4,0xee}, +{0x80e5,0x18}, +{0x80e6,0x96}, +{0x80e7,0x40}, +{0x80e8,0x0d}, +{0x80e9,0x78}, +{0x80ea,0xbc}, +{0x80eb,0xe6}, +{0x80ec,0x78}, +{0x80ed,0xb9}, +{0x80ee,0xf6}, +{0x80ef,0x78}, +{0x80f0,0xb6}, +{0x80f1,0xa6}, +{0x80f2,0x06}, +{0x80f3,0x08}, +{0x80f4,0xa6}, +{0x80f5,0x07}, +{0x80f6,0x90}, +{0x80f7,0x0e}, +{0x80f8,0x8c}, +{0x80f9,0xe4}, +{0x80fa,0x93}, +{0x80fb,0x12}, +{0x80fc,0x0f}, +{0x80fd,0x0b}, +{0x80fe,0xc3}, +{0x80ff,0x78}, +{0x8100,0xc2}, +{0x8101,0x96}, +{0x8102,0xee}, +{0x8103,0x18}, +{0x8104,0x96}, +{0x8105,0x50}, +{0x8106,0x0d}, +{0x8107,0x78}, +{0x8108,0xbc}, +{0x8109,0xe6}, +{0x810a,0x78}, +{0x810b,0xba}, +{0x810c,0xf6}, +{0x810d,0x78}, +{0x810e,0xc1}, +{0x810f,0xa6}, +{0x8110,0x06}, +{0x8111,0x08}, +{0x8112,0xa6}, +{0x8113,0x07}, +{0x8114,0x78}, +{0x8115,0xb6}, +{0x8116,0xe6}, +{0x8117,0xfe}, +{0x8118,0x08}, +{0x8119,0xe6}, +{0x811a,0xc3}, +{0x811b,0x78}, +{0x811c,0xc2}, +{0x811d,0x96}, +{0x811e,0xff}, +{0x811f,0xee}, +{0x8120,0x18}, +{0x8121,0x96}, +{0x8122,0x78}, +{0x8123,0xc3}, +{0x8124,0xf6}, +{0x8125,0x08}, +{0x8126,0xa6}, +{0x8127,0x07}, +{0x8128,0x90}, +{0x8129,0x0e}, +{0x812a,0x95}, +{0x812b,0xe4}, +{0x812c,0x18}, +{0x812d,0x12}, +{0x812e,0x0e}, +{0x812f,0xe9}, +{0x8130,0x40}, +{0x8131,0x02}, +{0x8132,0xd2}, +{0x8133,0x37}, +{0x8134,0x78}, +{0x8135,0xbc}, +{0x8136,0xe6}, +{0x8137,0x08}, +{0x8138,0x26}, +{0x8139,0x08}, +{0x813a,0xf6}, +{0x813b,0xe5}, +{0x813c,0x1f}, +{0x813d,0x64}, +{0x813e,0x01}, +{0x813f,0x70}, +{0x8140,0x4a}, +{0x8141,0xe6}, +{0x8142,0xc3}, +{0x8143,0x78}, +{0x8144,0xc0}, +{0x8145,0x12}, +{0x8146,0x0e}, +{0x8147,0xdf}, +{0x8148,0x40}, +{0x8149,0x05}, +{0x814a,0x12}, +{0x814b,0x0e}, +{0x814c,0xda}, +{0x814d,0x40}, +{0x814e,0x39}, +{0x814f,0x12}, +{0x8150,0x0f}, +{0x8151,0x02}, +{0x8152,0x40}, +{0x8153,0x04}, +{0x8154,0x7f}, +{0x8155,0xfe}, +{0x8156,0x80}, +{0x8157,0x02}, +{0x8158,0x7f}, +{0x8159,0x02}, +{0x815a,0x78}, +{0x815b,0xbd}, +{0x815c,0xa6}, +{0x815d,0x07}, +{0x815e,0x78}, +{0x815f,0xb9}, +{0x8160,0xe6}, +{0x8161,0x24}, +{0x8162,0x03}, +{0x8163,0x78}, +{0x8164,0xbf}, +{0x8165,0xf6}, +{0x8166,0x78}, +{0x8167,0xb9}, +{0x8168,0xe6}, +{0x8169,0x24}, +{0x816a,0xfd}, +{0x816b,0x78}, +{0x816c,0xc0}, +{0x816d,0xf6}, +{0x816e,0x12}, +{0x816f,0x0f}, +{0x8170,0x02}, +{0x8171,0x40}, +{0x8172,0x06}, +{0x8173,0x78}, +{0x8174,0xc0}, +{0x8175,0xe6}, +{0x8176,0xff}, +{0x8177,0x80}, +{0x8178,0x04}, +{0x8179,0x78}, +{0x817a,0xbf}, +{0x817b,0xe6}, +{0x817c,0xff}, +{0x817d,0x78}, +{0x817e,0xbe}, +{0x817f,0xa6}, +{0x8180,0x07}, +{0x8181,0x75}, +{0x8182,0x1f}, +{0x8183,0x02}, +{0x8184,0x78}, +{0x8185,0xb8}, +{0x8186,0x76}, +{0x8187,0x01}, +{0x8188,0x02}, +{0x8189,0x02}, +{0x818a,0x4a}, +{0x818b,0xe5}, +{0x818c,0x1f}, +{0x818d,0x64}, +{0x818e,0x02}, +{0x818f,0x60}, +{0x8190,0x03}, +{0x8191,0x02}, +{0x8192,0x02}, +{0x8193,0x2a}, +{0x8194,0x78}, +{0x8195,0xbe}, +{0x8196,0xe6}, +{0x8197,0xff}, +{0x8198,0xc3}, +{0x8199,0x78}, +{0x819a,0xc0}, +{0x819b,0x12}, +{0x819c,0x0e}, +{0x819d,0xe0}, +{0x819e,0x40}, +{0x819f,0x08}, +{0x81a0,0x12}, +{0x81a1,0x0e}, +{0x81a2,0xda}, +{0x81a3,0x50}, +{0x81a4,0x03}, +{0x81a5,0x02}, +{0x81a6,0x02}, +{0x81a7,0x28}, +{0x81a8,0x12}, +{0x81a9,0x0f}, +{0x81aa,0x02}, +{0x81ab,0x40}, +{0x81ac,0x04}, +{0x81ad,0x7f}, +{0x81ae,0xff}, +{0x81af,0x80}, +{0x81b0,0x02}, +{0x81b1,0x7f}, +{0x81b2,0x01}, +{0x81b3,0x78}, +{0x81b4,0xbd}, +{0x81b5,0xa6}, +{0x81b6,0x07}, +{0x81b7,0x78}, +{0x81b8,0xb9}, +{0x81b9,0xe6}, +{0x81ba,0x04}, +{0x81bb,0x78}, +{0x81bc,0xbf}, +{0x81bd,0xf6}, +{0x81be,0x78}, +{0x81bf,0xb9}, +{0x81c0,0xe6}, +{0x81c1,0x14}, +{0x81c2,0x78}, +{0x81c3,0xc0}, +{0x81c4,0xf6}, +{0x81c5,0x18}, +{0x81c6,0x12}, +{0x81c7,0x0f}, +{0x81c8,0x04}, +{0x81c9,0x40}, +{0x81ca,0x04}, +{0x81cb,0xe6}, +{0x81cc,0xff}, +{0x81cd,0x80}, +{0x81ce,0x02}, +{0x81cf,0x7f}, +{0x81d0,0x00}, +{0x81d1,0x78}, +{0x81d2,0xbf}, +{0x81d3,0xa6}, +{0x81d4,0x07}, +{0x81d5,0xd3}, +{0x81d6,0x08}, +{0x81d7,0xe6}, +{0x81d8,0x64}, +{0x81d9,0x80}, +{0x81da,0x94}, +{0x81db,0x80}, +{0x81dc,0x40}, +{0x81dd,0x04}, +{0x81de,0xe6}, +{0x81df,0xff}, +{0x81e0,0x80}, +{0x81e1,0x02}, +{0x81e2,0x7f}, +{0x81e3,0x00}, +{0x81e4,0x78}, +{0x81e5,0xc0}, +{0x81e6,0xa6}, +{0x81e7,0x07}, +{0x81e8,0xc3}, +{0x81e9,0x18}, +{0x81ea,0xe6}, +{0x81eb,0x64}, +{0x81ec,0x80}, +{0x81ed,0x94}, +{0x81ee,0xb3}, +{0x81ef,0x50}, +{0x81f0,0x04}, +{0x81f1,0xe6}, +{0x81f2,0xff}, +{0x81f3,0x80}, +{0x81f4,0x02}, +{0x81f5,0x7f}, +{0x81f6,0x33}, +{0x81f7,0x78}, +{0x81f8,0xbf}, +{0x81f9,0xa6}, +{0x81fa,0x07}, +{0x81fb,0xc3}, +{0x81fc,0x08}, +{0x81fd,0xe6}, +{0x81fe,0x64}, +{0x81ff,0x80}, +{0x8200,0x94}, +{0x8201,0xb3}, +{0x8202,0x50}, +{0x8203,0x04}, +{0x8204,0xe6}, +{0x8205,0xff}, +{0x8206,0x80}, +{0x8207,0x02}, +{0x8208,0x7f}, +{0x8209,0x33}, +{0x820a,0x78}, +{0x820b,0xc0}, +{0x820c,0xa6}, +{0x820d,0x07}, +{0x820e,0x12}, +{0x820f,0x0f}, +{0x8210,0x02}, +{0x8211,0x40}, +{0x8212,0x06}, +{0x8213,0x78}, +{0x8214,0xc0}, +{0x8215,0xe6}, +{0x8216,0xff}, +{0x8217,0x80}, +{0x8218,0x04}, +{0x8219,0x78}, +{0x821a,0xbf}, +{0x821b,0xe6}, +{0x821c,0xff}, +{0x821d,0x78}, +{0x821e,0xbe}, +{0x821f,0xa6}, +{0x8220,0x07}, +{0x8221,0x75}, +{0x8222,0x1f}, +{0x8223,0x03}, +{0x8224,0x78}, +{0x8225,0xb8}, +{0x8226,0x76}, +{0x8227,0x01}, +{0x8228,0x80}, +{0x8229,0x20}, +{0x822a,0xe5}, +{0x822b,0x1f}, +{0x822c,0x64}, +{0x822d,0x03}, +{0x822e,0x70}, +{0x822f,0x26}, +{0x8230,0x78}, +{0x8231,0xbe}, +{0x8232,0xe6}, +{0x8233,0xff}, +{0x8234,0xc3}, +{0x8235,0x78}, +{0x8236,0xc0}, +{0x8237,0x12}, +{0x8238,0x0e}, +{0x8239,0xe0}, +{0x823a,0x40}, +{0x823b,0x05}, +{0x823c,0x12}, +{0x823d,0x0e}, +{0x823e,0xda}, +{0x823f,0x40}, +{0x8240,0x09}, +{0x8241,0x78}, +{0x8242,0xb9}, +{0x8243,0xe6}, +{0x8244,0x78}, +{0x8245,0xbe}, +{0x8246,0xf6}, +{0x8247,0x75}, +{0x8248,0x1f}, +{0x8249,0x04}, +{0x824a,0x78}, +{0x824b,0xbe}, +{0x824c,0xe6}, +{0x824d,0x75}, +{0x824e,0xf0}, +{0x824f,0x05}, +{0x8250,0xa4}, +{0x8251,0xf5}, +{0x8252,0x4b}, +{0x8253,0x02}, +{0x8254,0x0a}, +{0x8255,0xff}, +{0x8256,0xe5}, +{0x8257,0x1f}, +{0x8258,0xb4}, +{0x8259,0x04}, +{0x825a,0x10}, +{0x825b,0x90}, +{0x825c,0x0e}, +{0x825d,0x94}, +{0x825e,0xe4}, +{0x825f,0x78}, +{0x8260,0xc3}, +{0x8261,0x12}, +{0x8262,0x0e}, +{0x8263,0xe9}, +{0x8264,0x40}, +{0x8265,0x02}, +{0x8266,0xd2}, +{0x8267,0x37}, +{0x8268,0x75}, +{0x8269,0x1f}, +{0x826a,0x05}, +{0x826b,0x22}, +{0x826c,0x30}, +{0x826d,0x01}, +{0x826e,0x03}, +{0x826f,0x02}, +{0x8270,0x04}, +{0x8271,0xc0}, +{0x8272,0x30}, +{0x8273,0x02}, +{0x8274,0x03}, +{0x8275,0x02}, +{0x8276,0x04}, +{0x8277,0xc0}, +{0x8278,0x90}, +{0x8279,0x51}, +{0x827a,0xa5}, +{0x827b,0xe0}, +{0x827c,0x78}, +{0x827d,0x93}, +{0x827e,0xf6}, +{0x827f,0xa3}, +{0x8280,0xe0}, +{0x8281,0x08}, +{0x8282,0xf6}, +{0x8283,0xa3}, +{0x8284,0xe0}, +{0x8285,0x08}, +{0x8286,0xf6}, +{0x8287,0xe5}, +{0x8288,0x1f}, +{0x8289,0x70}, +{0x828a,0x3c}, +{0x828b,0x75}, +{0x828c,0x1e}, +{0x828d,0x20}, +{0x828e,0xd2}, +{0x828f,0x35}, +{0x8290,0x12}, +{0x8291,0x0c}, +{0x8292,0x7a}, +{0x8293,0x78}, +{0x8294,0x7e}, +{0x8295,0xa6}, +{0x8296,0x06}, +{0x8297,0x08}, +{0x8298,0xa6}, +{0x8299,0x07}, +{0x829a,0x78}, +{0x829b,0x8b}, +{0x829c,0xa6}, +{0x829d,0x09}, +{0x829e,0x18}, +{0x829f,0x76}, +{0x82a0,0x01}, +{0x82a1,0x12}, +{0x82a2,0x0c}, +{0x82a3,0x5b}, +{0x82a4,0x78}, +{0x82a5,0x4e}, +{0x82a6,0xa6}, +{0x82a7,0x06}, +{0x82a8,0x08}, +{0x82a9,0xa6}, +{0x82aa,0x07}, +{0x82ab,0x78}, +{0x82ac,0x8b}, +{0x82ad,0xe6}, +{0x82ae,0x78}, +{0x82af,0x6e}, +{0x82b0,0xf6}, +{0x82b1,0x75}, +{0x82b2,0x1f}, +{0x82b3,0x01}, +{0x82b4,0x78}, +{0x82b5,0x93}, +{0x82b6,0xe6}, +{0x82b7,0x78}, +{0x82b8,0x90}, +{0x82b9,0xf6}, +{0x82ba,0x78}, +{0x82bb,0x94}, +{0x82bc,0xe6}, +{0x82bd,0x78}, +{0x82be,0x91}, +{0x82bf,0xf6}, +{0x82c0,0x78}, +{0x82c1,0x95}, +{0x82c2,0xe6}, +{0x82c3,0x78}, +{0x82c4,0x92}, +{0x82c5,0xf6}, +{0x82c6,0x22}, +{0x82c7,0x79}, +{0x82c8,0x90}, +{0x82c9,0xe7}, +{0x82ca,0xd3}, +{0x82cb,0x78}, +{0x82cc,0x93}, +{0x82cd,0x96}, +{0x82ce,0x40}, +{0x82cf,0x05}, +{0x82d0,0xe7}, +{0x82d1,0x96}, +{0x82d2,0xff}, +{0x82d3,0x80}, +{0x82d4,0x08}, +{0x82d5,0xc3}, +{0x82d6,0x79}, +{0x82d7,0x93}, +{0x82d8,0xe7}, +{0x82d9,0x78}, +{0x82da,0x90}, +{0x82db,0x96}, +{0x82dc,0xff}, +{0x82dd,0x78}, +{0x82de,0x88}, +{0x82df,0x76}, +{0x82e0,0x00}, +{0x82e1,0x08}, +{0x82e2,0xa6}, +{0x82e3,0x07}, +{0x82e4,0x79}, +{0x82e5,0x91}, +{0x82e6,0xe7}, +{0x82e7,0xd3}, +{0x82e8,0x78}, +{0x82e9,0x94}, +{0x82ea,0x96}, +{0x82eb,0x40}, +{0x82ec,0x05}, +{0x82ed,0xe7}, +{0x82ee,0x96}, +{0x82ef,0xff}, +{0x82f0,0x80}, +{0x82f1,0x08}, +{0x82f2,0xc3}, +{0x82f3,0x79}, +{0x82f4,0x94}, +{0x82f5,0xe7}, +{0x82f6,0x78}, +{0x82f7,0x91}, +{0x82f8,0x96}, +{0x82f9,0xff}, +{0x82fa,0x12}, +{0x82fb,0x0c}, +{0x82fc,0x8e}, +{0x82fd,0x79}, +{0x82fe,0x92}, +{0x82ff,0xe7}, +{0x8300,0xd3}, +{0x8301,0x78}, +{0x8302,0x95}, +{0x8303,0x96}, +{0x8304,0x40}, +{0x8305,0x05}, +{0x8306,0xe7}, +{0x8307,0x96}, +{0x8308,0xff}, +{0x8309,0x80}, +{0x830a,0x08}, +{0x830b,0xc3}, +{0x830c,0x79}, +{0x830d,0x95}, +{0x830e,0xe7}, +{0x830f,0x78}, +{0x8310,0x92}, +{0x8311,0x96}, +{0x8312,0xff}, +{0x8313,0x12}, +{0x8314,0x0c}, +{0x8315,0x8e}, +{0x8316,0x12}, +{0x8317,0x0c}, +{0x8318,0x5b}, +{0x8319,0x78}, +{0x831a,0x8a}, +{0x831b,0xe6}, +{0x831c,0x25}, +{0x831d,0xe0}, +{0x831e,0x24}, +{0x831f,0x4e}, +{0x8320,0xf8}, +{0x8321,0xa6}, +{0x8322,0x06}, +{0x8323,0x08}, +{0x8324,0xa6}, +{0x8325,0x07}, +{0x8326,0x78}, +{0x8327,0x8a}, +{0x8328,0xe6}, +{0x8329,0x24}, +{0x832a,0x6e}, +{0x832b,0xf8}, +{0x832c,0xa6}, +{0x832d,0x09}, +{0x832e,0x78}, +{0x832f,0x8a}, +{0x8330,0xe6}, +{0x8331,0x24}, +{0x8332,0x01}, +{0x8333,0xff}, +{0x8334,0xe4}, +{0x8335,0x33}, +{0x8336,0xfe}, +{0x8337,0xd3}, +{0x8338,0xef}, +{0x8339,0x94}, +{0x833a,0x0f}, +{0x833b,0xee}, +{0x833c,0x64}, +{0x833d,0x80}, +{0x833e,0x94}, +{0x833f,0x80}, +{0x8340,0x40}, +{0x8341,0x04}, +{0x8342,0x7f}, +{0x8343,0x00}, +{0x8344,0x80}, +{0x8345,0x05}, +{0x8346,0x78}, +{0x8347,0x8a}, +{0x8348,0xe6}, +{0x8349,0x04}, +{0x834a,0xff}, +{0x834b,0x78}, +{0x834c,0x8a}, +{0x834d,0xa6}, +{0x834e,0x07}, +{0x834f,0xe5}, +{0x8350,0x1f}, +{0x8351,0xb4}, +{0x8352,0x01}, +{0x8353,0x0a}, +{0x8354,0xe6}, +{0x8355,0x60}, +{0x8356,0x03}, +{0x8357,0x02}, +{0x8358,0x04}, +{0x8359,0xc0}, +{0x835a,0x75}, +{0x835b,0x1f}, +{0x835c,0x02}, +{0x835d,0x22}, +{0x835e,0x12}, +{0x835f,0x0c}, +{0x8360,0x7a}, +{0x8361,0x78}, +{0x8362,0x80}, +{0x8363,0xa6}, +{0x8364,0x06}, +{0x8365,0x08}, +{0x8366,0xa6}, +{0x8367,0x07}, +{0x8368,0x12}, +{0x8369,0x0c}, +{0x836a,0x7a}, +{0x836b,0x78}, +{0x836c,0x82}, +{0x836d,0xa6}, +{0x836e,0x06}, +{0x836f,0x08}, +{0x8370,0xa6}, +{0x8371,0x07}, +{0x8372,0x78}, +{0x8373,0x6e}, +{0x8374,0xe6}, +{0x8375,0x78}, +{0x8376,0x8c}, +{0x8377,0xf6}, +{0x8378,0x78}, +{0x8379,0x6e}, +{0x837a,0xe6}, +{0x837b,0x78}, +{0x837c,0x8d}, +{0x837d,0xf6}, +{0x837e,0x7f}, +{0x837f,0x01}, +{0x8380,0xef}, +{0x8381,0x25}, +{0x8382,0xe0}, +{0x8383,0x24}, +{0x8384,0x4f}, +{0x8385,0xf9}, +{0x8386,0xc3}, +{0x8387,0x78}, +{0x8388,0x81}, +{0x8389,0xe6}, +{0x838a,0x97}, +{0x838b,0x18}, +{0x838c,0xe6}, +{0x838d,0x19}, +{0x838e,0x97}, +{0x838f,0x50}, +{0x8390,0x0a}, +{0x8391,0x12}, +{0x8392,0x0c}, +{0x8393,0x82}, +{0x8394,0x78}, +{0x8395,0x80}, +{0x8396,0xa6}, +{0x8397,0x04}, +{0x8398,0x08}, +{0x8399,0xa6}, +{0x839a,0x05}, +{0x839b,0x74}, +{0x839c,0x6e}, +{0x839d,0x2f}, +{0x839e,0xf9}, +{0x839f,0x78}, +{0x83a0,0x8c}, +{0x83a1,0xe6}, +{0x83a2,0xc3}, +{0x83a3,0x97}, +{0x83a4,0x50}, +{0x83a5,0x08}, +{0x83a6,0x74}, +{0x83a7,0x6e}, +{0x83a8,0x2f}, +{0x83a9,0xf8}, +{0x83aa,0xe6}, +{0x83ab,0x78}, +{0x83ac,0x8c}, +{0x83ad,0xf6}, +{0x83ae,0xef}, +{0x83af,0x25}, +{0x83b0,0xe0}, +{0x83b1,0x24}, +{0x83b2,0x4f}, +{0x83b3,0xf9}, +{0x83b4,0xd3}, +{0x83b5,0x78}, +{0x83b6,0x83}, +{0x83b7,0xe6}, +{0x83b8,0x97}, +{0x83b9,0x18}, +{0x83ba,0xe6}, +{0x83bb,0x19}, +{0x83bc,0x97}, +{0x83bd,0x40}, +{0x83be,0x0a}, +{0x83bf,0x12}, +{0x83c0,0x0c}, +{0x83c1,0x82}, +{0x83c2,0x78}, +{0x83c3,0x82}, +{0x83c4,0xa6}, +{0x83c5,0x04}, +{0x83c6,0x08}, +{0x83c7,0xa6}, +{0x83c8,0x05}, +{0x83c9,0x74}, +{0x83ca,0x6e}, +{0x83cb,0x2f}, +{0x83cc,0xf9}, +{0x83cd,0x78}, +{0x83ce,0x8d}, +{0x83cf,0xe6}, +{0x83d0,0xd3}, +{0x83d1,0x97}, +{0x83d2,0x40}, +{0x83d3,0x08}, +{0x83d4,0x74}, +{0x83d5,0x6e}, +{0x83d6,0x2f}, +{0x83d7,0xf8}, +{0x83d8,0xe6}, +{0x83d9,0x78}, +{0x83da,0x8d}, +{0x83db,0xf6}, +{0x83dc,0x0f}, +{0x83dd,0xef}, +{0x83de,0x64}, +{0x83df,0x10}, +{0x83e0,0x70}, +{0x83e1,0x9e}, +{0x83e2,0xc3}, +{0x83e3,0x79}, +{0x83e4,0x81}, +{0x83e5,0xe7}, +{0x83e6,0x78}, +{0x83e7,0x83}, +{0x83e8,0x96}, +{0x83e9,0xff}, +{0x83ea,0x19}, +{0x83eb,0xe7}, +{0x83ec,0x18}, +{0x83ed,0x96}, +{0x83ee,0x78}, +{0x83ef,0x84}, +{0x83f0,0xf6}, +{0x83f1,0x08}, +{0x83f2,0xa6}, +{0x83f3,0x07}, +{0x83f4,0xc3}, +{0x83f5,0x79}, +{0x83f6,0x8c}, +{0x83f7,0xe7}, +{0x83f8,0x78}, +{0x83f9,0x8d}, +{0x83fa,0x96}, +{0x83fb,0x08}, +{0x83fc,0xf6}, +{0x83fd,0xd3}, +{0x83fe,0x79}, +{0x83ff,0x81}, +{0x8400,0xe7}, +{0x8401,0x78}, +{0x8402,0x7f}, +{0x8403,0x96}, +{0x8404,0x19}, +{0x8405,0xe7}, +{0x8406,0x18}, +{0x8407,0x96}, +{0x8408,0x40}, +{0x8409,0x05}, +{0x840a,0x09}, +{0x840b,0xe7}, +{0x840c,0x08}, +{0x840d,0x80}, +{0x840e,0x06}, +{0x840f,0xc3}, +{0x8410,0x79}, +{0x8411,0x7f}, +{0x8412,0xe7}, +{0x8413,0x78}, +{0x8414,0x81}, +{0x8415,0x96}, +{0x8416,0xff}, +{0x8417,0x19}, +{0x8418,0xe7}, +{0x8419,0x18}, +{0x841a,0x96}, +{0x841b,0xfe}, +{0x841c,0x78}, +{0x841d,0x86}, +{0x841e,0xa6}, +{0x841f,0x06}, +{0x8420,0x08}, +{0x8421,0xa6}, +{0x8422,0x07}, +{0x8423,0x79}, +{0x8424,0x8c}, +{0x8425,0xe7}, +{0x8426,0xd3}, +{0x8427,0x78}, +{0x8428,0x8b}, +{0x8429,0x96}, +{0x842a,0x40}, +{0x842b,0x05}, +{0x842c,0xe7}, +{0x842d,0x96}, +{0x842e,0xff}, +{0x842f,0x80}, +{0x8430,0x08}, +{0x8431,0xc3}, +{0x8432,0x79}, +{0x8433,0x8b}, +{0x8434,0xe7}, +{0x8435,0x78}, +{0x8436,0x8c}, +{0x8437,0x96}, +{0x8438,0xff}, +{0x8439,0x78}, +{0x843a,0x8f}, +{0x843b,0xa6}, +{0x843c,0x07}, +{0x843d,0xe5}, +{0x843e,0x1f}, +{0x843f,0x64}, +{0x8440,0x02}, +{0x8441,0x70}, +{0x8442,0x69}, +{0x8443,0x90}, +{0x8444,0x0e}, +{0x8445,0x91}, +{0x8446,0x93}, +{0x8447,0xff}, +{0x8448,0x18}, +{0x8449,0xe6}, +{0x844a,0xc3}, +{0x844b,0x9f}, +{0x844c,0x50}, +{0x844d,0x72}, +{0x844e,0x12}, +{0x844f,0x0c}, +{0x8450,0x4a}, +{0x8451,0x12}, +{0x8452,0x0c}, +{0x8453,0x2f}, +{0x8454,0x90}, +{0x8455,0x0e}, +{0x8456,0x8e}, +{0x8457,0x12}, +{0x8458,0x0c}, +{0x8459,0x38}, +{0x845a,0x78}, +{0x845b,0x80}, +{0x845c,0x12}, +{0x845d,0x0c}, +{0x845e,0x6b}, +{0x845f,0x7b}, +{0x8460,0x04}, +{0x8461,0x12}, +{0x8462,0x0c}, +{0x8463,0x1d}, +{0x8464,0xc3}, +{0x8465,0x12}, +{0x8466,0x06}, +{0x8467,0x45}, +{0x8468,0x50}, +{0x8469,0x56}, +{0x846a,0x90}, +{0x846b,0x0e}, +{0x846c,0x92}, +{0x846d,0xe4}, +{0x846e,0x93}, +{0x846f,0xff}, +{0x8470,0x78}, +{0x8471,0x8f}, +{0x8472,0xe6}, +{0x8473,0x9f}, +{0x8474,0x40}, +{0x8475,0x02}, +{0x8476,0x80}, +{0x8477,0x11}, +{0x8478,0x90}, +{0x8479,0x0e}, +{0x847a,0x90}, +{0x847b,0xe4}, +{0x847c,0x93}, +{0x847d,0xff}, +{0x847e,0xd3}, +{0x847f,0x78}, +{0x8480,0x89}, +{0x8481,0xe6}, +{0x8482,0x9f}, +{0x8483,0x18}, +{0x8484,0xe6}, +{0x8485,0x94}, +{0x8486,0x00}, +{0x8487,0x40}, +{0x8488,0x03}, +{0x8489,0x75}, +{0x848a,0x1f}, +{0x848b,0x05}, +{0x848c,0x12}, +{0x848d,0x0c}, +{0x848e,0x4a}, +{0x848f,0x12}, +{0x8490,0x0c}, +{0x8491,0x2f}, +{0x8492,0x90}, +{0x8493,0x0e}, +{0x8494,0x8f}, +{0x8495,0x12}, +{0x8496,0x0c}, +{0x8497,0x38}, +{0x8498,0x78}, +{0x8499,0x7e}, +{0x849a,0x12}, +{0x849b,0x0c}, +{0x849c,0x6b}, +{0x849d,0x7b}, +{0x849e,0x40}, +{0x849f,0x12}, +{0x84a0,0x0c}, +{0x84a1,0x1d}, +{0x84a2,0xd3}, +{0x84a3,0x12}, +{0x84a4,0x06}, +{0x84a5,0x45}, +{0x84a6,0x40}, +{0x84a7,0x18}, +{0x84a8,0x75}, +{0x84a9,0x1f}, +{0x84aa,0x05}, +{0x84ab,0x22}, +{0x84ac,0xe5}, +{0x84ad,0x1f}, +{0x84ae,0xb4}, +{0x84af,0x05}, +{0x84b0,0x0f}, +{0x84b1,0xd2}, +{0x84b2,0x01}, +{0x84b3,0xc2}, +{0x84b4,0x02}, +{0x84b5,0xe4}, +{0x84b6,0xf5}, +{0x84b7,0x1f}, +{0x84b8,0xf5}, +{0x84b9,0x1e}, +{0x84ba,0xd2}, +{0x84bb,0x35}, +{0x84bc,0xd2}, +{0x84bd,0x33}, +{0x84be,0xd2}, +{0x84bf,0x36}, +{0x84c0,0x22}, +{0x84c1,0xef}, +{0x84c2,0x8d}, +{0x84c3,0xf0}, +{0x84c4,0xa4}, +{0x84c5,0xa8}, +{0x84c6,0xf0}, +{0x84c7,0xcf}, +{0x84c8,0x8c}, +{0x84c9,0xf0}, +{0x84ca,0xa4}, +{0x84cb,0x28}, +{0x84cc,0xce}, +{0x84cd,0x8d}, +{0x84ce,0xf0}, +{0x84cf,0xa4}, +{0x84d0,0x2e}, +{0x84d1,0xfe}, +{0x84d2,0x22}, +{0x84d3,0xbc}, +{0x84d4,0x00}, +{0x84d5,0x0b}, +{0x84d6,0xbe}, +{0x84d7,0x00}, +{0x84d8,0x29}, +{0x84d9,0xef}, +{0x84da,0x8d}, +{0x84db,0xf0}, +{0x84dc,0x84}, +{0x84dd,0xff}, +{0x84de,0xad}, +{0x84df,0xf0}, +{0x84e0,0x22}, +{0x84e1,0xe4}, +{0x84e2,0xcc}, +{0x84e3,0xf8}, +{0x84e4,0x75}, +{0x84e5,0xf0}, +{0x84e6,0x08}, +{0x84e7,0xef}, +{0x84e8,0x2f}, +{0x84e9,0xff}, +{0x84ea,0xee}, +{0x84eb,0x33}, +{0x84ec,0xfe}, +{0x84ed,0xec}, +{0x84ee,0x33}, +{0x84ef,0xfc}, +{0x84f0,0xee}, +{0x84f1,0x9d}, +{0x84f2,0xec}, +{0x84f3,0x98}, +{0x84f4,0x40}, +{0x84f5,0x05}, +{0x84f6,0xfc}, +{0x84f7,0xee}, +{0x84f8,0x9d}, +{0x84f9,0xfe}, +{0x84fa,0x0f}, +{0x84fb,0xd5}, +{0x84fc,0xf0}, +{0x84fd,0xe9}, +{0x84fe,0xe4}, +{0x84ff,0xce}, +{0x8500,0xfd}, +{0x8501,0x22}, +{0x8502,0xed}, +{0x8503,0xf8}, +{0x8504,0xf5}, +{0x8505,0xf0}, +{0x8506,0xee}, +{0x8507,0x84}, +{0x8508,0x20}, +{0x8509,0xd2}, +{0x850a,0x1c}, +{0x850b,0xfe}, +{0x850c,0xad}, +{0x850d,0xf0}, +{0x850e,0x75}, +{0x850f,0xf0}, +{0x8510,0x08}, +{0x8511,0xef}, +{0x8512,0x2f}, +{0x8513,0xff}, +{0x8514,0xed}, +{0x8515,0x33}, +{0x8516,0xfd}, +{0x8517,0x40}, +{0x8518,0x07}, +{0x8519,0x98}, +{0x851a,0x50}, +{0x851b,0x06}, +{0x851c,0xd5}, +{0x851d,0xf0}, +{0x851e,0xf2}, +{0x851f,0x22}, +{0x8520,0xc3}, +{0x8521,0x98}, +{0x8522,0xfd}, +{0x8523,0x0f}, +{0x8524,0xd5}, +{0x8525,0xf0}, +{0x8526,0xea}, +{0x8527,0x22}, +{0x8528,0xe8}, +{0x8529,0x8f}, +{0x852a,0xf0}, +{0x852b,0xa4}, +{0x852c,0xcc}, +{0x852d,0x8b}, +{0x852e,0xf0}, +{0x852f,0xa4}, +{0x8530,0x2c}, +{0x8531,0xfc}, +{0x8532,0xe9}, +{0x8533,0x8e}, +{0x8534,0xf0}, +{0x8535,0xa4}, +{0x8536,0x2c}, +{0x8537,0xfc}, +{0x8538,0x8a}, +{0x8539,0xf0}, +{0x853a,0xed}, +{0x853b,0xa4}, +{0x853c,0x2c}, +{0x853d,0xfc}, +{0x853e,0xea}, +{0x853f,0x8e}, +{0x8540,0xf0}, +{0x8541,0xa4}, +{0x8542,0xcd}, +{0x8543,0xa8}, +{0x8544,0xf0}, +{0x8545,0x8b}, +{0x8546,0xf0}, +{0x8547,0xa4}, +{0x8548,0x2d}, +{0x8549,0xcc}, +{0x854a,0x38}, +{0x854b,0x25}, +{0x854c,0xf0}, +{0x854d,0xfd}, +{0x854e,0xe9}, +{0x854f,0x8f}, +{0x8550,0xf0}, +{0x8551,0xa4}, +{0x8552,0x2c}, +{0x8553,0xcd}, +{0x8554,0x35}, +{0x8555,0xf0}, +{0x8556,0xfc}, +{0x8557,0xeb}, +{0x8558,0x8e}, +{0x8559,0xf0}, +{0x855a,0xa4}, +{0x855b,0xfe}, +{0x855c,0xa9}, +{0x855d,0xf0}, +{0x855e,0xeb}, +{0x855f,0x8f}, +{0x8560,0xf0}, +{0x8561,0xa4}, +{0x8562,0xcf}, +{0x8563,0xc5}, +{0x8564,0xf0}, +{0x8565,0x2e}, +{0x8566,0xcd}, +{0x8567,0x39}, +{0x8568,0xfe}, +{0x8569,0xe4}, +{0x856a,0x3c}, +{0x856b,0xfc}, +{0x856c,0xea}, +{0x856d,0xa4}, +{0x856e,0x2d}, +{0x856f,0xce}, +{0x8570,0x35}, +{0x8571,0xf0}, +{0x8572,0xfd}, +{0x8573,0xe4}, +{0x8574,0x3c}, +{0x8575,0xfc}, +{0x8576,0x22}, +{0x8577,0x75}, +{0x8578,0xf0}, +{0x8579,0x08}, +{0x857a,0x75}, +{0x857b,0x82}, +{0x857c,0x00}, +{0x857d,0xef}, +{0x857e,0x2f}, +{0x857f,0xff}, +{0x8580,0xee}, +{0x8581,0x33}, +{0x8582,0xfe}, +{0x8583,0xcd}, +{0x8584,0x33}, +{0x8585,0xcd}, +{0x8586,0xcc}, +{0x8587,0x33}, +{0x8588,0xcc}, +{0x8589,0xc5}, +{0x858a,0x82}, +{0x858b,0x33}, +{0x858c,0xc5}, +{0x858d,0x82}, +{0x858e,0x9b}, +{0x858f,0xed}, +{0x8590,0x9a}, +{0x8591,0xec}, +{0x8592,0x99}, +{0x8593,0xe5}, +{0x8594,0x82}, +{0x8595,0x98}, +{0x8596,0x40}, +{0x8597,0x0c}, +{0x8598,0xf5}, +{0x8599,0x82}, +{0x859a,0xee}, +{0x859b,0x9b}, +{0x859c,0xfe}, +{0x859d,0xed}, +{0x859e,0x9a}, +{0x859f,0xfd}, +{0x85a0,0xec}, +{0x85a1,0x99}, +{0x85a2,0xfc}, +{0x85a3,0x0f}, +{0x85a4,0xd5}, +{0x85a5,0xf0}, +{0x85a6,0xd6}, +{0x85a7,0xe4}, +{0x85a8,0xce}, +{0x85a9,0xfb}, +{0x85aa,0xe4}, +{0x85ab,0xcd}, +{0x85ac,0xfa}, +{0x85ad,0xe4}, +{0x85ae,0xcc}, +{0x85af,0xf9}, +{0x85b0,0xa8}, +{0x85b1,0x82}, +{0x85b2,0x22}, +{0x85b3,0xb8}, +{0x85b4,0x00}, +{0x85b5,0xc1}, +{0x85b6,0xb9}, +{0x85b7,0x00}, +{0x85b8,0x59}, +{0x85b9,0xba}, +{0x85ba,0x00}, +{0x85bb,0x2d}, +{0x85bc,0xec}, +{0x85bd,0x8b}, +{0x85be,0xf0}, +{0x85bf,0x84}, +{0x85c0,0xcf}, +{0x85c1,0xce}, +{0x85c2,0xcd}, +{0x85c3,0xfc}, +{0x85c4,0xe5}, +{0x85c5,0xf0}, +{0x85c6,0xcb}, +{0x85c7,0xf9}, +{0x85c8,0x78}, +{0x85c9,0x18}, +{0x85ca,0xef}, +{0x85cb,0x2f}, +{0x85cc,0xff}, +{0x85cd,0xee}, +{0x85ce,0x33}, +{0x85cf,0xfe}, +{0x85d0,0xed}, +{0x85d1,0x33}, +{0x85d2,0xfd}, +{0x85d3,0xec}, +{0x85d4,0x33}, +{0x85d5,0xfc}, +{0x85d6,0xeb}, +{0x85d7,0x33}, +{0x85d8,0xfb}, +{0x85d9,0x10}, +{0x85da,0xd7}, +{0x85db,0x03}, +{0x85dc,0x99}, +{0x85dd,0x40}, +{0x85de,0x04}, +{0x85df,0xeb}, +{0x85e0,0x99}, +{0x85e1,0xfb}, +{0x85e2,0x0f}, +{0x85e3,0xd8}, +{0x85e4,0xe5}, +{0x85e5,0xe4}, +{0x85e6,0xf9}, +{0x85e7,0xfa}, +{0x85e8,0x22}, +{0x85e9,0x78}, +{0x85ea,0x18}, +{0x85eb,0xef}, +{0x85ec,0x2f}, +{0x85ed,0xff}, +{0x85ee,0xee}, +{0x85ef,0x33}, +{0x85f0,0xfe}, +{0x85f1,0xed}, +{0x85f2,0x33}, +{0x85f3,0xfd}, +{0x85f4,0xec}, +{0x85f5,0x33}, +{0x85f6,0xfc}, +{0x85f7,0xc9}, +{0x85f8,0x33}, +{0x85f9,0xc9}, +{0x85fa,0x10}, +{0x85fb,0xd7}, +{0x85fc,0x05}, +{0x85fd,0x9b}, +{0x85fe,0xe9}, +{0x85ff,0x9a}, +{0x8600,0x40}, +{0x8601,0x07}, +{0x8602,0xec}, +{0x8603,0x9b}, +{0x8604,0xfc}, +{0x8605,0xe9}, +{0x8606,0x9a}, +{0x8607,0xf9}, +{0x8608,0x0f}, +{0x8609,0xd8}, +{0x860a,0xe0}, +{0x860b,0xe4}, +{0x860c,0xc9}, +{0x860d,0xfa}, +{0x860e,0xe4}, +{0x860f,0xcc}, +{0x8610,0xfb}, +{0x8611,0x22}, +{0x8612,0x75}, +{0x8613,0xf0}, +{0x8614,0x10}, +{0x8615,0xef}, +{0x8616,0x2f}, +{0x8617,0xff}, +{0x8618,0xee}, +{0x8619,0x33}, +{0x861a,0xfe}, +{0x861b,0xed}, +{0x861c,0x33}, +{0x861d,0xfd}, +{0x861e,0xcc}, +{0x861f,0x33}, +{0x8620,0xcc}, +{0x8621,0xc8}, +{0x8622,0x33}, +{0x8623,0xc8}, +{0x8624,0x10}, +{0x8625,0xd7}, +{0x8626,0x07}, +{0x8627,0x9b}, +{0x8628,0xec}, +{0x8629,0x9a}, +{0x862a,0xe8}, +{0x862b,0x99}, +{0x862c,0x40}, +{0x862d,0x0a}, +{0x862e,0xed}, +{0x862f,0x9b}, +{0x8630,0xfd}, +{0x8631,0xec}, +{0x8632,0x9a}, +{0x8633,0xfc}, +{0x8634,0xe8}, +{0x8635,0x99}, +{0x8636,0xf8}, +{0x8637,0x0f}, +{0x8638,0xd5}, +{0x8639,0xf0}, +{0x863a,0xda}, +{0x863b,0xe4}, +{0x863c,0xcd}, +{0x863d,0xfb}, +{0x863e,0xe4}, +{0x863f,0xcc}, +{0x8640,0xfa}, +{0x8641,0xe4}, +{0x8642,0xc8}, +{0x8643,0xf9}, +{0x8644,0x22}, +{0x8645,0xeb}, +{0x8646,0x9f}, +{0x8647,0xf5}, +{0x8648,0xf0}, +{0x8649,0xea}, +{0x864a,0x9e}, +{0x864b,0x42}, +{0x864c,0xf0}, +{0x864d,0xe9}, +{0x864e,0x9d}, +{0x864f,0x42}, +{0x8650,0xf0}, +{0x8651,0xe8}, +{0x8652,0x9c}, +{0x8653,0x45}, +{0x8654,0xf0}, +{0x8655,0x22}, +{0x8656,0xe8}, +{0x8657,0x60}, +{0x8658,0x0f}, +{0x8659,0xec}, +{0x865a,0xc3}, +{0x865b,0x13}, +{0x865c,0xfc}, +{0x865d,0xed}, +{0x865e,0x13}, +{0x865f,0xfd}, +{0x8660,0xee}, +{0x8661,0x13}, +{0x8662,0xfe}, +{0x8663,0xef}, +{0x8664,0x13}, +{0x8665,0xff}, +{0x8666,0xd8}, +{0x8667,0xf1}, +{0x8668,0x22}, +{0x8669,0xe8}, +{0x866a,0x60}, +{0x866b,0x0f}, +{0x866c,0xef}, +{0x866d,0xc3}, +{0x866e,0x33}, +{0x866f,0xff}, +{0x8670,0xee}, +{0x8671,0x33}, +{0x8672,0xfe}, +{0x8673,0xed}, +{0x8674,0x33}, +{0x8675,0xfd}, +{0x8676,0xec}, +{0x8677,0x33}, +{0x8678,0xfc}, +{0x8679,0xd8}, +{0x867a,0xf1}, +{0x867b,0x22}, +{0x867c,0xe4}, +{0x867d,0x93}, +{0x867e,0xfc}, +{0x867f,0x74}, +{0x8680,0x01}, +{0x8681,0x93}, +{0x8682,0xfd}, +{0x8683,0x74}, +{0x8684,0x02}, +{0x8685,0x93}, +{0x8686,0xfe}, +{0x8687,0x74}, +{0x8688,0x03}, +{0x8689,0x93}, +{0x868a,0xff}, +{0x868b,0x22}, +{0x868c,0xe6}, +{0x868d,0xfb}, +{0x868e,0x08}, +{0x868f,0xe6}, +{0x8690,0xf9}, +{0x8691,0x08}, +{0x8692,0xe6}, +{0x8693,0xfa}, +{0x8694,0x08}, +{0x8695,0xe6}, +{0x8696,0xcb}, +{0x8697,0xf8}, +{0x8698,0x22}, +{0x8699,0xec}, +{0x869a,0xf6}, +{0x869b,0x08}, +{0x869c,0xed}, +{0x869d,0xf6}, +{0x869e,0x08}, +{0x869f,0xee}, +{0x86a0,0xf6}, +{0x86a1,0x08}, +{0x86a2,0xef}, +{0x86a3,0xf6}, +{0x86a4,0x22}, +{0x86a5,0xa4}, +{0x86a6,0x25}, +{0x86a7,0x82}, +{0x86a8,0xf5}, +{0x86a9,0x82}, +{0x86aa,0xe5}, +{0x86ab,0xf0}, +{0x86ac,0x35}, +{0x86ad,0x83}, +{0x86ae,0xf5}, +{0x86af,0x83}, +{0x86b0,0x22}, +{0x86b1,0xd0}, +{0x86b2,0x83}, +{0x86b3,0xd0}, +{0x86b4,0x82}, +{0x86b5,0xf8}, +{0x86b6,0xe4}, +{0x86b7,0x93}, +{0x86b8,0x70}, +{0x86b9,0x12}, +{0x86ba,0x74}, +{0x86bb,0x01}, +{0x86bc,0x93}, +{0x86bd,0x70}, +{0x86be,0x0d}, +{0x86bf,0xa3}, +{0x86c0,0xa3}, +{0x86c1,0x93}, +{0x86c2,0xf8}, +{0x86c3,0x74}, +{0x86c4,0x01}, +{0x86c5,0x93}, +{0x86c6,0xf5}, +{0x86c7,0x82}, +{0x86c8,0x88}, +{0x86c9,0x83}, +{0x86ca,0xe4}, +{0x86cb,0x73}, +{0x86cc,0x74}, +{0x86cd,0x02}, +{0x86ce,0x93}, +{0x86cf,0x68}, +{0x86d0,0x60}, +{0x86d1,0xef}, +{0x86d2,0xa3}, +{0x86d3,0xa3}, +{0x86d4,0xa3}, +{0x86d5,0x80}, +{0x86d6,0xdf}, +{0x86d7,0x90}, +{0x86d8,0x38}, +{0x86d9,0x04}, +{0x86da,0x78}, +{0x86db,0x52}, +{0x86dc,0x12}, +{0x86dd,0x0b}, +{0x86de,0xfd}, +{0x86df,0x90}, +{0x86e0,0x38}, +{0x86e1,0x00}, +{0x86e2,0xe0}, +{0x86e3,0xfe}, +{0x86e4,0xa3}, +{0x86e5,0xe0}, +{0x86e6,0xfd}, +{0x86e7,0xed}, +{0x86e8,0xff}, +{0x86e9,0xc3}, +{0x86ea,0x12}, +{0x86eb,0x0b}, +{0x86ec,0x9e}, +{0x86ed,0x90}, +{0x86ee,0x38}, +{0x86ef,0x10}, +{0x86f0,0x12}, +{0x86f1,0x0b}, +{0x86f2,0x92}, +{0x86f3,0x90}, +{0x86f4,0x38}, +{0x86f5,0x06}, +{0x86f6,0x78}, +{0x86f7,0x54}, +{0x86f8,0x12}, +{0x86f9,0x0b}, +{0x86fa,0xfd}, +{0x86fb,0x90}, +{0x86fc,0x38}, +{0x86fd,0x02}, +{0x86fe,0xe0}, +{0x86ff,0xfe}, +{0x8700,0xa3}, +{0x8701,0xe0}, +{0x8702,0xfd}, +{0x8703,0xed}, +{0x8704,0xff}, +{0x8705,0xc3}, +{0x8706,0x12}, +{0x8707,0x0b}, +{0x8708,0x9e}, +{0x8709,0x90}, +{0x870a,0x38}, +{0x870b,0x12}, +{0x870c,0x12}, +{0x870d,0x0b}, +{0x870e,0x92}, +{0x870f,0xa3}, +{0x8710,0xe0}, +{0x8711,0xb4}, +{0x8712,0x31}, +{0x8713,0x07}, +{0x8714,0x78}, +{0x8715,0x52}, +{0x8716,0x79}, +{0x8717,0x52}, +{0x8718,0x12}, +{0x8719,0x0c}, +{0x871a,0x13}, +{0x871b,0x90}, +{0x871c,0x38}, +{0x871d,0x14}, +{0x871e,0xe0}, +{0x871f,0xb4}, +{0x8720,0x71}, +{0x8721,0x15}, +{0x8722,0x78}, +{0x8723,0x52}, +{0x8724,0xe6}, +{0x8725,0xfe}, +{0x8726,0x08}, +{0x8727,0xe6}, +{0x8728,0x78}, +{0x8729,0x02}, +{0x872a,0xce}, +{0x872b,0xc3}, +{0x872c,0x13}, +{0x872d,0xce}, +{0x872e,0x13}, +{0x872f,0xd8}, +{0x8730,0xf9}, +{0x8731,0x79}, +{0x8732,0x53}, +{0x8733,0xf7}, +{0x8734,0xee}, +{0x8735,0x19}, +{0x8736,0xf7}, +{0x8737,0x90}, +{0x8738,0x38}, +{0x8739,0x15}, +{0x873a,0xe0}, +{0x873b,0xb4}, +{0x873c,0x31}, +{0x873d,0x07}, +{0x873e,0x78}, +{0x873f,0x54}, +{0x8740,0x79}, +{0x8741,0x54}, +{0x8742,0x12}, +{0x8743,0x0c}, +{0x8744,0x13}, +{0x8745,0x90}, +{0x8746,0x38}, +{0x8747,0x15}, +{0x8748,0xe0}, +{0x8749,0xb4}, +{0x874a,0x71}, +{0x874b,0x15}, +{0x874c,0x78}, +{0x874d,0x54}, +{0x874e,0xe6}, +{0x874f,0xfe}, +{0x8750,0x08}, +{0x8751,0xe6}, +{0x8752,0x78}, +{0x8753,0x02}, +{0x8754,0xce}, +{0x8755,0xc3}, +{0x8756,0x13}, +{0x8757,0xce}, +{0x8758,0x13}, +{0x8759,0xd8}, +{0x875a,0xf9}, +{0x875b,0x79}, +{0x875c,0x55}, +{0x875d,0xf7}, +{0x875e,0xee}, +{0x875f,0x19}, +{0x8760,0xf7}, +{0x8761,0x79}, +{0x8762,0x52}, +{0x8763,0x12}, +{0x8764,0x0b}, +{0x8765,0xd9}, +{0x8766,0x09}, +{0x8767,0x12}, +{0x8768,0x0b}, +{0x8769,0xd9}, +{0x876a,0xaf}, +{0x876b,0x47}, +{0x876c,0x12}, +{0x876d,0x0b}, +{0x876e,0xb2}, +{0x876f,0xe5}, +{0x8770,0x44}, +{0x8771,0xfb}, +{0x8772,0x7a}, +{0x8773,0x00}, +{0x8774,0xfd}, +{0x8775,0x7c}, +{0x8776,0x00}, +{0x8777,0x12}, +{0x8778,0x04}, +{0x8779,0xd3}, +{0x877a,0x78}, +{0x877b,0x5a}, +{0x877c,0xa6}, +{0x877d,0x06}, +{0x877e,0x08}, +{0x877f,0xa6}, +{0x8780,0x07}, +{0x8781,0xaf}, +{0x8782,0x45}, +{0x8783,0x12}, +{0x8784,0x0b}, +{0x8785,0xb2}, +{0x8786,0xad}, +{0x8787,0x03}, +{0x8788,0x7c}, +{0x8789,0x00}, +{0x878a,0x12}, +{0x878b,0x04}, +{0x878c,0xd3}, +{0x878d,0x78}, +{0x878e,0x56}, +{0x878f,0xa6}, +{0x8790,0x06}, +{0x8791,0x08}, +{0x8792,0xa6}, +{0x8793,0x07}, +{0x8794,0xaf}, +{0x8795,0x48}, +{0x8796,0x78}, +{0x8797,0x54}, +{0x8798,0x12}, +{0x8799,0x0b}, +{0x879a,0xb4}, +{0x879b,0xe5}, +{0x879c,0x43}, +{0x879d,0xfb}, +{0x879e,0xfd}, +{0x879f,0x7c}, +{0x87a0,0x00}, +{0x87a1,0x12}, +{0x87a2,0x04}, +{0x87a3,0xd3}, +{0x87a4,0x78}, +{0x87a5,0x5c}, +{0x87a6,0xa6}, +{0x87a7,0x06}, +{0x87a8,0x08}, +{0x87a9,0xa6}, +{0x87aa,0x07}, +{0x87ab,0xaf}, +{0x87ac,0x46}, +{0x87ad,0x7e}, +{0x87ae,0x00}, +{0x87af,0x78}, +{0x87b0,0x54}, +{0x87b1,0x12}, +{0x87b2,0x0b}, +{0x87b3,0xb6}, +{0x87b4,0xad}, +{0x87b5,0x03}, +{0x87b6,0x7c}, +{0x87b7,0x00}, +{0x87b8,0x12}, +{0x87b9,0x04}, +{0x87ba,0xd3}, +{0x87bb,0x78}, +{0x87bc,0x58}, +{0x87bd,0xa6}, +{0x87be,0x06}, +{0x87bf,0x08}, +{0x87c0,0xa6}, +{0x87c1,0x07}, +{0x87c2,0xc3}, +{0x87c3,0x78}, +{0x87c4,0x5b}, +{0x87c5,0xe6}, +{0x87c6,0x94}, +{0x87c7,0x08}, +{0x87c8,0x18}, +{0x87c9,0xe6}, +{0x87ca,0x94}, +{0x87cb,0x00}, +{0x87cc,0x50}, +{0x87cd,0x05}, +{0x87ce,0x76}, +{0x87cf,0x00}, +{0x87d0,0x08}, +{0x87d1,0x76}, +{0x87d2,0x08}, +{0x87d3,0xc3}, +{0x87d4,0x78}, +{0x87d5,0x5d}, +{0x87d6,0xe6}, +{0x87d7,0x94}, +{0x87d8,0x08}, +{0x87d9,0x18}, +{0x87da,0xe6}, +{0x87db,0x94}, +{0x87dc,0x00}, +{0x87dd,0x50}, +{0x87de,0x05}, +{0x87df,0x76}, +{0x87e0,0x00}, +{0x87e1,0x08}, +{0x87e2,0x76}, +{0x87e3,0x08}, +{0x87e4,0x78}, +{0x87e5,0x5a}, +{0x87e6,0x12}, +{0x87e7,0x0b}, +{0x87e8,0xc6}, +{0x87e9,0xff}, +{0x87ea,0xd3}, +{0x87eb,0x78}, +{0x87ec,0x57}, +{0x87ed,0xe6}, +{0x87ee,0x9f}, +{0x87ef,0x18}, +{0x87f0,0xe6}, +{0x87f1,0x9e}, +{0x87f2,0x40}, +{0x87f3,0x0e}, +{0x87f4,0x78}, +{0x87f5,0x5a}, +{0x87f6,0xe6}, +{0x87f7,0x13}, +{0x87f8,0xfe}, +{0x87f9,0x08}, +{0x87fa,0xe6}, +{0x87fb,0x78}, +{0x87fc,0x57}, +{0x87fd,0x12}, +{0x87fe,0x0c}, +{0x87ff,0x08}, +{0x8800,0x80}, +{0x8801,0x04}, +{0x8802,0x7e}, +{0x8803,0x00}, +{0x8804,0x7f}, +{0x8805,0x00}, +{0x8806,0x78}, +{0x8807,0x5e}, +{0x8808,0x12}, +{0x8809,0x0b}, +{0x880a,0xbe}, +{0x880b,0xff}, +{0x880c,0xd3}, +{0x880d,0x78}, +{0x880e,0x59}, +{0x880f,0xe6}, +{0x8810,0x9f}, +{0x8811,0x18}, +{0x8812,0xe6}, +{0x8813,0x9e}, +{0x8814,0x40}, +{0x8815,0x0e}, +{0x8816,0x78}, +{0x8817,0x5c}, +{0x8818,0xe6}, +{0x8819,0x13}, +{0x881a,0xfe}, +{0x881b,0x08}, +{0x881c,0xe6}, +{0x881d,0x78}, +{0x881e,0x59}, +{0x881f,0x12}, +{0x8820,0x0c}, +{0x8821,0x08}, +{0x8822,0x80}, +{0x8823,0x04}, +{0x8824,0x7e}, +{0x8825,0x00}, +{0x8826,0x7f}, +{0x8827,0x00}, +{0x8828,0xe4}, +{0x8829,0xfc}, +{0x882a,0xfd}, +{0x882b,0x78}, +{0x882c,0x62}, +{0x882d,0x12}, +{0x882e,0x06}, +{0x882f,0x99}, +{0x8830,0x78}, +{0x8831,0x5a}, +{0x8832,0x12}, +{0x8833,0x0b}, +{0x8834,0xc6}, +{0x8835,0x78}, +{0x8836,0x57}, +{0x8837,0x26}, +{0x8838,0xff}, +{0x8839,0xee}, +{0x883a,0x18}, +{0x883b,0x36}, +{0x883c,0xfe}, +{0x883d,0x78}, +{0x883e,0x66}, +{0x883f,0x12}, +{0x8840,0x0b}, +{0x8841,0xbe}, +{0x8842,0x78}, +{0x8843,0x59}, +{0x8844,0x26}, +{0x8845,0xff}, +{0x8846,0xee}, +{0x8847,0x18}, +{0x8848,0x36}, +{0x8849,0xfe}, +{0x884a,0xe4}, +{0x884b,0xfc}, +{0x884c,0xfd}, +{0x884d,0x78}, +{0x884e,0x6a}, +{0x884f,0x12}, +{0x8850,0x06}, +{0x8851,0x99}, +{0x8852,0x12}, +{0x8853,0x0b}, +{0x8854,0xce}, +{0x8855,0x78}, +{0x8856,0x66}, +{0x8857,0x12}, +{0x8858,0x06}, +{0x8859,0x8c}, +{0x885a,0xd3}, +{0x885b,0x12}, +{0x885c,0x06}, +{0x885d,0x45}, +{0x885e,0x40}, +{0x885f,0x08}, +{0x8860,0x12}, +{0x8861,0x0b}, +{0x8862,0xce}, +{0x8863,0x78}, +{0x8864,0x66}, +{0x8865,0x12}, +{0x8866,0x06}, +{0x8867,0x99}, +{0x8868,0x78}, +{0x8869,0x54}, +{0x886a,0x12}, +{0x886b,0x0b}, +{0x886c,0xd0}, +{0x886d,0x78}, +{0x886e,0x6a}, +{0x886f,0x12}, +{0x8870,0x06}, +{0x8871,0x8c}, +{0x8872,0xd3}, +{0x8873,0x12}, +{0x8874,0x06}, +{0x8875,0x45}, +{0x8876,0x40}, +{0x8877,0x0a}, +{0x8878,0x78}, +{0x8879,0x54}, +{0x887a,0x12}, +{0x887b,0x0b}, +{0x887c,0xd0}, +{0x887d,0x78}, +{0x887e,0x6a}, +{0x887f,0x12}, +{0x8880,0x06}, +{0x8881,0x99}, +{0x8882,0x78}, +{0x8883,0x61}, +{0x8884,0xe6}, +{0x8885,0x90}, +{0x8886,0x60}, +{0x8887,0x01}, +{0x8888,0xf0}, +{0x8889,0x78}, +{0x888a,0x65}, +{0x888b,0xe6}, +{0x888c,0xa3}, +{0x888d,0xf0}, +{0x888e,0x78}, +{0x888f,0x69}, +{0x8890,0xe6}, +{0x8891,0xa3}, +{0x8892,0xf0}, +{0x8893,0x78}, +{0x8894,0x55}, +{0x8895,0xe6}, +{0x8896,0xa3}, +{0x8897,0xf0}, +{0x8898,0x7d}, +{0x8899,0x01}, +{0x889a,0x78}, +{0x889b,0x61}, +{0x889c,0x12}, +{0x889d,0x0b}, +{0x889e,0xe9}, +{0x889f,0x24}, +{0x88a0,0x01}, +{0x88a1,0x12}, +{0x88a2,0x0b}, +{0x88a3,0xa6}, +{0x88a4,0x78}, +{0x88a5,0x65}, +{0x88a6,0x12}, +{0x88a7,0x0b}, +{0x88a8,0xe9}, +{0x88a9,0x24}, +{0x88aa,0x02}, +{0x88ab,0x12}, +{0x88ac,0x0b}, +{0x88ad,0xa6}, +{0x88ae,0x78}, +{0x88af,0x69}, +{0x88b0,0x12}, +{0x88b1,0x0b}, +{0x88b2,0xe9}, +{0x88b3,0x24}, +{0x88b4,0x03}, +{0x88b5,0x12}, +{0x88b6,0x0b}, +{0x88b7,0xa6}, +{0x88b8,0x78}, +{0x88b9,0x6d}, +{0x88ba,0x12}, +{0x88bb,0x0b}, +{0x88bc,0xe9}, +{0x88bd,0x24}, +{0x88be,0x04}, +{0x88bf,0x12}, +{0x88c0,0x0b}, +{0x88c1,0xa6}, +{0x88c2,0x0d}, +{0x88c3,0xbd}, +{0x88c4,0x05}, +{0x88c5,0xd4}, +{0x88c6,0xc2}, +{0x88c7,0x0e}, +{0x88c8,0xc2}, +{0x88c9,0x06}, +{0x88ca,0x22}, +{0x88cb,0x85}, +{0x88cc,0x08}, +{0x88cd,0x41}, +{0x88ce,0x90}, +{0x88cf,0x30}, +{0x88d0,0x24}, +{0x88d1,0xe0}, +{0x88d2,0xf5}, +{0x88d3,0x3d}, +{0x88d4,0xa3}, +{0x88d5,0xe0}, +{0x88d6,0xf5}, +{0x88d7,0x3e}, +{0x88d8,0xa3}, +{0x88d9,0xe0}, +{0x88da,0xf5}, +{0x88db,0x3f}, +{0x88dc,0xa3}, +{0x88dd,0xe0}, +{0x88de,0xf5}, +{0x88df,0x40}, +{0x88e0,0xa3}, +{0x88e1,0xe0}, +{0x88e2,0xf5}, +{0x88e3,0x3c}, +{0x88e4,0xd2}, +{0x88e5,0x34}, +{0x88e6,0xe5}, +{0x88e7,0x41}, +{0x88e8,0x12}, +{0x88e9,0x06}, +{0x88ea,0xb1}, +{0x88eb,0x09}, +{0x88ec,0x31}, +{0x88ed,0x03}, +{0x88ee,0x09}, +{0x88ef,0x35}, +{0x88f0,0x04}, +{0x88f1,0x09}, +{0x88f2,0x3b}, +{0x88f3,0x05}, +{0x88f4,0x09}, +{0x88f5,0x3e}, +{0x88f6,0x06}, +{0x88f7,0x09}, +{0x88f8,0x41}, +{0x88f9,0x07}, +{0x88fa,0x09}, +{0x88fb,0x4a}, +{0x88fc,0x08}, +{0x88fd,0x09}, +{0x88fe,0x5b}, +{0x88ff,0x12}, +{0x8900,0x09}, +{0x8901,0x73}, +{0x8902,0x18}, +{0x8903,0x09}, +{0x8904,0x89}, +{0x8905,0x19}, +{0x8906,0x09}, +{0x8907,0x5e}, +{0x8908,0x1a}, +{0x8909,0x09}, +{0x890a,0x6a}, +{0x890b,0x1b}, +{0x890c,0x09}, +{0x890d,0xad}, +{0x890e,0x80}, +{0x890f,0x09}, +{0x8910,0xb2}, +{0x8911,0x81}, +{0x8912,0x0a}, +{0x8913,0x1d}, +{0x8914,0x8f}, +{0x8915,0x0a}, +{0x8916,0x09}, +{0x8917,0x90}, +{0x8918,0x0a}, +{0x8919,0x1d}, +{0x891a,0x91}, +{0x891b,0x0a}, +{0x891c,0x1d}, +{0x891d,0x92}, +{0x891e,0x0a}, +{0x891f,0x1d}, +{0x8920,0x93}, +{0x8921,0x0a}, +{0x8922,0x1d}, +{0x8923,0x94}, +{0x8924,0x0a}, +{0x8925,0x1d}, +{0x8926,0x98}, +{0x8927,0x0a}, +{0x8928,0x17}, +{0x8929,0x9f}, +{0x892a,0x0a}, +{0x892b,0x1a}, +{0x892c,0xec}, +{0x892d,0x00}, +{0x892e,0x00}, +{0x892f,0x0a}, +{0x8930,0x38}, +{0x8931,0x12}, +{0x8932,0x0f}, +{0x8933,0x74}, +{0x8934,0x22}, +{0x8935,0x12}, +{0x8936,0x0f}, +{0x8937,0x74}, +{0x8938,0xd2}, +{0x8939,0x03}, +{0x893a,0x22}, +{0x893b,0xd2}, +{0x893c,0x03}, +{0x893d,0x22}, +{0x893e,0xc2}, +{0x893f,0x03}, +{0x8940,0x22}, +{0x8941,0xa2}, +{0x8942,0x37}, +{0x8943,0xe4}, +{0x8944,0x33}, +{0x8945,0xf5}, +{0x8946,0x3c}, +{0x8947,0x02}, +{0x8948,0x0a}, +{0x8949,0x1d}, +{0x894a,0xc2}, +{0x894b,0x01}, +{0x894c,0xc2}, +{0x894d,0x02}, +{0x894e,0xc2}, +{0x894f,0x03}, +{0x8950,0x12}, +{0x8951,0x0d}, +{0x8952,0x0d}, +{0x8953,0x75}, +{0x8954,0x1e}, +{0x8955,0x70}, +{0x8956,0xd2}, +{0x8957,0x35}, +{0x8958,0x02}, +{0x8959,0x0a}, +{0x895a,0x1d}, +{0x895b,0x02}, +{0x895c,0x0a}, +{0x895d,0x04}, +{0x895e,0x85}, +{0x895f,0x40}, +{0x8960,0x4a}, +{0x8961,0x85}, +{0x8962,0x3c}, +{0x8963,0x4b}, +{0x8964,0x12}, +{0x8965,0x0a}, +{0x8966,0xff}, +{0x8967,0x02}, +{0x8968,0x0a}, +{0x8969,0x1d}, +{0x896a,0x85}, +{0x896b,0x4a}, +{0x896c,0x40}, +{0x896d,0x85}, +{0x896e,0x4b}, +{0x896f,0x3c}, +{0x8970,0x02}, +{0x8971,0x0a}, +{0x8972,0x1d}, +{0x8973,0xe4}, +{0x8974,0xf5}, +{0x8975,0x22}, +{0x8976,0xf5}, +{0x8977,0x23}, +{0x8978,0x85}, +{0x8979,0x40}, +{0x897a,0x31}, +{0x897b,0x85}, +{0x897c,0x3f}, +{0x897d,0x30}, +{0x897e,0x85}, +{0x897f,0x3e}, +{0x8980,0x2f}, +{0x8981,0x85}, +{0x8982,0x3d}, +{0x8983,0x2e}, +{0x8984,0x12}, +{0x8985,0x0f}, +{0x8986,0x46}, +{0x8987,0x80}, +{0x8988,0x1f}, +{0x8989,0x75}, +{0x898a,0x22}, +{0x898b,0x00}, +{0x898c,0x75}, +{0x898d,0x23}, +{0x898e,0x01}, +{0x898f,0x74}, +{0x8990,0xff}, +{0x8991,0xf5}, +{0x8992,0x2d}, +{0x8993,0xf5}, +{0x8994,0x2c}, +{0x8995,0xf5}, +{0x8996,0x2b}, +{0x8997,0xf5}, +{0x8998,0x2a}, +{0x8999,0x12}, +{0x899a,0x0f}, +{0x899b,0x46}, +{0x899c,0x85}, +{0x899d,0x2d}, +{0x899e,0x40}, +{0x899f,0x85}, +{0x89a0,0x2c}, +{0x89a1,0x3f}, +{0x89a2,0x85}, +{0x89a3,0x2b}, +{0x89a4,0x3e}, +{0x89a5,0x85}, +{0x89a6,0x2a}, +{0x89a7,0x3d}, +{0x89a8,0xe4}, +{0x89a9,0xf5}, +{0x89aa,0x3c}, +{0x89ab,0x80}, +{0x89ac,0x70}, +{0x89ad,0x12}, +{0x89ae,0x0f}, +{0x89af,0x16}, +{0x89b0,0x80}, +{0x89b1,0x6b}, +{0x89b2,0x85}, +{0x89b3,0x3d}, +{0x89b4,0x45}, +{0x89b5,0x85}, +{0x89b6,0x3e}, +{0x89b7,0x46}, +{0x89b8,0xe5}, +{0x89b9,0x47}, +{0x89ba,0xc3}, +{0x89bb,0x13}, +{0x89bc,0xff}, +{0x89bd,0xe5}, +{0x89be,0x45}, +{0x89bf,0xc3}, +{0x89c0,0x9f}, +{0x89c1,0x50}, +{0x89c2,0x02}, +{0x89c3,0x8f}, +{0x89c4,0x45}, +{0x89c5,0xe5}, +{0x89c6,0x48}, +{0x89c7,0xc3}, +{0x89c8,0x13}, +{0x89c9,0xff}, +{0x89ca,0xe5}, +{0x89cb,0x46}, +{0x89cc,0xc3}, +{0x89cd,0x9f}, +{0x89ce,0x50}, +{0x89cf,0x02}, +{0x89d0,0x8f}, +{0x89d1,0x46}, +{0x89d2,0xe5}, +{0x89d3,0x47}, +{0x89d4,0xc3}, +{0x89d5,0x13}, +{0x89d6,0xff}, +{0x89d7,0xfd}, +{0x89d8,0xe5}, +{0x89d9,0x45}, +{0x89da,0x2d}, +{0x89db,0xfd}, +{0x89dc,0xe4}, +{0x89dd,0x33}, +{0x89de,0xfc}, +{0x89df,0xe5}, +{0x89e0,0x44}, +{0x89e1,0x12}, +{0x89e2,0x0f}, +{0x89e3,0x90}, +{0x89e4,0x40}, +{0x89e5,0x05}, +{0x89e6,0xe5}, +{0x89e7,0x44}, +{0x89e8,0x9f}, +{0x89e9,0xf5}, +{0x89ea,0x45}, +{0x89eb,0xe5}, +{0x89ec,0x48}, +{0x89ed,0xc3}, +{0x89ee,0x13}, +{0x89ef,0xff}, +{0x89f0,0xfd}, +{0x89f1,0xe5}, +{0x89f2,0x46}, +{0x89f3,0x2d}, +{0x89f4,0xfd}, +{0x89f5,0xe4}, +{0x89f6,0x33}, +{0x89f7,0xfc}, +{0x89f8,0xe5}, +{0x89f9,0x43}, +{0x89fa,0x12}, +{0x89fb,0x0f}, +{0x89fc,0x90}, +{0x89fd,0x40}, +{0x89fe,0x05}, +{0x89ff,0xe5}, +{0x8a00,0x43}, +{0x8a01,0x9f}, +{0x8a02,0xf5}, +{0x8a03,0x46}, +{0x8a04,0x12}, +{0x8a05,0x06}, +{0x8a06,0xd7}, +{0x8a07,0x80}, +{0x8a08,0x14}, +{0x8a09,0x85}, +{0x8a0a,0x40}, +{0x8a0b,0x48}, +{0x8a0c,0x85}, +{0x8a0d,0x3f}, +{0x8a0e,0x47}, +{0x8a0f,0x85}, +{0x8a10,0x3e}, +{0x8a11,0x46}, +{0x8a12,0x85}, +{0x8a13,0x3d}, +{0x8a14,0x45}, +{0x8a15,0x80}, +{0x8a16,0x06}, +{0x8a17,0x02}, +{0x8a18,0x06}, +{0x8a19,0xd7}, +{0x8a1a,0x12}, +{0x8a1b,0x0d}, +{0x8a1c,0x7e}, +{0x8a1d,0x90}, +{0x8a1e,0x30}, +{0x8a1f,0x24}, +{0x8a20,0xe5}, +{0x8a21,0x3d}, +{0x8a22,0xf0}, +{0x8a23,0xa3}, +{0x8a24,0xe5}, +{0x8a25,0x3e}, +{0x8a26,0xf0}, +{0x8a27,0xa3}, +{0x8a28,0xe5}, +{0x8a29,0x3f}, +{0x8a2a,0xf0}, +{0x8a2b,0xa3}, +{0x8a2c,0xe5}, +{0x8a2d,0x40}, +{0x8a2e,0xf0}, +{0x8a2f,0xa3}, +{0x8a30,0xe5}, +{0x8a31,0x3c}, +{0x8a32,0xf0}, +{0x8a33,0x90}, +{0x8a34,0x30}, +{0x8a35,0x23}, +{0x8a36,0xe4}, +{0x8a37,0xf0}, +{0x8a38,0x22}, +{0x8a39,0xc0}, +{0x8a3a,0xe0}, +{0x8a3b,0xc0}, +{0x8a3c,0x83}, +{0x8a3d,0xc0}, +{0x8a3e,0x82}, +{0x8a3f,0xc0}, +{0x8a40,0xd0}, +{0x8a41,0x90}, +{0x8a42,0x3f}, +{0x8a43,0x0c}, +{0x8a44,0xe0}, +{0x8a45,0xf5}, +{0x8a46,0x32}, +{0x8a47,0xe5}, +{0x8a48,0x32}, +{0x8a49,0x30}, +{0x8a4a,0xe3}, +{0x8a4b,0x74}, +{0x8a4c,0x30}, +{0x8a4d,0x36}, +{0x8a4e,0x66}, +{0x8a4f,0x90}, +{0x8a50,0x60}, +{0x8a51,0x19}, +{0x8a52,0xe0}, +{0x8a53,0xf5}, +{0x8a54,0x0a}, +{0x8a55,0xa3}, +{0x8a56,0xe0}, +{0x8a57,0xf5}, +{0x8a58,0x0b}, +{0x8a59,0x90}, +{0x8a5a,0x60}, +{0x8a5b,0x1d}, +{0x8a5c,0xe0}, +{0x8a5d,0xf5}, +{0x8a5e,0x14}, +{0x8a5f,0xa3}, +{0x8a60,0xe0}, +{0x8a61,0xf5}, +{0x8a62,0x15}, +{0x8a63,0x90}, +{0x8a64,0x60}, +{0x8a65,0x21}, +{0x8a66,0xe0}, +{0x8a67,0xf5}, +{0x8a68,0x0c}, +{0x8a69,0xa3}, +{0x8a6a,0xe0}, +{0x8a6b,0xf5}, +{0x8a6c,0x0d}, +{0x8a6d,0x90}, +{0x8a6e,0x60}, +{0x8a6f,0x29}, +{0x8a70,0xe0}, +{0x8a71,0xf5}, +{0x8a72,0x0e}, +{0x8a73,0xa3}, +{0x8a74,0xe0}, +{0x8a75,0xf5}, +{0x8a76,0x0f}, +{0x8a77,0x90}, +{0x8a78,0x60}, +{0x8a79,0x31}, +{0x8a7a,0xe0}, +{0x8a7b,0xf5}, +{0x8a7c,0x10}, +{0x8a7d,0xa3}, +{0x8a7e,0xe0}, +{0x8a7f,0xf5}, +{0x8a80,0x11}, +{0x8a81,0x90}, +{0x8a82,0x60}, +{0x8a83,0x39}, +{0x8a84,0xe0}, +{0x8a85,0xf5}, +{0x8a86,0x12}, +{0x8a87,0xa3}, +{0x8a88,0xe0}, +{0x8a89,0xf5}, +{0x8a8a,0x13}, +{0x8a8b,0x30}, +{0x8a8c,0x01}, +{0x8a8d,0x06}, +{0x8a8e,0x30}, +{0x8a8f,0x33}, +{0x8a90,0x03}, +{0x8a91,0xd3}, +{0x8a92,0x80}, +{0x8a93,0x01}, +{0x8a94,0xc3}, +{0x8a95,0x92}, +{0x8a96,0x09}, +{0x8a97,0x30}, +{0x8a98,0x02}, +{0x8a99,0x06}, +{0x8a9a,0x30}, +{0x8a9b,0x33}, +{0x8a9c,0x03}, +{0x8a9d,0xd3}, +{0x8a9e,0x80}, +{0x8a9f,0x01}, +{0x8aa0,0xc3}, +{0x8aa1,0x92}, +{0x8aa2,0x0a}, +{0x8aa3,0x30}, +{0x8aa4,0x33}, +{0x8aa5,0x0c}, +{0x8aa6,0x30}, +{0x8aa7,0x03}, +{0x8aa8,0x09}, +{0x8aa9,0x20}, +{0x8aaa,0x02}, +{0x8aab,0x06}, +{0x8aac,0x20}, +{0x8aad,0x01}, +{0x8aae,0x03}, +{0x8aaf,0xd3}, +{0x8ab0,0x80}, +{0x8ab1,0x01}, +{0x8ab2,0xc3}, +{0x8ab3,0x92}, +{0x8ab4,0x0b}, +{0x8ab5,0x90}, +{0x8ab6,0x30}, +{0x8ab7,0x01}, +{0x8ab8,0xe0}, +{0x8ab9,0x44}, +{0x8aba,0x40}, +{0x8abb,0xf0}, +{0x8abc,0xe0}, +{0x8abd,0x54}, +{0x8abe,0xbf}, +{0x8abf,0xf0}, +{0x8ac0,0xe5}, +{0x8ac1,0x32}, +{0x8ac2,0x30}, +{0x8ac3,0xe1}, +{0x8ac4,0x14}, +{0x8ac5,0x30}, +{0x8ac6,0x34}, +{0x8ac7,0x11}, +{0x8ac8,0x90}, +{0x8ac9,0x30}, +{0x8aca,0x22}, +{0x8acb,0xe0}, +{0x8acc,0xf5}, +{0x8acd,0x08}, +{0x8ace,0xe4}, +{0x8acf,0xf0}, +{0x8ad0,0x30}, +{0x8ad1,0x00}, +{0x8ad2,0x03}, +{0x8ad3,0xd3}, +{0x8ad4,0x80}, +{0x8ad5,0x01}, +{0x8ad6,0xc3}, +{0x8ad7,0x92}, +{0x8ad8,0x08}, +{0x8ad9,0xe5}, +{0x8ada,0x32}, +{0x8adb,0x30}, +{0x8adc,0xe5}, +{0x8add,0x12}, +{0x8ade,0x90}, +{0x8adf,0x56}, +{0x8ae0,0xa1}, +{0x8ae1,0xe0}, +{0x8ae2,0xf5}, +{0x8ae3,0x09}, +{0x8ae4,0x30}, +{0x8ae5,0x31}, +{0x8ae6,0x09}, +{0x8ae7,0x30}, +{0x8ae8,0x05}, +{0x8ae9,0x03}, +{0x8aea,0xd3}, +{0x8aeb,0x80}, +{0x8aec,0x01}, +{0x8aed,0xc3}, +{0x8aee,0x92}, +{0x8aef,0x0d}, +{0x8af0,0x90}, +{0x8af1,0x3f}, +{0x8af2,0x0c}, +{0x8af3,0xe5}, +{0x8af4,0x32}, +{0x8af5,0xf0}, +{0x8af6,0xd0}, +{0x8af7,0xd0}, +{0x8af8,0xd0}, +{0x8af9,0x82}, +{0x8afa,0xd0}, +{0x8afb,0x83}, +{0x8afc,0xd0}, +{0x8afd,0xe0}, +{0x8afe,0x32}, +{0x8aff,0x90}, +{0x8b00,0x0e}, +{0x8b01,0x7e}, +{0x8b02,0xe4}, +{0x8b03,0x93}, +{0x8b04,0xfe}, +{0x8b05,0x74}, +{0x8b06,0x01}, +{0x8b07,0x93}, +{0x8b08,0xff}, +{0x8b09,0xc3}, +{0x8b0a,0x90}, +{0x8b0b,0x0e}, +{0x8b0c,0x7c}, +{0x8b0d,0x74}, +{0x8b0e,0x01}, +{0x8b0f,0x93}, +{0x8b10,0x9f}, +{0x8b11,0xff}, +{0x8b12,0xe4}, +{0x8b13,0x93}, +{0x8b14,0x9e}, +{0x8b15,0xfe}, +{0x8b16,0xe4}, +{0x8b17,0x8f}, +{0x8b18,0x3b}, +{0x8b19,0x8e}, +{0x8b1a,0x3a}, +{0x8b1b,0xf5}, +{0x8b1c,0x39}, +{0x8b1d,0xf5}, +{0x8b1e,0x38}, +{0x8b1f,0xab}, +{0x8b20,0x3b}, +{0x8b21,0xaa}, +{0x8b22,0x3a}, +{0x8b23,0xa9}, +{0x8b24,0x39}, +{0x8b25,0xa8}, +{0x8b26,0x38}, +{0x8b27,0xaf}, +{0x8b28,0x4b}, +{0x8b29,0xfc}, +{0x8b2a,0xfd}, +{0x8b2b,0xfe}, +{0x8b2c,0x12}, +{0x8b2d,0x05}, +{0x8b2e,0x28}, +{0x8b2f,0x12}, +{0x8b30,0x0d}, +{0x8b31,0xe1}, +{0x8b32,0xe4}, +{0x8b33,0x7b}, +{0x8b34,0xff}, +{0x8b35,0xfa}, +{0x8b36,0xf9}, +{0x8b37,0xf8}, +{0x8b38,0x12}, +{0x8b39,0x05}, +{0x8b3a,0xb3}, +{0x8b3b,0x12}, +{0x8b3c,0x0d}, +{0x8b3d,0xe1}, +{0x8b3e,0x90}, +{0x8b3f,0x0e}, +{0x8b40,0x69}, +{0x8b41,0xe4}, +{0x8b42,0x12}, +{0x8b43,0x0d}, +{0x8b44,0xf6}, +{0x8b45,0x12}, +{0x8b46,0x0d}, +{0x8b47,0xe1}, +{0x8b48,0xe4}, +{0x8b49,0x85}, +{0x8b4a,0x4a}, +{0x8b4b,0x37}, +{0x8b4c,0xf5}, +{0x8b4d,0x36}, +{0x8b4e,0xf5}, +{0x8b4f,0x35}, +{0x8b50,0xf5}, +{0x8b51,0x34}, +{0x8b52,0xaf}, +{0x8b53,0x37}, +{0x8b54,0xae}, +{0x8b55,0x36}, +{0x8b56,0xad}, +{0x8b57,0x35}, +{0x8b58,0xac}, +{0x8b59,0x34}, +{0x8b5a,0xa3}, +{0x8b5b,0x12}, +{0x8b5c,0x0d}, +{0x8b5d,0xf6}, +{0x8b5e,0x8f}, +{0x8b5f,0x37}, +{0x8b60,0x8e}, +{0x8b61,0x36}, +{0x8b62,0x8d}, +{0x8b63,0x35}, +{0x8b64,0x8c}, +{0x8b65,0x34}, +{0x8b66,0xe5}, +{0x8b67,0x3b}, +{0x8b68,0x45}, +{0x8b69,0x37}, +{0x8b6a,0xf5}, +{0x8b6b,0x3b}, +{0x8b6c,0xe5}, +{0x8b6d,0x3a}, +{0x8b6e,0x45}, +{0x8b6f,0x36}, +{0x8b70,0xf5}, +{0x8b71,0x3a}, +{0x8b72,0xe5}, +{0x8b73,0x39}, +{0x8b74,0x45}, +{0x8b75,0x35}, +{0x8b76,0xf5}, +{0x8b77,0x39}, +{0x8b78,0xe5}, +{0x8b79,0x38}, +{0x8b7a,0x45}, +{0x8b7b,0x34}, +{0x8b7c,0xf5}, +{0x8b7d,0x38}, +{0x8b7e,0xe4}, +{0x8b7f,0xf5}, +{0x8b80,0x22}, +{0x8b81,0xf5}, +{0x8b82,0x23}, +{0x8b83,0x85}, +{0x8b84,0x3b}, +{0x8b85,0x31}, +{0x8b86,0x85}, +{0x8b87,0x3a}, +{0x8b88,0x30}, +{0x8b89,0x85}, +{0x8b8a,0x39}, +{0x8b8b,0x2f}, +{0x8b8c,0x85}, +{0x8b8d,0x38}, +{0x8b8e,0x2e}, +{0x8b8f,0x02}, +{0x8b90,0x0f}, +{0x8b91,0x46}, +{0x8b92,0xe0}, +{0x8b93,0xa3}, +{0x8b94,0xe0}, +{0x8b95,0x75}, +{0x8b96,0xf0}, +{0x8b97,0x02}, +{0x8b98,0xa4}, +{0x8b99,0xff}, +{0x8b9a,0xae}, +{0x8b9b,0xf0}, +{0x8b9c,0xc3}, +{0x8b9d,0x08}, +{0x8b9e,0xe6}, +{0x8b9f,0x9f}, +{0x8ba0,0xf6}, +{0x8ba1,0x18}, +{0x8ba2,0xe6}, +{0x8ba3,0x9e}, +{0x8ba4,0xf6}, +{0x8ba5,0x22}, +{0x8ba6,0xff}, +{0x8ba7,0xe5}, +{0x8ba8,0xf0}, +{0x8ba9,0x34}, +{0x8baa,0x60}, +{0x8bab,0x8f}, +{0x8bac,0x82}, +{0x8bad,0xf5}, +{0x8bae,0x83}, +{0x8baf,0xec}, +{0x8bb0,0xf0}, +{0x8bb1,0x22}, +{0x8bb2,0x78}, +{0x8bb3,0x52}, +{0x8bb4,0x7e}, +{0x8bb5,0x00}, +{0x8bb6,0xe6}, +{0x8bb7,0xfc}, +{0x8bb8,0x08}, +{0x8bb9,0xe6}, +{0x8bba,0xfd}, +{0x8bbb,0x02}, +{0x8bbc,0x04}, +{0x8bbd,0xc1}, +{0x8bbe,0xe4}, +{0x8bbf,0xfc}, +{0x8bc0,0xfd}, +{0x8bc1,0x12}, +{0x8bc2,0x06}, +{0x8bc3,0x99}, +{0x8bc4,0x78}, +{0x8bc5,0x5c}, +{0x8bc6,0xe6}, +{0x8bc7,0xc3}, +{0x8bc8,0x13}, +{0x8bc9,0xfe}, +{0x8bca,0x08}, +{0x8bcb,0xe6}, +{0x8bcc,0x13}, +{0x8bcd,0x22}, +{0x8bce,0x78}, +{0x8bcf,0x52}, +{0x8bd0,0xe6}, +{0x8bd1,0xfe}, +{0x8bd2,0x08}, +{0x8bd3,0xe6}, +{0x8bd4,0xff}, +{0x8bd5,0xe4}, +{0x8bd6,0xfc}, +{0x8bd7,0xfd}, +{0x8bd8,0x22}, +{0x8bd9,0xe7}, +{0x8bda,0xc4}, +{0x8bdb,0xf8}, +{0x8bdc,0x54}, +{0x8bdd,0xf0}, +{0x8bde,0xc8}, +{0x8bdf,0x68}, +{0x8be0,0xf7}, +{0x8be1,0x09}, +{0x8be2,0xe7}, +{0x8be3,0xc4}, +{0x8be4,0x54}, +{0x8be5,0x0f}, +{0x8be6,0x48}, +{0x8be7,0xf7}, +{0x8be8,0x22}, +{0x8be9,0xe6}, +{0x8bea,0xfc}, +{0x8beb,0xed}, +{0x8bec,0x75}, +{0x8bed,0xf0}, +{0x8bee,0x04}, +{0x8bef,0xa4}, +{0x8bf0,0x22}, +{0x8bf1,0x12}, +{0x8bf2,0x06}, +{0x8bf3,0x7c}, +{0x8bf4,0x8f}, +{0x8bf5,0x48}, +{0x8bf6,0x8e}, +{0x8bf7,0x47}, +{0x8bf8,0x8d}, +{0x8bf9,0x46}, +{0x8bfa,0x8c}, +{0x8bfb,0x45}, +{0x8bfc,0x22}, +{0x8bfd,0xe0}, +{0x8bfe,0xfe}, +{0x8bff,0xa3}, +{0x8c00,0xe0}, +{0x8c01,0xfd}, +{0x8c02,0xee}, +{0x8c03,0xf6}, +{0x8c04,0xed}, +{0x8c05,0x08}, +{0x8c06,0xf6}, +{0x8c07,0x22}, +{0x8c08,0x13}, +{0x8c09,0xff}, +{0x8c0a,0xc3}, +{0x8c0b,0xe6}, +{0x8c0c,0x9f}, +{0x8c0d,0xff}, +{0x8c0e,0x18}, +{0x8c0f,0xe6}, +{0x8c10,0x9e}, +{0x8c11,0xfe}, +{0x8c12,0x22}, +{0x8c13,0xe6}, +{0x8c14,0xc3}, +{0x8c15,0x13}, +{0x8c16,0xf7}, +{0x8c17,0x08}, +{0x8c18,0xe6}, +{0x8c19,0x13}, +{0x8c1a,0x09}, +{0x8c1b,0xf7}, +{0x8c1c,0x22}, +{0x8c1d,0xad}, +{0x8c1e,0x39}, +{0x8c1f,0xac}, +{0x8c20,0x38}, +{0x8c21,0xfa}, +{0x8c22,0xf9}, +{0x8c23,0xf8}, +{0x8c24,0x12}, +{0x8c25,0x05}, +{0x8c26,0x28}, +{0x8c27,0x8f}, +{0x8c28,0x3b}, +{0x8c29,0x8e}, +{0x8c2a,0x3a}, +{0x8c2b,0x8d}, +{0x8c2c,0x39}, +{0x8c2d,0x8c}, +{0x8c2e,0x38}, +{0x8c2f,0xab}, +{0x8c30,0x37}, +{0x8c31,0xaa}, +{0x8c32,0x36}, +{0x8c33,0xa9}, +{0x8c34,0x35}, +{0x8c35,0xa8}, +{0x8c36,0x34}, +{0x8c37,0x22}, +{0x8c38,0x93}, +{0x8c39,0xff}, +{0x8c3a,0xe4}, +{0x8c3b,0xfc}, +{0x8c3c,0xfd}, +{0x8c3d,0xfe}, +{0x8c3e,0x12}, +{0x8c3f,0x05}, +{0x8c40,0x28}, +{0x8c41,0x8f}, +{0x8c42,0x37}, +{0x8c43,0x8e}, +{0x8c44,0x36}, +{0x8c45,0x8d}, +{0x8c46,0x35}, +{0x8c47,0x8c}, +{0x8c48,0x34}, +{0x8c49,0x22}, +{0x8c4a,0x78}, +{0x8c4b,0x84}, +{0x8c4c,0xe6}, +{0x8c4d,0xfe}, +{0x8c4e,0x08}, +{0x8c4f,0xe6}, +{0x8c50,0xff}, +{0x8c51,0xe4}, +{0x8c52,0x8f}, +{0x8c53,0x37}, +{0x8c54,0x8e}, +{0x8c55,0x36}, +{0x8c56,0xf5}, +{0x8c57,0x35}, +{0x8c58,0xf5}, +{0x8c59,0x34}, +{0x8c5a,0x22}, +{0x8c5b,0x90}, +{0x8c5c,0x0e}, +{0x8c5d,0x8c}, +{0x8c5e,0xe4}, +{0x8c5f,0x93}, +{0x8c60,0x25}, +{0x8c61,0xe0}, +{0x8c62,0x24}, +{0x8c63,0x0a}, +{0x8c64,0xf8}, +{0x8c65,0xe6}, +{0x8c66,0xfe}, +{0x8c67,0x08}, +{0x8c68,0xe6}, +{0x8c69,0xff}, +{0x8c6a,0x22}, +{0x8c6b,0xe6}, +{0x8c6c,0xfe}, +{0x8c6d,0x08}, +{0x8c6e,0xe6}, +{0x8c6f,0xff}, +{0x8c70,0xe4}, +{0x8c71,0x8f}, +{0x8c72,0x3b}, +{0x8c73,0x8e}, +{0x8c74,0x3a}, +{0x8c75,0xf5}, +{0x8c76,0x39}, +{0x8c77,0xf5}, +{0x8c78,0x38}, +{0x8c79,0x22}, +{0x8c7a,0x78}, +{0x8c7b,0x4e}, +{0x8c7c,0xe6}, +{0x8c7d,0xfe}, +{0x8c7e,0x08}, +{0x8c7f,0xe6}, +{0x8c80,0xff}, +{0x8c81,0x22}, +{0x8c82,0xef}, +{0x8c83,0x25}, +{0x8c84,0xe0}, +{0x8c85,0x24}, +{0x8c86,0x4e}, +{0x8c87,0xf8}, +{0x8c88,0xe6}, +{0x8c89,0xfc}, +{0x8c8a,0x08}, +{0x8c8b,0xe6}, +{0x8c8c,0xfd}, +{0x8c8d,0x22}, +{0x8c8e,0x78}, +{0x8c8f,0x89}, +{0x8c90,0xef}, +{0x8c91,0x26}, +{0x8c92,0xf6}, +{0x8c93,0x18}, +{0x8c94,0xe4}, +{0x8c95,0x36}, +{0x8c96,0xf6}, +{0x8c97,0x22}, +{0x8c98,0x75}, +{0x8c99,0x89}, +{0x8c9a,0x03}, +{0x8c9b,0x75}, +{0x8c9c,0xa8}, +{0x8c9d,0x01}, +{0x8c9e,0x75}, +{0x8c9f,0xb8}, +{0x8ca0,0x04}, +{0x8ca1,0x75}, +{0x8ca2,0x34}, +{0x8ca3,0xff}, +{0x8ca4,0x75}, +{0x8ca5,0x35}, +{0x8ca6,0x0e}, +{0x8ca7,0x75}, +{0x8ca8,0x36}, +{0x8ca9,0x15}, +{0x8caa,0x75}, +{0x8cab,0x37}, +{0x8cac,0x0d}, +{0x8cad,0x12}, +{0x8cae,0x0e}, +{0x8caf,0x9a}, +{0x8cb0,0x12}, +{0x8cb1,0x00}, +{0x8cb2,0x09}, +{0x8cb3,0x12}, +{0x8cb4,0x0f}, +{0x8cb5,0x16}, +{0x8cb6,0x12}, +{0x8cb7,0x00}, +{0x8cb8,0x06}, +{0x8cb9,0xd2}, +{0x8cba,0x00}, +{0x8cbb,0xd2}, +{0x8cbc,0x34}, +{0x8cbd,0xd2}, +{0x8cbe,0xaf}, +{0x8cbf,0x75}, +{0x8cc0,0x34}, +{0x8cc1,0xff}, +{0x8cc2,0x75}, +{0x8cc3,0x35}, +{0x8cc4,0x0e}, +{0x8cc5,0x75}, +{0x8cc6,0x36}, +{0x8cc7,0x49}, +{0x8cc8,0x75}, +{0x8cc9,0x37}, +{0x8cca,0x03}, +{0x8ccb,0x12}, +{0x8ccc,0x0e}, +{0x8ccd,0x9a}, +{0x8cce,0x30}, +{0x8ccf,0x08}, +{0x8cd0,0x09}, +{0x8cd1,0xc2}, +{0x8cd2,0x34}, +{0x8cd3,0x12}, +{0x8cd4,0x08}, +{0x8cd5,0xcb}, +{0x8cd6,0xc2}, +{0x8cd7,0x08}, +{0x8cd8,0xd2}, +{0x8cd9,0x34}, +{0x8cda,0x30}, +{0x8cdb,0x0b}, +{0x8cdc,0x09}, +{0x8cdd,0xc2}, +{0x8cde,0x36}, +{0x8cdf,0x12}, +{0x8ce0,0x02}, +{0x8ce1,0x6c}, +{0x8ce2,0xc2}, +{0x8ce3,0x0b}, +{0x8ce4,0xd2}, +{0x8ce5,0x36}, +{0x8ce6,0x30}, +{0x8ce7,0x09}, +{0x8ce8,0x09}, +{0x8ce9,0xc2}, +{0x8cea,0x36}, +{0x8ceb,0x12}, +{0x8cec,0x00}, +{0x8ced,0x0e}, +{0x8cee,0xc2}, +{0x8cef,0x09}, +{0x8cf0,0xd2}, +{0x8cf1,0x36}, +{0x8cf2,0x30}, +{0x8cf3,0x0e}, +{0x8cf4,0x03}, +{0x8cf5,0x12}, +{0x8cf6,0x06}, +{0x8cf7,0xd7}, +{0x8cf8,0x30}, +{0x8cf9,0x35}, +{0x8cfa,0xd3}, +{0x8cfb,0x90}, +{0x8cfc,0x30}, +{0x8cfd,0x29}, +{0x8cfe,0xe5}, +{0x8cff,0x1e}, +{0x8d00,0xf0}, +{0x8d01,0xb4}, +{0x8d02,0x10}, +{0x8d03,0x05}, +{0x8d04,0x90}, +{0x8d05,0x30}, +{0x8d06,0x23}, +{0x8d07,0xe4}, +{0x8d08,0xf0}, +{0x8d09,0xc2}, +{0x8d0a,0x35}, +{0x8d0b,0x80}, +{0x8d0c,0xc1}, +{0x8d0d,0xe4}, +{0x8d0e,0xf5}, +{0x8d0f,0x4b}, +{0x8d10,0x90}, +{0x8d11,0x0e}, +{0x8d12,0x7a}, +{0x8d13,0x93}, +{0x8d14,0xff}, +{0x8d15,0xe4}, +{0x8d16,0x8f}, +{0x8d17,0x37}, +{0x8d18,0xf5}, +{0x8d19,0x36}, +{0x8d1a,0xf5}, +{0x8d1b,0x35}, +{0x8d1c,0xf5}, +{0x8d1d,0x34}, +{0x8d1e,0xaf}, +{0x8d1f,0x37}, +{0x8d20,0xae}, +{0x8d21,0x36}, +{0x8d22,0xad}, +{0x8d23,0x35}, +{0x8d24,0xac}, +{0x8d25,0x34}, +{0x8d26,0x90}, +{0x8d27,0x0e}, +{0x8d28,0x6a}, +{0x8d29,0x12}, +{0x8d2a,0x0d}, +{0x8d2b,0xf6}, +{0x8d2c,0x8f}, +{0x8d2d,0x37}, +{0x8d2e,0x8e}, +{0x8d2f,0x36}, +{0x8d30,0x8d}, +{0x8d31,0x35}, +{0x8d32,0x8c}, +{0x8d33,0x34}, +{0x8d34,0x90}, +{0x8d35,0x0e}, +{0x8d36,0x72}, +{0x8d37,0x12}, +{0x8d38,0x06}, +{0x8d39,0x7c}, +{0x8d3a,0xef}, +{0x8d3b,0x45}, +{0x8d3c,0x37}, +{0x8d3d,0xf5}, +{0x8d3e,0x37}, +{0x8d3f,0xee}, +{0x8d40,0x45}, +{0x8d41,0x36}, +{0x8d42,0xf5}, +{0x8d43,0x36}, +{0x8d44,0xed}, +{0x8d45,0x45}, +{0x8d46,0x35}, +{0x8d47,0xf5}, +{0x8d48,0x35}, +{0x8d49,0xec}, +{0x8d4a,0x45}, +{0x8d4b,0x34}, +{0x8d4c,0xf5}, +{0x8d4d,0x34}, +{0x8d4e,0xe4}, +{0x8d4f,0xf5}, +{0x8d50,0x22}, +{0x8d51,0xf5}, +{0x8d52,0x23}, +{0x8d53,0x85}, +{0x8d54,0x37}, +{0x8d55,0x31}, +{0x8d56,0x85}, +{0x8d57,0x36}, +{0x8d58,0x30}, +{0x8d59,0x85}, +{0x8d5a,0x35}, +{0x8d5b,0x2f}, +{0x8d5c,0x85}, +{0x8d5d,0x34}, +{0x8d5e,0x2e}, +{0x8d5f,0x12}, +{0x8d60,0x0f}, +{0x8d61,0x46}, +{0x8d62,0xe4}, +{0x8d63,0xf5}, +{0x8d64,0x22}, +{0x8d65,0xf5}, +{0x8d66,0x23}, +{0x8d67,0x90}, +{0x8d68,0x0e}, +{0x8d69,0x72}, +{0x8d6a,0x12}, +{0x8d6b,0x0d}, +{0x8d6c,0xea}, +{0x8d6d,0x12}, +{0x8d6e,0x0f}, +{0x8d6f,0x46}, +{0x8d70,0xe4}, +{0x8d71,0xf5}, +{0x8d72,0x22}, +{0x8d73,0xf5}, +{0x8d74,0x23}, +{0x8d75,0x90}, +{0x8d76,0x0e}, +{0x8d77,0x6e}, +{0x8d78,0x12}, +{0x8d79,0x0d}, +{0x8d7a,0xea}, +{0x8d7b,0x02}, +{0x8d7c,0x0f}, +{0x8d7d,0x46}, +{0x8d7e,0xe5}, +{0x8d7f,0x40}, +{0x8d80,0x24}, +{0x8d81,0xf2}, +{0x8d82,0xf5}, +{0x8d83,0x37}, +{0x8d84,0xe5}, +{0x8d85,0x3f}, +{0x8d86,0x34}, +{0x8d87,0x43}, +{0x8d88,0xf5}, +{0x8d89,0x36}, +{0x8d8a,0xe5}, +{0x8d8b,0x3e}, +{0x8d8c,0x34}, +{0x8d8d,0xa2}, +{0x8d8e,0xf5}, +{0x8d8f,0x35}, +{0x8d90,0xe5}, +{0x8d91,0x3d}, +{0x8d92,0x34}, +{0x8d93,0x28}, +{0x8d94,0xf5}, +{0x8d95,0x34}, +{0x8d96,0xe5}, +{0x8d97,0x37}, +{0x8d98,0xff}, +{0x8d99,0xe4}, +{0x8d9a,0xfe}, +{0x8d9b,0xfd}, +{0x8d9c,0xfc}, +{0x8d9d,0x78}, +{0x8d9e,0x18}, +{0x8d9f,0x12}, +{0x8da0,0x06}, +{0x8da1,0x69}, +{0x8da2,0x8f}, +{0x8da3,0x40}, +{0x8da4,0x8e}, +{0x8da5,0x3f}, +{0x8da6,0x8d}, +{0x8da7,0x3e}, +{0x8da8,0x8c}, +{0x8da9,0x3d}, +{0x8daa,0xe5}, +{0x8dab,0x37}, +{0x8dac,0x54}, +{0x8dad,0xa0}, +{0x8dae,0xff}, +{0x8daf,0xe5}, +{0x8db0,0x36}, +{0x8db1,0xfe}, +{0x8db2,0xe4}, +{0x8db3,0xfd}, +{0x8db4,0xfc}, +{0x8db5,0x78}, +{0x8db6,0x07}, +{0x8db7,0x12}, +{0x8db8,0x06}, +{0x8db9,0x56}, +{0x8dba,0x78}, +{0x8dbb,0x10}, +{0x8dbc,0x12}, +{0x8dbd,0x0f}, +{0x8dbe,0x9a}, +{0x8dbf,0xe4}, +{0x8dc0,0xff}, +{0x8dc1,0xfe}, +{0x8dc2,0xe5}, +{0x8dc3,0x35}, +{0x8dc4,0xfd}, +{0x8dc5,0xe4}, +{0x8dc6,0xfc}, +{0x8dc7,0x78}, +{0x8dc8,0x0e}, +{0x8dc9,0x12}, +{0x8dca,0x06}, +{0x8dcb,0x56}, +{0x8dcc,0x12}, +{0x8dcd,0x0f}, +{0x8dce,0x9d}, +{0x8dcf,0xe4}, +{0x8dd0,0xff}, +{0x8dd1,0xfe}, +{0x8dd2,0xfd}, +{0x8dd3,0xe5}, +{0x8dd4,0x34}, +{0x8dd5,0xfc}, +{0x8dd6,0x78}, +{0x8dd7,0x18}, +{0x8dd8,0x12}, +{0x8dd9,0x06}, +{0x8dda,0x56}, +{0x8ddb,0x78}, +{0x8ddc,0x08}, +{0x8ddd,0x12}, +{0x8dde,0x0f}, +{0x8ddf,0x9a}, +{0x8de0,0x22}, +{0x8de1,0x8f}, +{0x8de2,0x3b}, +{0x8de3,0x8e}, +{0x8de4,0x3a}, +{0x8de5,0x8d}, +{0x8de6,0x39}, +{0x8de7,0x8c}, +{0x8de8,0x38}, +{0x8de9,0x22}, +{0x8dea,0x12}, +{0x8deb,0x06}, +{0x8dec,0x7c}, +{0x8ded,0x8f}, +{0x8dee,0x31}, +{0x8def,0x8e}, +{0x8df0,0x30}, +{0x8df1,0x8d}, +{0x8df2,0x2f}, +{0x8df3,0x8c}, +{0x8df4,0x2e}, +{0x8df5,0x22}, +{0x8df6,0x93}, +{0x8df7,0xf9}, +{0x8df8,0xf8}, +{0x8df9,0x02}, +{0x8dfa,0x06}, +{0x8dfb,0x69}, +{0x8dfc,0x00}, +{0x8dfd,0x00}, +{0x8dfe,0x00}, +{0x8dff,0x00}, +{0x8e00,0x12}, +{0x8e01,0x01}, +{0x8e02,0x17}, +{0x8e03,0x08}, +{0x8e04,0x31}, +{0x8e05,0x15}, +{0x8e06,0x53}, +{0x8e07,0x54}, +{0x8e08,0x44}, +{0x8e09,0x20}, +{0x8e0a,0x20}, +{0x8e0b,0x20}, +{0x8e0c,0x20}, +{0x8e0d,0x20}, +{0x8e0e,0x13}, +{0x8e0f,0x01}, +{0x8e10,0x10}, +{0x8e11,0x01}, +{0x8e12,0x56}, +{0x8e13,0x40}, +{0x8e14,0x1a}, +{0x8e15,0x30}, +{0x8e16,0x29}, +{0x8e17,0x7e}, +{0x8e18,0x00}, +{0x8e19,0x30}, +{0x8e1a,0x04}, +{0x8e1b,0x20}, +{0x8e1c,0xdf}, +{0x8e1d,0x30}, +{0x8e1e,0x05}, +{0x8e1f,0x40}, +{0x8e20,0xbf}, +{0x8e21,0x50}, +{0x8e22,0x03}, +{0x8e23,0x00}, +{0x8e24,0xfd}, +{0x8e25,0x50}, +{0x8e26,0x27}, +{0x8e27,0x01}, +{0x8e28,0xfe}, +{0x8e29,0x60}, +{0x8e2a,0x00}, +{0x8e2b,0x11}, +{0x8e2c,0x00}, +{0x8e2d,0x3f}, +{0x8e2e,0x05}, +{0x8e2f,0x30}, +{0x8e30,0x00}, +{0x8e31,0x3f}, +{0x8e32,0x06}, +{0x8e33,0x22}, +{0x8e34,0x00}, +{0x8e35,0x3f}, +{0x8e36,0x01}, +{0x8e37,0x2a}, +{0x8e38,0x00}, +{0x8e39,0x3f}, +{0x8e3a,0x02}, +{0x8e3b,0x00}, +{0x8e3c,0x00}, +{0x8e3d,0x36}, +{0x8e3e,0x06}, +{0x8e3f,0x07}, +{0x8e40,0x00}, +{0x8e41,0x3f}, +{0x8e42,0x0b}, +{0x8e43,0x0f}, +{0x8e44,0xf0}, +{0x8e45,0x00}, +{0x8e46,0x00}, +{0x8e47,0x00}, +{0x8e48,0x00}, +{0x8e49,0x30}, +{0x8e4a,0x01}, +{0x8e4b,0x40}, +{0x8e4c,0xbf}, +{0x8e4d,0x30}, +{0x8e4e,0x01}, +{0x8e4f,0x00}, +{0x8e50,0xbf}, +{0x8e51,0x30}, +{0x8e52,0x29}, +{0x8e53,0x70}, +{0x8e54,0x00}, +{0x8e55,0x3a}, +{0x8e56,0x00}, +{0x8e57,0x00}, +{0x8e58,0xff}, +{0x8e59,0x3a}, +{0x8e5a,0x00}, +{0x8e5b,0x00}, +{0x8e5c,0xff}, +{0x8e5d,0x36}, +{0x8e5e,0x03}, +{0x8e5f,0x36}, +{0x8e60,0x02}, +{0x8e61,0x41}, +{0x8e62,0x44}, +{0x8e63,0x58}, +{0x8e64,0x20}, +{0x8e65,0x18}, +{0x8e66,0x10}, +{0x8e67,0x0a}, +{0x8e68,0x04}, +{0x8e69,0x04}, +{0x8e6a,0x00}, +{0x8e6b,0x03}, +{0x8e6c,0xff}, +{0x8e6d,0x64}, +{0x8e6e,0x00}, +{0x8e6f,0x00}, +{0x8e70,0x80}, +{0x8e71,0x00}, +{0x8e72,0x00}, +{0x8e73,0x00}, +{0x8e74,0x00}, +{0x8e75,0x00}, +{0x8e76,0x00}, +{0x8e77,0x02}, +{0x8e78,0x04}, +{0x8e79,0x06}, +{0x8e7a,0x06}, +{0x8e7b,0x00}, +{0x8e7c,0x02}, +{0x8e7d,0x60},//cc}, +{0x8e7e,0x00}, +{0x8e7f,0x70}, +{0x8e80,0x50}, +{0x8e81,0x3c}, +{0x8e82,0x28}, +{0x8e83,0x1e}, +{0x8e84,0x10}, +{0x8e85,0x10}, +{0x8e86,0x50}, +{0x8e87,0x2d}, +{0x8e88,0x28}, +{0x8e89,0x16}, +{0x8e8a,0x10}, +{0x8e8b,0x10}, +{0x8e8c,0x02}, +{0x8e8d,0x00}, +{0x8e8e,0x10}, +{0x8e8f,0x30}, +{0x8e90,0x0a}, +{0x8e91,0x04}, +{0x8e92,0x05}, +{0x8e93,0x08}, +{0x8e94,0x06}, +{0x8e95,0x05}, +{0x8e96,0x00}, +{0x8e97,0xa5}, +{0x8e98,0x5a}, +{0x8e99,0x00}, +{0x8e9a,0xae}, +{0x8e9b,0x35}, +{0x8e9c,0xaf}, +{0x8e9d,0x36}, +{0x8e9e,0xe4}, +{0x8e9f,0xfd}, +{0x8ea0,0xed}, +{0x8ea1,0xc3}, +{0x8ea2,0x95}, +{0x8ea3,0x37}, +{0x8ea4,0x50}, +{0x8ea5,0x33}, +{0x8ea6,0x12}, +{0x8ea7,0x0f}, +{0x8ea8,0xe2}, +{0x8ea9,0xe4}, +{0x8eaa,0x93}, +{0x8eab,0xf5}, +{0x8eac,0x38}, +{0x8ead,0x74}, +{0x8eae,0x01}, +{0x8eaf,0x93}, +{0x8eb0,0xf5}, +{0x8eb1,0x39}, +{0x8eb2,0x45}, +{0x8eb3,0x38}, +{0x8eb4,0x60}, +{0x8eb5,0x23}, +{0x8eb6,0x85}, +{0x8eb7,0x39}, +{0x8eb8,0x82}, +{0x8eb9,0x85}, +{0x8eba,0x38}, +{0x8ebb,0x83}, +{0x8ebc,0xe0}, +{0x8ebd,0xfc}, +{0x8ebe,0x12}, +{0x8ebf,0x0f}, +{0x8ec0,0xe2}, +{0x8ec1,0x74}, +{0x8ec2,0x03}, +{0x8ec3,0x93}, +{0x8ec4,0x52}, +{0x8ec5,0x04}, +{0x8ec6,0x12}, +{0x8ec7,0x0f}, +{0x8ec8,0xe2}, +{0x8ec9,0x74}, +{0x8eca,0x02}, +{0x8ecb,0x93}, +{0x8ecc,0x42}, +{0x8ecd,0x04}, +{0x8ece,0x85}, +{0x8ecf,0x39}, +{0x8ed0,0x82}, +{0x8ed1,0x85}, +{0x8ed2,0x38}, +{0x8ed3,0x83}, +{0x8ed4,0xec}, +{0x8ed5,0xf0}, +{0x8ed6,0x0d}, +{0x8ed7,0x80}, +{0x8ed8,0xc7}, +{0x8ed9,0x22}, +{0x8eda,0x78}, +{0x8edb,0xbe}, +{0x8edc,0xe6}, +{0x8edd,0xd3}, +{0x8ede,0x08}, +{0x8edf,0xff}, +{0x8ee0,0xe6}, +{0x8ee1,0x64}, +{0x8ee2,0x80}, +{0x8ee3,0xf8}, +{0x8ee4,0xef}, +{0x8ee5,0x64}, +{0x8ee6,0x80}, +{0x8ee7,0x98}, +{0x8ee8,0x22}, +{0x8ee9,0x93}, +{0x8eea,0xff}, +{0x8eeb,0x7e}, +{0x8eec,0x00}, +{0x8eed,0xe6}, +{0x8eee,0xfc}, +{0x8eef,0x08}, +{0x8ef0,0xe6}, +{0x8ef1,0xfd}, +{0x8ef2,0x12}, +{0x8ef3,0x04}, +{0x8ef4,0xc1}, +{0x8ef5,0x78}, +{0x8ef6,0xc1}, +{0x8ef7,0xe6}, +{0x8ef8,0xfc}, +{0x8ef9,0x08}, +{0x8efa,0xe6}, +{0x8efb,0xfd}, +{0x8efc,0xd3}, +{0x8efd,0xef}, +{0x8efe,0x9d}, +{0x8eff,0xee}, +{0x8f00,0x9c}, +{0x8f01,0x22}, +{0x8f02,0x78}, +{0x8f03,0xbd}, +{0x8f04,0xd3}, +{0x8f05,0xe6}, +{0x8f06,0x64}, +{0x8f07,0x80}, +{0x8f08,0x94}, +{0x8f09,0x80}, +{0x8f0a,0x22}, +{0x8f0b,0x25}, +{0x8f0c,0xe0}, +{0x8f0d,0x24}, +{0x8f0e,0x0a}, +{0x8f0f,0xf8}, +{0x8f10,0xe6}, +{0x8f11,0xfe}, +{0x8f12,0x08}, +{0x8f13,0xe6}, +{0x8f14,0xff}, +{0x8f15,0x22}, +{0x8f16,0xe5}, +{0x8f17,0x3c}, +{0x8f18,0xd3}, +{0x8f19,0x94}, +{0x8f1a,0x00}, +{0x8f1b,0x40}, +{0x8f1c,0x0b}, +{0x8f1d,0x90}, +{0x8f1e,0x0e}, +{0x8f1f,0x88}, +{0x8f20,0x12}, +{0x8f21,0x0b}, +{0x8f22,0xf1}, +{0x8f23,0x90}, +{0x8f24,0x0e}, +{0x8f25,0x86}, +{0x8f26,0x80}, +{0x8f27,0x09}, +{0x8f28,0x90}, +{0x8f29,0x0e}, +{0x8f2a,0x82}, +{0x8f2b,0x12}, +{0x8f2c,0x0b}, +{0x8f2d,0xf1}, +{0x8f2e,0x90}, +{0x8f2f,0x0e}, +{0x8f30,0x80}, +{0x8f31,0xe4}, +{0x8f32,0x93}, +{0x8f33,0xf5}, +{0x8f34,0x44}, +{0x8f35,0xa3}, +{0x8f36,0xe4}, +{0x8f37,0x93}, +{0x8f38,0xf5}, +{0x8f39,0x43}, +{0x8f3a,0xd2}, +{0x8f3b,0x06}, +{0x8f3c,0x30}, +{0x8f3d,0x06}, +{0x8f3e,0x03}, +{0x8f3f,0xd3}, +{0x8f40,0x80}, +{0x8f41,0x01}, +{0x8f42,0xc3}, +{0x8f43,0x92}, +{0x8f44,0x0e}, +{0x8f45,0x22}, +{0x8f46,0xa2}, +{0x8f47,0xaf}, +{0x8f48,0x92}, +{0x8f49,0x32}, +{0x8f4a,0xc2}, +{0x8f4b,0xaf}, +{0x8f4c,0xe5}, +{0x8f4d,0x23}, +{0x8f4e,0x45}, +{0x8f4f,0x22}, +{0x8f50,0x90}, +{0x8f51,0x0e}, +{0x8f52,0x5d}, +{0x8f53,0x60}, +{0x8f54,0x0e}, +{0x8f55,0x12}, +{0x8f56,0x0f}, +{0x8f57,0xcb}, +{0x8f58,0xe0}, +{0x8f59,0xf5}, +{0x8f5a,0x2c}, +{0x8f5b,0x12}, +{0x8f5c,0x0f}, +{0x8f5d,0xc8}, +{0x8f5e,0xe0}, +{0x8f5f,0xf5}, +{0x8f60,0x2d}, +{0x8f61,0x80}, +{0x8f62,0x0c}, +{0x8f63,0x12}, +{0x8f64,0x0f}, +{0x8f65,0xcb}, +{0x8f66,0xe5}, +{0x8f67,0x30}, +{0x8f68,0xf0}, +{0x8f69,0x12}, +{0x8f6a,0x0f}, +{0x8f6b,0xc8}, +{0x8f6c,0xe5}, +{0x8f6d,0x31}, +{0x8f6e,0xf0}, +{0x8f6f,0xa2}, +{0x8f70,0x32}, +{0x8f71,0x92}, +{0x8f72,0xaf}, +{0x8f73,0x22}, +{0x8f74,0xd2}, +{0x8f75,0x01}, +{0x8f76,0xc2}, +{0x8f77,0x02}, +{0x8f78,0xe4}, +{0x8f79,0xf5}, +{0x8f7a,0x1f}, +{0x8f7b,0xf5}, +{0x8f7c,0x1e}, +{0x8f7d,0xd2}, +{0x8f7e,0x35}, +{0x8f7f,0xd2}, +{0x8f80,0x33}, +{0x8f81,0xd2}, +{0x8f82,0x36}, +{0x8f83,0xd2}, +{0x8f84,0x01}, +{0x8f85,0xc2}, +{0x8f86,0x02}, +{0x8f87,0xf5}, +{0x8f88,0x1f}, +{0x8f89,0xf5}, +{0x8f8a,0x1e}, +{0x8f8b,0xd2}, +{0x8f8c,0x35}, +{0x8f8d,0xd2}, +{0x8f8e,0x33}, +{0x8f8f,0x22}, +{0x8f90,0xfb}, +{0x8f91,0xd3}, +{0x8f92,0xed}, +{0x8f93,0x9b}, +{0x8f94,0x74}, +{0x8f95,0x80}, +{0x8f96,0xf8}, +{0x8f97,0x6c}, +{0x8f98,0x98}, +{0x8f99,0x22}, +{0x8f9a,0x12}, +{0x8f9b,0x06}, +{0x8f9c,0x69}, +{0x8f9d,0xe5}, +{0x8f9e,0x40}, +{0x8f9f,0x2f}, +{0x8fa0,0xf5}, +{0x8fa1,0x40}, +{0x8fa2,0xe5}, +{0x8fa3,0x3f}, +{0x8fa4,0x3e}, +{0x8fa5,0xf5}, +{0x8fa6,0x3f}, +{0x8fa7,0xe5}, +{0x8fa8,0x3e}, +{0x8fa9,0x3d}, +{0x8faa,0xf5}, +{0x8fab,0x3e}, +{0x8fac,0xe5}, +{0x8fad,0x3d}, +{0x8fae,0x3c}, +{0x8faf,0xf5}, +{0x8fb0,0x3d}, +{0x8fb1,0x22}, +{0x8fb2,0xc0}, +{0x8fb3,0xe0}, +{0x8fb4,0xc0}, +{0x8fb5,0x83}, +{0x8fb6,0xc0}, +{0x8fb7,0x82}, +{0x8fb8,0x90}, +{0x8fb9,0x3f}, +{0x8fba,0x0d}, +{0x8fbb,0xe0}, +{0x8fbc,0xf5}, +{0x8fbd,0x33}, +{0x8fbe,0xe5}, +{0x8fbf,0x33}, +{0x8fc0,0xf0}, +{0x8fc1,0xd0}, +{0x8fc2,0x82}, +{0x8fc3,0xd0}, +{0x8fc4,0x83}, +{0x8fc5,0xd0}, +{0x8fc6,0xe0}, +{0x8fc7,0x32}, +{0x8fc8,0x90}, +{0x8fc9,0x0e}, +{0x8fca,0x5f}, +{0x8fcb,0xe4}, +{0x8fcc,0x93}, +{0x8fcd,0xfe}, +{0x8fce,0x74}, +{0x8fcf,0x01}, +{0x8fd0,0x93}, +{0x8fd1,0xf5}, +{0x8fd2,0x82}, +{0x8fd3,0x8e}, +{0x8fd4,0x83}, +{0x8fd5,0x22}, +{0x8fd6,0x78}, +{0x8fd7,0x7f}, +{0x8fd8,0xe4}, +{0x8fd9,0xf6}, +{0x8fda,0xd8}, +{0x8fdb,0xfd}, +{0x8fdc,0x75}, +{0x8fdd,0x81}, +{0x8fde,0xcd}, +{0x8fdf,0x02}, +{0x8fe0,0x0c}, +{0x8fe1,0x98}, +{0x8fe2,0x8f}, +{0x8fe3,0x82}, +{0x8fe4,0x8e}, +{0x8fe5,0x83}, +{0x8fe6,0x75}, +{0x8fe7,0xf0}, +{0x8fe8,0x04}, +{0x8fe9,0xed}, +{0x8fea,0x02}, +{0x8feb,0x06}, +{0x8fec,0xa5}, +{0x3022,0x00}, +{0x3023,0x00}, +{0x3024,0x00}, +{0x3025,0x00}, +{0x3026,0x00}, +{0x3027,0x00}, +{0x3028,0x00}, +{0x3029,0x7F}, +{0x3000,0x00}, +#endif + {SEQUENCE_END,0x00}, +}; diff --git a/drivers/media/video/ov5640_old.c b/drivers/media/video/ov5640_old.c new file mode 100755 index 000000000000..25b0dc1e5d34 --- /dev/null +++ b/drivers/media/video/ov5640_old.c @@ -0,0 +1,4199 @@ +/* + * Driver for OV5640 CMOS Image Sensor from OmniVision + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ov5640.h" + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_OV5640 +#define SENSOR_V4L2_IDENT V4L2_IDENT_OV5640 +#define SENSOR_ID 0x5640 +#define SENSOR_MIN_WIDTH 176 +#define SENSOR_MIN_HEIGHT 144 +#define SENSOR_MAX_WIDTH 2592 +#define SENSOR_MAX_HEIGHT 1944 +#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 600 +#define SENSOR_INIT_WINSEQADR sensor_svga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#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_Exposure 0 +#define CONFIG_SENSOR_Flash 1 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 +#ifdef CONFIG_OV5640_AUTOFOCUS +#define CONFIG_SENSOR_Focus 1 +#define CONFIG_SENSOR_FocusCenterInCapture 0 +#define CONFIG_SENSOR_FocusContinues 0 +#include "ov5640_af_firmware.c" +#else +#define CONFIG_SENSOR_Focus 0 +#endif + +#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define CONFIG_SENSOR_WRITE_REGS 0 +#define WRITE_REGS_NUM 3 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +#if CONFIG_SENSOR_Focus +/*#define SENSOR_AF_MODE_INFINITY 0 +#define SENSOR_AF_MODE_MACRO 1 +#define SENSOR_AF_MODE_FIXED 2 +#define SENSOR_AF_MODE_AUTO 3 +#define SENSOR_AF_MODE_CONTINUOUS 4 +#define SENSOR_AF_MODE_CLOSE 5*/ +#define SENSOR_AF_MODE_AUTO 0 +#define SENSOR_AF_MODE_CLOSE 1 +#define SENSOR_AF_MODE_CONTINUOUS 2 +#endif + +#if CONFIG_SENSOR_Focus +/* ov5640 VCM Command and Status Registers */ +#define CMD_MAIN_Reg 0x3022 +//#define CMD_TAG_Reg 0x3023 +#define CMD_ACK_Reg 0x3023 +#define CMD_PARA0_Reg 0x3024 +#define CMD_PARA1_Reg 0x3025 +#define CMD_PARA2_Reg 0x3026 +#define CMD_PARA3_Reg 0x3027 +#define CMD_PARA4_Reg 0x3028 + +//#define STA_ZONE_Reg 0x3026 +#define STA_FOCUS_Reg 0x3029 + +/* ov5640 VCM Command */ + +#define ConstFocus_Cmd 0x04 +#define StepMode_Cmd 0x05 +#define PauseFocus_Cmd 0x06 +#define ReturnIdle_Cmd 0x08 +#define SetZone_Cmd 0x10 +#define UpdateZone_Cmd 0x12 +#define SetMotor_Cmd 0x20 +#define SingleFocus_Cmd 0x03 +#define GetFocusResult_Cmd 0x07 +#define ReleaseFocus_Cmd 0x08 +#define ZoneRelaunch_Cmd 0x12 +#define DefaultZoneConfig_Cmd 0x80 +#define TouchZoneConfig_Cmd 0x81 +#define CustomZoneConfig_Cmd 0x8f + + +/* ov5640 Focus State */ +//#define S_FIRWRE 0xFF /*Firmware is downloaded and not run*/ +#define S_STARTUP 0x7e /*Firmware is initializing*/ +#define S_ERROR 0x7f +#define S_IDLE 0x70 /*Idle state, focus is released; lens is located at the furthest position.*/ +#define S_FOCUSING 0x00 /*Auto Focus is running.*/ +#define S_FOCUSED 0x10 /*Auto Focus is completed.*/ + +#define S_CAPTURE 0x12 +#define S_STEP 0x20 + +/* ov5640 Zone State */ +#define Zone_Is_Focused(a, zone_val) (zone_val&(1<<(a-3))) +#define Zone_Get_ID(zone_val) (zone_val&0x03) + +#define Zone_CenterMode 0x01 +#define Zone_5xMode 0x02 +#define Zone_5PlusMode 0x03 +#define Zone_4fMode 0x04 + +#define ZoneSel_Auto 0x0b +#define ZoneSel_SemiAuto 0x0c +#define ZoneSel_Manual 0x0d +#define ZoneSel_Rotate 0x0e + +/* ov5640 Step Focus Commands */ +#define StepFocus_Near_Tag 0x01 +#define StepFocus_Far_Tag 0x02 +#define StepFocus_Furthest_Tag 0x03 +#define StepFocus_Nearest_Tag 0x04 +#define StepFocus_Spec_Tag 0x10 +#endif + +//flash off in fixed time to prevent from too hot , zyc +struct flash_timer{ + struct soc_camera_device *icd; + struct hrtimer timer; +}; +static enum hrtimer_restart flash_off_func(struct hrtimer *timer); + +static struct flash_timer flash_off_timer; +//for user defined if user want to customize the series , zyc +#ifdef CONFIG_OV5640_USER_DEFINED_SERIES +#include "ov5640_user_series.c" +#else + +/* init 800X600 SVGA */ +static struct reginfo sensor_init_data[] = +{ + {0x3103, 0x11}, + //{0x3008, 0x82}, + {0x3008, 0x42}, + {0x3103, 0x03}, + {0x3017, 0xff}, + {0x3018, 0xff}, + {0x3034, 0x1a}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x3037, 0x12}, + {0x3108, 0x01}, + {0x3630, 0x36}, + {0x3631, 0x0e}, + {0x3632, 0xe2}, + {0x3633, 0x12}, + {0x3621, 0xe0}, + {0x3704, 0xa0}, + {0x3703, 0x5a}, + {0x3715, 0x78}, + {0x3717, 0x01}, + {0x370b, 0x60}, + {0x3705, 0x1a}, + {0x3905, 0x02}, + {0x3906, 0x10}, + {0x3901, 0x0a}, + {0x3731, 0x12}, + {0x3600, 0x08}, + {0x3601, 0x33}, + {0x302d, 0x60}, + {0x3620, 0x52}, + {0x371b, 0x20}, + {0x471c, 0x50}, + {0x3a13, 0x43}, + {0x3a18, 0x00}, + {0x3a19, 0xf8}, + {0x3635, 0x13}, + {0x3636, 0x03}, + {0x3634, 0x40}, + {0x3622, 0x01}, + {0x3c01, 0x34}, + {0x3c04, 0x28}, + {0x3c05, 0x98}, + {0x3c06, 0x00}, + {0x3c07, 0x08}, + {0x3c08, 0x00}, + {0x3c09, 0x1c}, + {0x3c0a, 0x9c}, + {0x3c0b, 0x40}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9b}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3708, 0x64}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08, 0x01}, + {0x3a09, 0x27}, + {0x3a0a, 0x00}, + {0x3a0b, 0xf6}, + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4001, 0x02}, + {0x4004, 0x02}, + {0x3000, 0x00}, + {0x3002, 0x1c}, + {0x3004, 0xff}, + {0x3006, 0xc3}, + {0x300e, 0x58}, + {0x302e, 0x00}, + {0x4740, 0x20}, + {0x4300, 0x30}, + {0x501f, 0x00}, + {0x4713, 0x03}, + {0x4407, 0x04}, + {0x440e, 0x00}, + {0x460b, 0x35}, + {0x460c, 0x20}, + {0x4837, 0x22}, + {0x3824, 0x02}, + {0x5000, 0xa7}, + {0x5001, 0xa3}, + {0x5180, 0xff}, + {0x5181, 0xf2}, + {0x5182, 0x00}, + {0x5183, 0x14}, + {0x5184, 0x25}, + {0x5185, 0x24}, + {0x5186, 0x09}, + {0x5187, 0x09}, + {0x5188, 0x09}, + {0x5189, 0x75}, + {0x518a, 0x54}, + {0x518b, 0xe0}, + {0x518c, 0xb2}, + {0x518d, 0x42}, + {0x518e, 0x3d}, + {0x518f, 0x56}, + {0x5190, 0x46}, + {0x5191, 0xf8}, + {0x5192, 0x04}, + {0x5193, 0x70}, + {0x5194, 0xf0}, + {0x5195, 0xf0}, + {0x5196, 0x03}, + {0x5197, 0x01}, + {0x5198, 0x04}, + {0x5199, 0x12}, + {0x519a, 0x04}, + {0x519b, 0x00}, + {0x519c, 0x06}, + {0x519d, 0x82}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x5384, 0x0a}, + {0x5385, 0x7e}, + {0x5386, 0x88}, + {0x5387, 0x7c}, + {0x5388, 0x6c}, + {0x5389, 0x10}, + {0x538a, 0x01}, + {0x538b, 0x98}, + {0x5300, 0x08}, + {0x5301, 0x30}, + {0x5302, 0x10}, + {0x5303, 0x00}, + {0x5304, 0x08}, + {0x5305, 0x30}, + {0x5306, 0x08}, + {0x5307, 0x16}, + {0x5309, 0x08}, + {0x530a, 0x30}, + {0x530b, 0x04}, + {0x530c, 0x06}, + {0x5480, 0x01}, + {0x5481, 0x08}, + {0x5482, 0x14}, + {0x5483, 0x28}, + {0x5484, 0x51}, + {0x5485, 0x65}, + {0x5486, 0x71}, + {0x5487, 0x7d}, + {0x5488, 0x87}, + {0x5489, 0x91}, + {0x548a, 0x9a}, + {0x548b, 0xaa}, + {0x548c, 0xb8}, + {0x548d, 0xcd}, + {0x548e, 0xdd}, + {0x548f, 0xea}, + {0x5490, 0x1d}, + {0x5580, 0x02}, + {0x5583, 0x40}, + {0x5584, 0x10}, + {0x5589, 0x10}, + {0x558a, 0x00}, + {0x558b, 0xf8}, + {0x5800, 0x23}, + {0x5801, 0x14}, + {0x5802, 0x0f}, + {0x5803, 0x0f}, + {0x5804, 0x12}, + {0x5805, 0x26}, + {0x5806, 0x0c}, + {0x5807, 0x08}, + {0x5808, 0x05}, + {0x5809, 0x05}, + {0x580a, 0x08}, + {0x580b, 0x0d}, + {0x580c, 0x08}, + {0x580d, 0x03}, + {0x580e, 0x00}, + {0x580f, 0x00}, + {0x5810, 0x03}, + {0x5811, 0x09}, + {0x5812, 0x07}, + {0x5813, 0x03}, + {0x5814, 0x00}, + {0x5815, 0x01}, + {0x5816, 0x03}, + {0x5817, 0x08}, + {0x5818, 0x0d}, + {0x5819, 0x08}, + {0x581a, 0x05}, + {0x581b, 0x06}, + {0x581c, 0x08}, + {0x581d, 0x0e}, + {0x581e, 0x29}, + {0x581f, 0x17}, + {0x5820, 0x11}, + {0x5821, 0x11}, + {0x5822, 0x15}, + {0x5823, 0x28}, + {0x5824, 0x46}, + {0x5825, 0x26}, + {0x5826, 0x08}, + {0x5827, 0x26}, + {0x5828, 0x64}, + {0x5829, 0x26}, + {0x582a, 0x24}, + {0x582b, 0x22}, + {0x582c, 0x24}, + {0x582d, 0x24}, + {0x582e, 0x06}, + {0x582f, 0x22}, + {0x5830, 0x40}, + {0x5831, 0x42}, + {0x5832, 0x24}, + {0x5833, 0x26}, + {0x5834, 0x24}, + {0x5835, 0x22}, + {0x5836, 0x22}, + {0x5837, 0x26}, + {0x5838, 0x44}, + {0x5839, 0x24}, + {0x583a, 0x26}, + {0x583b, 0x28}, + {0x583c, 0x42}, + {0x583d, 0xce}, + {0x5025, 0x00}, + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a1b, 0x30}, + {0x3a1e, 0x26}, + {0x3a11, 0x60}, + {0x3a1f, 0x14}, + {0x3008, 0x02}, + {0x302c, 0xc2}, + {SEQUENCE_END, 0x00} +}; + +/* 720p 15fps @ 1280x720 */ + +static struct reginfo sensor_720p[]= +{ + {0x3503, 0x00}, + + {0x3c07,0x07}, + {0x3803,0xfa}, + {0x3806,0x06},//// + {0x3807,0xa9}, + {0x3808,0x05}, + {0x3809,0x00}, + {0x380a,0x02}, + {0x380b,0xd0}, + {0x380c,0x07}, + {0x380d,0x64}, + {0x380e,0x02}, + {0x380f,0xe4}, + {0x3813,0x04}, + {0x3a02,0x02}, + {0x3a03,0xe4}, + {0x3a08,0x01},/// + {0x3a09,0xbc},//// + {0x3a0a,0x01},/// + {0x3a0b,0x72},//// + {0x3a0e,0x01}, + {0x3a0d,0x02}, + {0x3a14,0x02}, + {0x3a15,0xe4}, + + {0x3820, 0x41}, //ddl@rock-chips.com add start: qsxvga -> 720p isn't stream on + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08 ,0x01},/// + {0x3a09, 0x27},/// + {0x3a0a, 0x00},/// + {0x3a0b, 0xf6},/// + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4004, 0x02}, + {0x3002, 0x1c},//// + {0x4713, 0x03},//////ddl@rock-chips.com add end + + {0x3002,0x00},/// + {0x4713,0x02},/// + {0x4837,0x16}, + {0x3824,0x04},/// + {0x5001,0x83}, + {0x3035,0x21}, + {0x3036,0x46}, + + {0x4837, 0x22}, + {0x5001, 0xa3}, + + {SEQUENCE_END, 0x00} +}; + +/* 1080p, 0x15fps, 0xyuv @1920x1080 */ + +static struct reginfo sensor_1080p[]= +{ + + {SEQUENCE_END, 0x00} +}; + +/* 2592X1944 QSXGA */ +static struct reginfo sensor_qsxga[] = +{ +#if 0 + {0x3503, 0x07}, + {0x3a00, 0x78}, + {0x350c, 0x00}, + {0x350d, 0x00}, + {0x3c07, 0x07}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x2c}, + {0x5001, 0x83}, +#else + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3811, 0x10}, // + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, //4b + {0x3708, 0x64}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x5000, 0xa7}, + {0x5001, 0x83}, + {0x519e, 0x38}, + {0x5381, 0x1e}, + {0x5382, 0x5b}, + {0x5383, 0x08}, + {0x460b, 0x37}, + {0x460c, 0x20}, + {0x3824, 0x01}, + {0x4005, 0x1A}, +#endif + {SEQUENCE_END, 0x00} +}; +/* 2048*1536 QXGA */ +static struct reginfo sensor_qxga[] = +{ +#if 0 + {0x3503, 0x07}, + {0x3a00, 0x78}, + {0x350c, 0x00}, + {0x350d, 0x00}, + {0x3c07, 0x07}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x08}, + {0x3809, 0x00}, + {0x380a, 0x06}, + {0x380b, 0x00}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x2c}, + {0x5001, 0xa3}, +#endif + {SEQUENCE_END, 0x00} +}; + +/* 1600X1200 UXGA */ +static struct reginfo sensor_uxga[] = +{ +#if 0 + {0x3503, 0x07}, + {0x3a00, 0x78}, + {0x350c, 0x00}, + {0x350d, 0x00}, + {0x3c07, 0x07}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x06}, + {0x3809, 0x40}, + {0x380a, 0x04}, + {0x380b, 0xb0}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x2c}, + {0x5001, 0xa3}, +#endif + {SEQUENCE_END, 0x00} +}; + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ +#if 0 + {0x3503, 0x07}, + {0x3a00, 0x78}, + {0x350c, 0x00}, + {0x350d, 0x00}, + {0x3c07, 0x07}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x04}, + {0x380b, 0x00}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x2c}, + {0x5001, 0xa3}, +#endif + {SEQUENCE_END, 0x00} +}; +/* 1024X768 XGA */ +static struct reginfo sensor_xga[] = +{ +#if 0 + {0x3503, 0x07}, + {0x3a00, 0x78}, + {0x350c, 0x00}, + {0x350d, 0x00}, + {0x3c07, 0x07}, + {0x3820, 0x40}, + {0x3821, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3803, 0x00}, + {0x3807, 0x9f}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x04}, + {0x380b, 0x00}, + {0x380c, 0x0b}, + {0x380d, 0x1c}, + {0x380e, 0x07}, + {0x380f, 0xb0}, + {0x3813, 0x04}, + {0x3618, 0x04}, + {0x3612, 0x2b}, + {0x3709, 0x12}, + {0x370c, 0x00}, + {0x3a02, 0x07}, + {0x3a03, 0xb0}, + {0x3a0e, 0x06}, + {0x3a0d, 0x08}, + {0x3a14, 0x07}, + {0x3a15, 0xb0}, + {0x4004, 0x06}, + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x2c}, + {0x5001, 0xa3}, +#endif + {SEQUENCE_END, 0x00} +}; +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0x3503, 0x00}, + {0x3c07, 0x08}, + {0x3820, 0x41}, + {0x3821, 0x07}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3803, 0x04}, + {0x3806, 0x07},/// + {0x3807, 0x9b}, + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + {0x380c, 0x07}, + {0x380d, 0x68}, + {0x380e, 0x03}, + {0x380f, 0xd8}, + {0x3813, 0x06}, + {0x3618, 0x00}, + {0x3612, 0x29}, + {0x3709, 0x52}, + {0x370c, 0x03}, + {0x3a02, 0x03}, + {0x3a03, 0xd8}, + {0x3a08 ,0x01},/// + {0x3a09, 0x27},/// + {0x3a0a, 0x00},/// + {0x3a0b, 0xf6},/// + {0x3a0e, 0x03}, + {0x3a0d, 0x04}, + {0x3a14, 0x03}, + {0x3a15, 0xd8}, + {0x4004, 0x02}, + {0x3002, 0x1c},//// + {0x4713, 0x03},//// + {0x3035, 0x21}, + {0x3036, 0x46}, + {0x4837, 0x22}, + {0x3824, 0x02},//// + {0x5001, 0xa3}, + {SEQUENCE_END, 0x00} +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ + + {SEQUENCE_END, 0x00} +}; +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + + {SEQUENCE_END, 0x00} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ + + {SEQUENCE_END, 0x00} +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + + {SEQUENCE_END, 0x00} +}; +#endif +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + {0x4300,0x30}, + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + {0x4300,0x32}, + {SEQUENCE_END, 0x00} +}; + + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0x3406 ,0x00}, + {0x5192 ,0x04}, + {0x5191 ,0xf8}, + {0x5193 ,0x70}, + {0x5194 ,0xf0}, + {0x5195 ,0xf0}, + {0x518d ,0x3d}, + {0x518f ,0x54}, + {0x518e ,0x3d}, + {0x5190 ,0x54}, + {0x518b ,0xa8}, + {0x518c ,0xa8}, + {0x5187 ,0x18}, + {0x5188 ,0x18}, + {0x5189 ,0x6e}, + {0x518a ,0x68}, + {0x5186 ,0x1c}, + {0x5181 ,0x50}, + {0x5184 ,0x25}, + {0x5182 ,0x11}, + {0x5183 ,0x14}, + {0x5184 ,0x25}, + {0x5185 ,0x24}, + {SEQUENCE_END, 0x00} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x6 }, + {0x3401 ,0x48}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x4 }, + {0x3405 ,0xd3 }, + {SEQUENCE_END, 0x00} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x6 }, + {0x3401 ,0x1c}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x4 }, + {0x3405 ,0xf3}, + {SEQUENCE_END, 0x00} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x5 }, + {0x3401 ,0x48}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x7 }, + {0x3405 ,0xcf}, + {SEQUENCE_END, 0x00} +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + {0x3406 ,0x1 }, + {0x3400 ,0x4 }, + {0x3401 ,0x10}, + {0x3402 ,0x4 }, + {0x3403 ,0x0 }, + {0x3404 ,0x8 }, + {0x3405 ,0xb6}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Brightness1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness2[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Brightness3[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Brightness4[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Brightness5[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0x5001, 0x7f}, + {0x5580, 0x00}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Effect_WandB[] = +{ + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x80}, + {0x5584, 0x80}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Effect_Sepia[] = +{ + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x40}, + {0x5584, 0xa0}, + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + //Negative + {0x5001, 0xff}, + {0x5580, 0x40}, + {SEQUENCE_END, 0x00} +};static struct reginfo sensor_Effect_Bluish[] = +{ + // Bluish + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0xa0}, + {0x5584, 0x40}, + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + // Greenish + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x60}, + {0x5584, 0x60}, + {SEQUENCE_END, 0x00} +}; +/*static struct reginfo sensor_Effect_Reddish[] = +{ + // Greenish + {0x5001, 0xff}, + {0x5580, 0x18}, + {0x5583, 0x80}, + {0x5584, 0xc0}, + {SEQUENCE_END, 0x00} +};*/ + +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + {0x3a0f, 0x10}, + {0x3a10, 0x08}, + {0x3a1b, 0x10}, + {0x3a1e, 0x08}, + {0x3a11, 0x20}, + {0x3a1f, 0x10}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Exposure1[]= +{ + {0x3a0f, 0x20}, + {0x3a10, 0x18}, + {0x3a11, 0x41}, + {0x3a1b, 0x20}, + {0x3a1e, 0x18}, + {0x3a1f, 0x10}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Exposure2[]= +{ + {0x3a0f, 0x30}, + {0x3a10, 0x28}, + {0x3a11, 0x61}, + {0x3a1b, 0x30}, + {0x3a1e, 0x28}, + {0x3a1f, 0x10}, + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Exposure3[]= +{ + {0x3a0f, 0x38}, + {0x3a10, 0x30}, + {0x3a11, 0x61}, + {0x3a1b, 0x38}, + {0x3a1e, 0x30}, + {0x3a1f, 0x10}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Exposure4[]= +{ + {0x3a0f, 0x40}, + {0x3a10, 0x38}, + {0x3a11, 0x71}, + {0x3a1b, 0x40}, + {0x3a1e, 0x38}, + {0x3a1f, 0x10}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Exposure5[]= +{ + {0x3a0f, 0x50}, + {0x3a10, 0x48}, + {0x3a11, 0x90}, + {0x3a1b, 0x50}, + {0x3a1e, 0x48}, + {0x3a1f, 0x20}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Exposure6[]= +{ + {0x3a0f, 0x60}, + {0x3a10, 0x58}, + {0x3a11, 0xa0}, + {0x3a1b, 0x60}, + {0x3a1e, 0x58}, + {0x3a1f, 0x20}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {SEQUENCE_END, 0x00} +};static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast1[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Contrast2[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast3[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast4[]= +{ + {SEQUENCE_END, 0x00} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Contrast6[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_MirrorOff[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif +#if CONFIG_SENSOR_Scene +static struct reginfo sensor_SceneAuto[] = +{ + {0x3a00 , 0x78}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_SceneNight[] = +{ + //15fps ~ 3.75fps night mode for 60/50Hz light environment, 24Mhz clock input,24Mzh pclk + {0x3034 ,0x1a}, + {0x3035 ,0x21}, + {0x3036 ,0x46}, + {0x3037 ,0x13}, + {0x3038 ,0x00}, + {0x3039 ,0x00}, + {0x3a00 ,0x7c}, + {0x3a08 ,0x01}, + {0x3a09 ,0x27}, + {0x3a0a ,0x00}, + {0x3a0b ,0xf6}, + {0x3a0d ,0x04}, + {0x3a0e ,0x04}, + {0x3a02 ,0x0b}, + {0x3a03 ,0x88}, + {0x3a14 ,0x0b}, + {0x3a15 ,0x88}, + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo sensor_Zoom1[] = +{ + {SEQUENCE_END, 0x00} +}; + +static struct reginfo sensor_Zoom2[] = +{ + {SEQUENCE_END, 0x00} +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {SEQUENCE_END, 0x00} +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL}; +#endif +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + /*{ + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + },*/ + { + .id = V4L2_CID_FOCUSZONE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "FocusZone Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + },{ + .id = V4L2_CID_FOCUS_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Focus Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #if CONFIG_SENSOR_FocusContinues + { + .id = V4L2_CID_FOCUS_CONTINUOUS, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Focus Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +enum sensor_wq_cmd +{ + WqCmd_af_init, + WqCmd_af_single, + WqCmd_af_special_pos, + WqCmd_af_far_pos, + WqCmd_af_near_pos, + WqCmd_af_continues, + WqCmd_af_return_idle, +}; +enum sensor_wq_result +{ + WqRet_success = 0, + WqRet_fail = -1, + WqRet_inval = -2 +}; +struct sensor_work +{ + struct i2c_client *client; + struct delayed_work dwork; + enum sensor_wq_cmd cmd; + wait_queue_head_t done; + enum sensor_wq_result result; + bool wait; + int var; + int zone_center_pos[2]; +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int auto_focus; + int affm_reinit; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + struct reginfo *winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int enable; + unsigned int funmodule_state; +} sensor_info_priv_t; + + + +struct sensor_parameter +{ + unsigned short int preview_maxlines; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int capture_framerate; + unsigned short int preview_framerate; + char awb[6]; +}; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + struct sensor_parameter parameter; + struct workqueue_struct *sensor_wq; + struct mutex wq_lock; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + + +#if CONFIG_SENSOR_WRITE_REGS +static int sensor_write_regs(struct i2c_client *client, u8 *reg_info, int num) +{ + int err=0,cnt; + struct i2c_msg msg[1]; + + msg->len = num; + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = reg_info; + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + + cnt= 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg failed, try to write again!\n", SENSOR_NAME_STRING()); + udelay(10); + } + } + + return err; + +} + +#endif + + + + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u16 reg, u8 val) +{ + int err,cnt; + u8 buf[3]; + struct i2c_msg msg[1]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + buf[2] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u16 reg, u8 *val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[2]; + + buf[0] = reg >> 8; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err = 0, cnt; + int i = 0; +#if CONFIG_SENSOR_Focus + struct sensor *sensor = to_sensor(client); +#endif +#if CONFIG_SENSOR_I2C_RDWRCHK + char valchk; +#endif +#if CONFIG_SENSOR_WRITE_REGS + int j = 0, reg_num; + u8 *ptemp, *phead; + int reg_length; +#endif + + cnt = 0; + if (sensor_task_lock(client, 1) < 0) + goto sensor_write_array_end; + while (regarray[i].reg != SEQUENCE_END) { + #if CONFIG_SENSOR_Focus + if ((regarray == sensor_af_firmware) && (sensor->info_priv.enable == 0)) { + SENSOR_DG("%s disable, Download af firmware terminated!\n",SENSOR_NAME_STRING()); + err = -EINVAL; + goto sensor_write_array_end; + } + #endif + +#if CONFIG_SENSOR_WRITE_REGS + + j = i; + reg_num = 2; + reg_length = 0x0001; + + while((regarray[i].reg + reg_length) == regarray[i+1].reg) { + i++; + reg_num++; + if(reg_num >= WRITE_REGS_NUM) + break; + } + + if(reg_num > 2) { + + int size_num; + size_num = reg_num + 1; + + ptemp = phead = (u8*)kmalloc((size_num+10)*sizeof(u8),GFP_KERNEL); + if (!phead) { + SENSOR_DG("-------------write registers allocate memory fail!!!\n"); + i = j; + err = sensor_write(client, regarray[i].reg, regarray[i].val); + } else { + *phead = regarray[j].reg >> 8; + *(ptemp+1) = regarray[j].reg & 0xFF; + ptemp += 2; + for( ; reg_num > 0; reg_num --, j++) { + *ptemp ++ = regarray[j].val; + } + + ptemp = phead; + err = sensor_write_regs(client, ptemp,size_num); + kfree(phead); + } + }else{ + err = sensor_write(client, regarray[i].reg, regarray[i].val); + } +#else + err = sensor_write(client, regarray[i].reg, regarray[i].val); +#endif + if (err < 0) + { + if (cnt-- > 0) { + SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg); + i = 0; + continue; + } else { + SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING()); + err = -EPERM; + goto sensor_write_array_end; + } + } else { + #if CONFIG_SENSOR_I2C_RDWRCHK + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + #endif + } + i++; + } + + #if CONFIG_SENSOR_Focus + if (((regarray->reg == SEQUENCE_PROPERTY) && (regarray->val == SEQUENCE_INIT)) + || (regarray == sensor_init_data)) { + sensor->info_priv.affm_reinit = 1; + } + #endif + +sensor_write_array_end: + sensor_task_lock(client,0); + return err; +} +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) +{ + int cnt; + int i = 0; + char valchk; + + cnt = 0; + valchk = 0; + while (regarray[i].reg != 0) + { + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + + i++; + } + return 0; +} +#endif +#if CONFIG_SENSOR_Focus +struct af_cmdinfo +{ + char cmd_tag; + char cmd_para[4]; + char validate_bit; +}; +static int sensor_af_cmdset(struct i2c_client *client, int cmd_main, struct af_cmdinfo *cmdinfo) +{ + int i; + char read_tag=0xff,cnt; + + if (cmdinfo) { + for (i=0; i<4; i++) { + if (cmdinfo->validate_bit & (1<cmd_para[i])) { + SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]); + } + } + + if (cmdinfo->validate_bit & 0x80) { + if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) { + SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag); + } + + } else { + if (sensor_write(client, CMD_ACK_Reg, 0x01)) { + SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main); + goto sensor_af_cmdset_err; + } + SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x no tag) success!\n",SENSOR_NAME_STRING(),cmd_main); + } + + if (sensor_write(client, CMD_MAIN_Reg, cmd_main)) { + SENSOR_TR("%s write CMD_MAIN_Reg(main:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main); + goto sensor_af_cmdset_err; + } + + cnt = 0; + do + { + msleep(5); + if (sensor_read(client,CMD_ACK_Reg,&read_tag)){ + SENSOR_TR("%s[%d] read TAG failed\n",SENSOR_NAME_STRING(),__LINE__); + break; + } + } while((read_tag != 0x00)&& (cnt++<100)); + + SENSOR_DG("%s write CMD_MAIN_Reg(main:0x%x read tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,read_tag); + return 0; +sensor_af_cmdset_err: + return -1; +} + +static int sensor_af_idlechk(struct i2c_client *client) +{ + int ret = 0; + char state; + struct af_cmdinfo cmdinfo; + + SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__); + + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x80; + ret = sensor_af_cmdset(client, ReturnIdle_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_idlechk_end; + } + + + do{ + ret = sensor_read(client, CMD_ACK_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_idlechk_end; + } + }while(0x00 != state); + + +sensor_af_idlechk_end: + return ret; +} +static int sensor_af_touch_zone(struct i2c_client *client, int *zone_center_pos) +{ + int ret = 0; + struct af_cmdinfo cmdinfo; + + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x83; + if (zone_center_pos[0]<=8) + cmdinfo.cmd_para[0] = 0; + else if ((zone_center_pos[0]>8) && (zone_center_pos[0]<72)) + cmdinfo.cmd_para[0] = zone_center_pos[0]-8; + else + cmdinfo.cmd_para[0] = 72; + + if (zone_center_pos[1]<=6) + cmdinfo.cmd_para[1] = 0; + else if ((zone_center_pos[1]>6) && (zone_center_pos[1]<54)) + cmdinfo.cmd_para[1] = zone_center_pos[1]-6; + else + cmdinfo.cmd_para[1] = 54; + + ret = sensor_af_cmdset(client, TouchZoneConfig_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s touch zone config error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_zone_end; + } +sensor_af_zone_end: + return ret; +} +static int sensor_af_single(struct i2c_client *client) +{ + int ret = 0; + char state,cnt; + struct af_cmdinfo cmdinfo; + char s_zone[5],i; + + cmdinfo.cmd_tag = 0x01; + cmdinfo.validate_bit = 0x80; + ret = sensor_af_cmdset(client, SingleFocus_Cmd, &cmdinfo); + if(0 != ret) { + SENSOR_TR("%s single focus mode set error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_single_end; + } + + cnt = 0; + do + { + if (cnt != 0) { + msleep(1); + } + cnt++; + ret = sensor_read(client, STA_FOCUS_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_single_end; + } + }while((state == S_FOCUSING) && (cnt<100)); + + if (state != S_FOCUSED) { + SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state); + ret = -1; + goto sensor_af_single_end; + } else { + SENSOR_DG("%s[%d] single focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); + } +sensor_af_single_end: + return ret; +} + +static int sensor_af_const(struct i2c_client *client) +{ + int ret = 0; + struct af_cmdinfo cmdinfo; + + + cmdinfo.cmd_tag = 0x01; + cmdinfo.cmd_para[0] = 0x00; + cmdinfo.validate_bit = 0x81; + + if (sensor_af_cmdset(client, ConstFocus_Cmd, &cmdinfo)) { + SENSOR_TR("%s[%d] const focus mode set error!\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_const_end; + } else { + SENSOR_DG("%s[%d] const focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); + } +sensor_af_const_end: + return ret; +} +static int sensor_af_pause2capture(struct i2c_client *client) +{ + int ret = 0; + + if (sensor_af_cmdset(client, PauseFocus_Cmd, NULL)) { + SENSOR_TR("%s pause focus mode set error!\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_pause_end; + } +sensor_af_pause_end: + return ret; +} + +static int sensor_af_init(struct i2c_client *client) +{ + int ret = 0, cnt; + char state; + + ret = sensor_write_array(client, sensor_af_firmware); + if (ret != 0) { + SENSOR_TR("%s Download firmware failed\n",SENSOR_NAME_STRING()); + ret = -1; + goto sensor_af_init_end; + } + + cnt = 0; + do + { + msleep(1); + if (cnt++ > 500) + break; + ret = sensor_read(client, STA_FOCUS_Reg, &state); + if (ret != 0){ + SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__); + ret = -1; + goto sensor_af_init_end; + } + } while (state != S_IDLE); + + if (state != S_IDLE) { + SENSOR_TR("%s focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),state); + ret = -1; + goto sensor_af_init_end; + } + +sensor_af_init_end: + SENSOR_DG("%s %s ret:0x%x \n",SENSOR_NAME_STRING(),__FUNCTION__,ret); + return ret; +} + +static int sensor_af_downfirmware(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + int ret=0; + struct soc_camera_device *icd = client->dev.platform_data; + struct v4l2_mbus_framefmt mf; + + SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__); + + if (sensor_af_init(client)) { + sensor->info_priv.funmodule_state &= (~SENSOR_AF_IS_OK); + ret = -1; + } else { + sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; + + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; + if (sensor_fmt_videochk(NULL, &mf) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ + ret = sensor_af_const(client); + } else { + switch (sensor->info_priv.auto_focus) + { + case SENSOR_AF_MODE_AUTO: + { + ret = sensor_af_single(client); + break; + } + case SENSOR_AF_MODE_CLOSE: + { + ret = 0; + break; + } + case SENSOR_AF_MODE_CONTINUOUS: + { + ret = sensor_af_const(client); + break; + } + default: + { + SENSOR_DG("%s focus mode(0x%x) is unkonwn\n",SENSOR_NAME_STRING(),sensor->info_priv.auto_focus); + goto sensor_af_downfirmware_end; + } + } + } + SENSOR_DG("%s sensor_af_downfirmware set focus mode(0x%x) ret:0x%x\n",SENSOR_NAME_STRING(), sensor->info_priv.auto_focus,ret); + } + +sensor_af_downfirmware_end: + + return ret; +} +static void sensor_af_workqueue(struct work_struct *work) +{ + struct sensor_work *sensor_work = container_of(work, struct sensor_work, dwork.work); + struct i2c_client *client = sensor_work->client; + struct sensor *sensor = to_sensor(client); + struct af_cmdinfo cmdinfo; + + SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd); + + mutex_lock(&sensor->wq_lock); + + switch (sensor_work->cmd) + { + case WqCmd_af_init: + { + if (sensor_af_downfirmware(client) < 0) { + SENSOR_TR("%s Sensor_af_init is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); + } + break; + } + case WqCmd_af_single: + { + if ((sensor_work->zone_center_pos[0] >=0) && (sensor_work->zone_center_pos[1]>=0)) + sensor_af_touch_zone(client,sensor_work->zone_center_pos); + + if (sensor_af_single(client) < 0) { + SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING()); + sensor_work->result = WqRet_fail; + } else { + sensor_work->result = WqRet_success; + } + break; + } + case WqCmd_af_special_pos: + { + sensor_af_idlechk(client); + + cmdinfo.cmd_tag = StepFocus_Spec_Tag; + cmdinfo.cmd_para[0] = sensor_work->var; + cmdinfo.validate_bit = 0x81; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_near_pos: + { + sensor_af_idlechk(client); + cmdinfo.cmd_tag = StepFocus_Near_Tag; + cmdinfo.validate_bit = 0x80; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_far_pos: + { + sensor_af_idlechk(client); + cmdinfo.cmd_tag = StepFocus_Far_Tag; + cmdinfo.validate_bit = 0x80; + if (sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_continues: + { + if (sensor_af_const(client) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + case WqCmd_af_return_idle: + { + if (sensor_af_idlechk(client) < 0) + sensor_work->result = WqRet_fail; + else + sensor_work->result = WqRet_success; + break; + } + default: + SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING()); + break; + } +set_end: + if (sensor_work->wait == false) { + kfree((void*)sensor_work); + } else { + wake_up(&sensor_work->done); + } + mutex_unlock(&sensor->wq_lock); + return; +} + +static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait, int *zone_pos) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + struct sensor_work *wk; + int ret=0; + + if (sensor->sensor_wq == NULL) { + ret = -EINVAL; + goto sensor_af_workqueue_set_end; + } + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) != SENSOR_AF_IS_OK) { + if (cmd != WqCmd_af_init) { + SENSOR_TR("%s %s cmd(%d) ingore,because af module isn't ready!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + ret = -1; + goto sensor_af_workqueue_set_end; + } + } + + wk = kzalloc(sizeof(struct sensor_work), GFP_KERNEL); + if (wk) { + wk->client = client; + INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue); + wk->cmd = cmd; + wk->result = WqRet_inval; + wk->wait = wait; + wk->var = var; + + if (zone_pos) { + if (*zone_pos || *(zone_pos+1) || *(zone_pos+2) || *(zone_pos+3)) { + *zone_pos += 1000; + *(zone_pos+1) += 1000; + *(zone_pos+2) += 1000; + *(zone_pos+3) += 1000; + wk->zone_center_pos[0] = ((*zone_pos + *(zone_pos+2))>>1)*80/2000; + wk->zone_center_pos[1] = ((*(zone_pos+1) + *(zone_pos+3))>>1)*60/2000; + } else { + #if CONFIG_SENSOR_FocusCenterInCapture + wk->zone_center_pos[0] = 32; + wk->zone_center_pos[1] = 24; + #else + wk->zone_center_pos[0] = -1; + wk->zone_center_pos[1] = -1; + #endif + } + } + + init_waitqueue_head(&wk->done); + + /* ddl@rock-chips.com: + * video_lock is been locked in v4l2_ioctl function, but auto focus may slow, + * As a result any other ioctl calls will proceed very, very slowly since each call + * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF + * and VIDIOC_DQBUF is sched. so unlock video_lock here. + */ + if (wait == true) { + queue_delayed_work(sensor->sensor_wq,&(wk->dwork),0); + mutex_unlock(&icd->video_lock); + if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) { //hhb + SENSOR_TR("%s %s cmd(%d) is timeout!\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + } + ret = wk->result; + kfree((void*)wk); + mutex_lock(&icd->video_lock); + } else { + queue_delayed_work(sensor->sensor_wq,&(wk->dwork),msecs_to_jiffies(10)); + } + + } else { + SENSOR_TR("%s %s cmd(%d) ingore,because struct sensor_work malloc failed!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + ret = -1; + } +sensor_af_workqueue_set_end: + return ret; +} +#endif +static int sensor_parameter_record(struct i2c_client *client) +{ + u8 ret_l,ret_m,ret_h; + int tp_l,tp_m,tp_h; + struct sensor *sensor = to_sensor(client); + + sensor_read(client,0x3a00, &ret_l); + sensor_write(client,0x3a00, ret_l&0xfb); + + sensor_write(client,0x3503,0x07); //stop AE/AG + sensor_read(client,0x3406, &ret_l); + sensor_write(client,0x3406, ret_l|0x01); + + sensor_read(client,0x3500,&ret_h); + sensor_read(client,0x3501, &ret_m); + sensor_read(client,0x3502, &ret_l); + tp_l = ret_l; + tp_m = ret_m; + tp_h = ret_h; + sensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F); + + //Read back AGC Gain for preview + sensor_read(client,0x350b, &ret_l); + sensor->parameter.preview_gain = ret_l; + + SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n", + SENSOR_NAME_STRING(), tp_l,sensor->parameter.preview_exposure,tp_h, tp_m, tp_l); + return 0; +} +#define OV5640_FULL_PERIOD_PIXEL_NUMS_HTS (2844) +#define OV5640_FULL_PERIOD_LINE_NUMS_VTS (1968) +#define OV5640_PV_PERIOD_PIXEL_NUMS_HTS (1896) +#define OV5640_PV_PERIOD_LINE_NUMS_VTS (984) +static int sensor_ae_transfer(struct i2c_client *client) +{ + u8 ExposureLow; + u8 ExposureMid; + u8 ExposureHigh; + u16 ulCapture_Exposure; + u16 Preview_Maxlines; + u8 Gain; + u16 OV5640_g_iExtra_ExpLines; + struct sensor *sensor = to_sensor(client); + + //Preview_Maxlines = sensor->parameter.preview_line_width; + Preview_Maxlines = sensor->parameter.preview_maxlines; + Gain = sensor->parameter.preview_gain; + + + ulCapture_Exposure = (sensor->parameter.preview_exposure*OV5640_PV_PERIOD_PIXEL_NUMS_HTS)/OV5640_FULL_PERIOD_PIXEL_NUMS_HTS; + + SENSOR_DG("cap shutter calutaed = %d, 0x%x\n", ulCapture_Exposure,ulCapture_Exposure); + + // write the gain and exposure to 0x350* registers + sensor_write(client,0x350b, Gain); + + if (ulCapture_Exposure <= 1940) { + OV5640_g_iExtra_ExpLines = 0; + }else { + OV5640_g_iExtra_ExpLines = ulCapture_Exposure - 1940; + } + SENSOR_DG("Set Extra-line = %d, iExp = %d \n", OV5640_g_iExtra_ExpLines, ulCapture_Exposure); + + ExposureLow = (ulCapture_Exposure<<4)&0xff; + ExposureMid = (ulCapture_Exposure>>4)&0xff; + ExposureHigh = (ulCapture_Exposure>>12); + + sensor_write(client,0x350c, (OV5640_g_iExtra_ExpLines&0xff00)>>8); + sensor_write(client,0x350d, OV5640_g_iExtra_ExpLines&0xff); + sensor_write(client,0x3502, ExposureLow); + sensor_write(client,0x3501, ExposureMid); + sensor_write(client,0x3500, ExposureHigh); + + SENSOR_DG(" %s Write 0x350b=0x%02x 0x350c=0x%2x 0x350d=0x%2x 0x3502=0x%02x 0x3501=0x%02x 0x3500=0x%02x\n",SENSOR_NAME_STRING(), Gain, ExposureLow, ExposureMid, ExposureHigh); + mdelay(100); + return 0; +} + +static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + int ret = 0; + + SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); + + switch (cmd) + { + case Sensor_PowerDown: + { + if (icl->powerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(2); + if (icl->reset) + icl->reset(icd->pdev); + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + if(on == Flash_On){ + //flash off after 2 secs + hrtimer_cancel(&(flash_off_timer.timer)); + hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL); + } + } + break; + } + default: + { + SENSOR_TR("%s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd); + break; + } + } + +sensor_power_end: + return ret; +} + +static enum hrtimer_restart flash_off_func(struct hrtimer *timer){ + struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer); + sensor_ioctrl(fps_timer->icd,Sensor_Flash,0); + SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__); + return 0; + +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + char value; + int ret,pid = 0; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + ret = sensor_write(client, 0x3008, 0x80); + if (ret != 0) { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); //delay 5 microseconds + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x300a, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x300b, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x \n", SENSOR_NAME_STRING(), pid); + + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + ret = sensor_write_array(client, sensor_init_data); + udelay(1000); //wait sensor power on,so that I2C write sensor registers would sucess hhb@rock-chips.con + + if (ret != 0) { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + sensor_task_lock(client,0); + sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + flash_off_timer.icd = icd; + flash_off_timer.timer.function = flash_off_func; + #endif + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + + sensor->info_priv.funmodule_state = SENSOR_INIT_IS_OK; + + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_task_lock(client, 1); + sensor_write(client, 0x3017, 0x00); // FREX,VSYNC,HREF,PCLK,D9-D6 + sensor_write(client, 0x3018, 0x03); // D5-D0 + sensor_write(client,0x3019,0x00); // STROBE,SDA + sensor_task_lock(client, 0); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; +} + +static struct reginfo sensor_power_down_sequence[]= +{ + {0x00,0x00} +}; + +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + return 0; +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret = 0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_svga; + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_xga; + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_720p; + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_uxga; + set_w = 1600; + set_h = 1200; + } + else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_1080p; + set_w = 1920; + set_h = 1080; + } + else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_qxga; + set_w = 2048; + set_h = 1536; + } + else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) + { + winseqe_set_addr = sensor_qsxga; + set_w = 2592; + set_h = 1944; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + + if (winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) + { + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + sensor_parameter_record(client); + #if CONFIG_SENSOR_Focus + if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CONTINUOUS) + sensor_af_pause2capture(client); + #endif + #if CONFIG_SENSOR_Flash + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + #endif + }else { /* ddl@rock-chips.com : Video */ + #if CONFIG_SENSOR_Flash + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + #endif + } + if ((sensor->info_priv.winseqe_cur_addr->reg == SEQUENCE_PROPERTY) && (sensor->info_priv.winseqe_cur_addr->val == SEQUENCE_INIT)) { + if (((winseqe_set_addr->reg == SEQUENCE_PROPERTY) && (winseqe_set_addr->val == SEQUENCE_NORMAL)) + || (winseqe_set_addr->reg != SEQUENCE_PROPERTY)) { + ret |= sensor_write_array(client,sensor_init_data); + udelay(1000); //wait sensor power on,so that I2C write sensor registers would sucess hhb@rock-chips.con + SENSOR_DG("\n%s reinit ret:0x%x \n",SENSOR_NAME_STRING(), ret); + } + } + + if ((winseqe_set_addr == sensor_qsxga) && (sensor->info_priv.winseqe_cur_addr == sensor_720p)) { + sensor_write_array(client, sensor_svga); + } + + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + sensor_ae_transfer(client); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.snap2preview == true) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + #if CONFIG_SENSOR_Focus + if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CLOSE) { + msleep(500); + } else { + sensor_af_workqueue_set(icd,WqCmd_af_return_idle,0,false,NULL); + if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_CONTINUOUS) { + sensor_af_workqueue_set(icd,WqCmd_af_continues,0,false,NULL); + } + + msleep(300); + } + #else + msleep(500); + #endif + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + mf->width = set_w; + mf->height = set_h; +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) + { + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END)) + { + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END)) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END)) + { + set_w = 800; + set_h = 600; + } + else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END)) + { + set_w = 1024; + set_h = 768; + } + else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END)) + { + set_w = 1280; + set_h = 720; + } + else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END)) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END)) + { + set_w = 1600; + set_h = 1200; + } + else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END)) + { + set_w = 1920; + set_h = 1080; + } + else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END)) + { + set_w = 2048; + set_h = 1536; + } + else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END)) + { + set_w = 2592; + set_h = 1944; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV2655 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n%s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + { + *value = digitalzoom_total - digitalzoom_cur; + } + + if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + { + *value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += *value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Focus +static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int ret = 0; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (!qctrl_info) + return -EINVAL; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { + ret = sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true,NULL); + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EINVAL; + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + } + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } + + return ret; +} +static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int ret = 0; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE); + if (!qctrl_info) + return -EINVAL; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { + if (value > 0) { + ret = sensor_af_workqueue_set(icd, WqCmd_af_near_pos, 0, true,NULL); + } else { + ret = sensor_af_workqueue_set(icd, WqCmd_af_far_pos, 0, true,NULL); + } + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EINVAL; + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + } + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } + return ret; +} + +static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int *zone_pos) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int ret = 0; + + if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { + switch (value) + { + case SENSOR_AF_MODE_AUTO: + { + ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true, zone_pos); + break; + } + + /*case SENSOR_AF_MODE_MACRO: + { + ret = sensor_set_focus_absolute(icd, qctrl, 0xff); + break; + } + + case SENSOR_AF_MODE_INFINITY: + { + ret = sensor_set_focus_absolute(icd, qctrl, 0x00); + break; + } + */ + case SENSOR_AF_MODE_CONTINUOUS: + { + ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true,NULL); + break; + } + default: + SENSOR_TR("\n %s..%s AF value(0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__,value); + break; + + } + + SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret); + } else { + ret = -EACCES; + SENSOR_TR("\n %s..%s AF module state(0x%x, 0x%x) is error!\n",SENSOR_NAME_STRING(),__FUNCTION__, + sensor->info_priv.funmodule_state,sensor->info_priv.affm_reinit); + } + + return ret; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %d\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = 0x%x is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + sensor_set_focus_relative(icd, qctrl,ext_ctrl->value); + break; + } + case V4L2_CID_FOCUS_AUTO: + { + if (ext_ctrl->value) { + if ((ext_ctrl->value==1) || (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus)) { + if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO,ext_ctrl->rect) != 0) { + if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; + } + return -EINVAL; + } + } + if (ext_ctrl->value == 1) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO; + } else if (SENSOR_AF_MODE_AUTO == sensor->info_priv.auto_focus){ + if (ext_ctrl->value == 0) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; + } + break; + } + case V4L2_CID_FOCUS_CONTINUOUS: + { + if (SENSOR_AF_MODE_CONTINUOUS != sensor->info_priv.auto_focus) { + if (ext_ctrl->value == 1) { + if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_CONTINUOUS,NULL) != 0) { + if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) { + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; + } + return -EINVAL; + } + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CONTINUOUS; + } + } else { + if (ext_ctrl->value == 0) + sensor->info_priv.auto_focus = SENSOR_AF_MODE_CLOSE; + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + #if CONFIG_SENSOR_Focus + struct soc_camera_device *icd = client->dev.platform_data; + struct v4l2_mbus_framefmt mf; + #endif + + if (enable == 1) { + sensor->info_priv.enable = 1; + #if CONFIG_SENSOR_Focus + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; + /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ + if (sensor_fmt_capturechk(sd, &mf) == false) { + if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { + sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false,NULL); + sensor->info_priv.affm_reinit = 0; + } + } + #endif + } else if (enable == 0) { + sensor->info_priv.enable = 0; + #if CONFIG_SENSOR_Focus + flush_workqueue(sensor->sensor_wq); + #endif + } + return 0; +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char value; + int ret,pid = 0; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + /* soft reset */ + ret = sensor_write(client, 0x3008, 0x80); + if (ret != 0) { + SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + mdelay(5); //delay 5 microseconds + + /* check if it is an sensor sensor */ + ret = sensor_read(client, 0x300a, &value); + if (ret != 0) { + SENSOR_TR("read chip id high byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value << 8); + + ret = sensor_read(client, 0x300b, &value); + if (ret != 0) { + SENSOR_TR("read chip id low byte failed\n"); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + pid |= (value & 0xff); + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + return 0; + +sensor_video_probe_err: + return ret; +} +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0,i; + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + #if CONFIG_SENSOR_Flash //hhb + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + #endif + sensor_deactivate(client); + break; + } + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + printk("flash io:%d\n",sensor->sensor_gpio_res->gpio_flash); + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + sensor_controls[i].id=0xffff; + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + }else{ //two cameras are the same,need to deal diffrently ,zyc + for (i = 0; i < icd->ops->num_controls; i++) { + if(0xffff == icd->ops->controls[i].id){ + sensor_controls[i].id=V4L2_CID_FLASH; + } + } + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } + +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, + .s_stream = sensor_s_stream, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } else { + #if CONFIG_SENSOR_Focus + sensor->sensor_wq = create_singlethread_workqueue(SENSOR_NAME_STRING(_af_workqueue)); + if (sensor->sensor_wq == NULL) + SENSOR_TR("%s create fail!", SENSOR_NAME_STRING(_af_workqueue)); + mutex_init(&sensor->wq_lock); + #endif + } + hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + #if CONFIG_SENSOR_Focus + if (sensor->sensor_wq) { + destroy_workqueue(sensor->sensor_wq); + sensor->sensor_wq = NULL; + } + #endif + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); + return i2c_add_driver(&sensor_i2c_driver); +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/media/video/rk30_camera.c b/drivers/media/video/rk30_camera.c index eb933b727b26..b5ca10be2f78 100755 --- a/drivers/media/video/rk30_camera.c +++ b/drivers/media/video/rk30_camera.c @@ -937,12 +937,76 @@ static void rk_init_camera_plateform_data(void) static void rk30_camera_request_reserve_mem(void) { + int i,max_resolution; + int cam_ipp_mem=PMEM_CAMIPP_NECESSARY, cam_pmem=PMEM_CAM_NECESSARY; + + i =0; + max_resolution = 0x00; + while (strstr(new_camera[i].dev.device_info.dev.init_name,"end")==NULL) { + if (new_camera[i].resolution > max_resolution) + max_resolution = new_camera[i].resolution; + i++; + } + + if (max_resolution < PMEM_SENSOR_FULL_RESOLUTION_CIF_1) + max_resolution = PMEM_SENSOR_FULL_RESOLUTION_CIF_1; + if (max_resolution < PMEM_SENSOR_FULL_RESOLUTION_CIF_0) + max_resolution = PMEM_SENSOR_FULL_RESOLUTION_CIF_0; + + switch (max_resolution) + { + case 0x800000: + default: + { + cam_ipp_mem = 0x800000; + cam_pmem = 0x1900000; + break; + } + + case 0x500000: + { + cam_ipp_mem = 0x800000; + cam_pmem = 0x1400000; + break; + } + + case 0x300000: + { + cam_ipp_mem = 0x600000; + cam_pmem = 0xf00000; + break; + } + + case 0x200000: + { + cam_ipp_mem = 0x600000; + cam_pmem = 0xc00000; + break; + } + + case 0x100000: + { + cam_ipp_mem = 0x600000; + cam_pmem = 0xa00000; + break; + } + + case 0x30000: + { + cam_ipp_mem = 0x600000; + cam_pmem = 0x600000; + break; + } + } + + + #ifdef CONFIG_VIDEO_RK29_WORK_IPP rk_camera_platform_data.meminfo.vbase = rk_camera_platform_data.meminfo_cif1.vbase = NULL; #if defined(CONFIG_VIDEO_RKCIF_WORK_SIMUL_OFF) || ((RK_SUPPORT_CIF0 && RK_SUPPORT_CIF1) == 0) rk_camera_platform_data.meminfo.name = "camera_ipp_mem"; - rk_camera_platform_data.meminfo.start = board_mem_reserve_add("camera_ipp_mem",PMEM_CAMIPP_NECESSARY); - rk_camera_platform_data.meminfo.size= PMEM_CAMIPP_NECESSARY; + rk_camera_platform_data.meminfo.start = board_mem_reserve_add("camera_ipp_mem",cam_ipp_mem); + rk_camera_platform_data.meminfo.size= cam_ipp_mem; memcpy(&rk_camera_platform_data.meminfo_cif1,&rk_camera_platform_data.meminfo,sizeof(struct rk29camera_mem_res)); #else @@ -956,8 +1020,8 @@ static void rk30_camera_request_reserve_mem(void) #endif #endif #if PMEM_CAM_NECESSARY - android_pmem_cam_pdata.start = board_mem_reserve_add((char*)(android_pmem_cam_pdata.name),PMEM_CAM_NECESSARY); - android_pmem_cam_pdata.size= PMEM_CAM_NECESSARY; + android_pmem_cam_pdata.start = board_mem_reserve_add((char*)(android_pmem_cam_pdata.name),cam_pmem); + android_pmem_cam_pdata.size= cam_pmem; #endif } @@ -965,20 +1029,19 @@ static int rk_register_camera_devices(void) { int i; int host_registered_0,host_registered_1; + struct rkcamera_platform_data *new_camera; rk_init_camera_plateform_data(); host_registered_0 = 0; host_registered_1 = 0; + for (i=0; idev.device_info.dev.init_name,"end")==NULL) { + if (new_camera->dev.link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_1) { + host_registered_1 = 1; + } else if (new_camera->dev.link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_0) { + host_registered_0 = 1; + } + new_camera++; + } + } + + if (host_registered_0) { + platform_device_register(&rk_device_camera_host_0); + } + + if (host_registered_1) { + platform_device_register(&rk_device_camera_host_1); + } + for (i=0; i + static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); +#define CAMMODULE_NAME "rk_cam_cif" + #define dprintk(level, fmt, arg...) do { \ if (debug >= level) \ - printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0) + printk(KERN_WARNING "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0) -#define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define RKCAMERA_TR(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__) #define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) // CIF Reg Offset #define CIF_CIF_CTRL 0x00 @@ -228,7 +231,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CROP_ALIGN_BYTES (0x03) #define CIF_DO_CROP 0 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM) -#define CROP_ALIGN_BYTES (0x03) +#define CROP_ALIGN_BYTES (0x0f) #define CIF_DO_CROP 0 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA) #define CROP_ALIGN_BYTES (0x03) @@ -290,8 +293,14 @@ module_param(debug, int, S_IRUGO|S_IWUSR); * 1. support rk3188; Must soft reset cif controller after each frame irq; *v0.2.21: * 1. fix ctrl register capture bit may be turn on in rk_videobuf_capture function +* +*v0.3.1 : +* 1. compatible with generic_sensor; + */ -#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 0x21) +#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 3, 0x01) +static int version = RK_CAM_VERSION_CODE; +module_param(version, int, S_IRUGO); /* limit to rk29 hardware capabilities */ #define RK_CAM_BUS_PARAM (SOCAM_MASTER |\ @@ -380,6 +389,20 @@ struct rk_camera_timer{ 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; +}; + struct rk_camera_dev { struct soc_camera_host soc_host; @@ -388,14 +411,6 @@ struct rk_camera_dev * interface. If anyone ever builds hardware to enable more than * one camera, they will have to modify this driver too */ struct soc_camera_device *icd; - - //************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************/ void __iomem *base; int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */ unsigned int irq; @@ -462,12 +477,14 @@ static const struct v4l2_queryctrl rk_camera_controls[] = #endif }; +static struct rk_cif_clk cif_clk[2]; + static DEFINE_MUTEX(camera_lock); 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); - +static int rk_camera_scale_crop_arm(struct work_struct *work); /* * Videobuf operations @@ -524,7 +541,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__); + RKCAMERA_TR("kmalloc failed\n"); BUG(); } INIT_LIST_HEAD(&pcdev->camera_work_queue); @@ -546,7 +563,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__); + RKCAMERA_TR("vbinfo kmalloc fail\n"); BUG(); } memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count)); @@ -555,7 +572,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, #endif } 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); + RKCAMERA_DG("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count); return 0; } @@ -737,7 +754,7 @@ 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); + RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i); } } } @@ -970,7 +987,7 @@ static int rk_camera_scale_crop_rga(struct work_struct *work){ } #endif -#if ((defined(CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON)) && (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)) +#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP) static int rk_camera_scale_crop_ipp(struct work_struct *work) { @@ -983,7 +1000,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, scale_crop_ret=0; /* *ddl@rock-chips.com: @@ -1008,13 +1025,12 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work) ipp_req.dst0.w = pcdev->icd->user_width/scale_times; 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); + rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt); vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; 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; hzoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times; src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width/2 @@ -1027,39 +1043,41 @@ static int rk_camera_scale_crop_ipp(struct work_struct *work) ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset; ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset; 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); - } else { - break; - } + + if (ipp_blit_sync(&ipp_req)){ + RKCAMERA_TR("ipp do erro, so switch to arm \n"); + scale_crop_ret = 0x01; + break; } - - if (ipp_times <= 0) { - 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); - - goto do_ipp_err; - } } } + + if (scale_crop_ret == 0x01) { + ret = rk_camera_scale_crop_arm(work); + } + do_ipp_err: + + if (ret) { + 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 and ARM 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); + } + return ret; } #endif -#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM) static int rk_camera_scale_crop_arm(struct work_struct *work) { struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work); @@ -1177,7 +1195,6 @@ 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); @@ -1278,7 +1295,7 @@ static irqreturn_t rk_camera_irq(int irq, void *data) } } if (pcdev->active == NULL) { - RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__); + RKCAMERA_DG("video_buf queue is empty!\n"); } do_gettimeofday(&vb->ts); @@ -1340,9 +1357,9 @@ static void rk_videobuf_release(struct videobuf_queue *vq, } #endif if (vb == pcdev->active) { - RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb); + RKCAMERA_DG("Wait for this video buf(0x%x) write finished!\n ",(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); + RKCAMERA_DG("This video buf(0x%x) write finished, release now!!\n",(unsigned int)vb); } flush_workqueue(pcdev->camera_wq); @@ -1385,28 +1402,59 @@ 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) + +static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate) { - int err = 0; + int err = 0,cif; + struct rk_cif_clk *clk; - if(!pcdev->aclk_cif || !pcdev->hclk_cif || !pcdev->cif_clk_in || !pcdev->cif_clk_out){ + 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; + } + + clk = &cif_clk[cif]; + + 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_ACTIVE_ERR; - } - - clk_enable(pcdev->pd_cif); - clk_enable(pcdev->aclk_cif); + 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); + 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; + } + spin_unlock(&clk->lock); +rk_camera_clk_ctrl_end: + return err; +} - clk_enable(pcdev->hclk_cif); - clk_enable(pcdev->cif_clk_in); +static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd) +{ + int err = 0; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - //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); + /* + * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c + */ - ndelay(10); + //soft reset the registers #if 0 //has somthing wrong when suspend and resume now if(IS_CIF0()){ @@ -1444,26 +1492,18 @@ static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_dev #endif write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|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)); + RKCAMERA_DG("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base, CIF_CIF_CTRL)); return 0; RK_CAMERA_ACTIVE_ERR: return -ENODEV; } 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); +{ + /* + * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c + */ - clk_disable(pcdev->pd_cif); - return; } @@ -1626,7 +1666,8 @@ 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__); + + RKCAMERA_DG("%s enter\n",__FUNCTION__); fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); if (!fmt) @@ -1667,7 +1708,7 @@ 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); + RKCAMERA_DG("cif_ctrl_val = 0x%x\n",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); @@ -1699,11 +1740,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)); + RKCAMERA_DG("ctrl:0x%x CIF_CIF_FOR=%x \n",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); + RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret); return ret; } @@ -1833,24 +1874,23 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val); break; } -#if 1 - { + #if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)) - mdelay(100); - if(IS_CIF0()){ - // pmu_set_idle_request(IDLE_REQ_VIO, true); - cru_set_soft_reset(SOFT_RST_CIF0, true); - udelay(5); - cru_set_soft_reset(SOFT_RST_CIF0, false); - // pmu_set_idle_request(IDLE_REQ_VIO, false); - - }else{ - // pmu_set_idle_request(IDLE_REQ_VIO, true); - cru_set_soft_reset(SOFT_RST_CIF1, true); - udelay(5); - cru_set_soft_reset(SOFT_RST_CIF1, false); - // pmu_set_idle_request(IDLE_REQ_VIO, false); - } + mdelay(100); + if(IS_CIF0()){ + //pmu_set_idle_request(IDLE_REQ_VIO, true); + cru_set_soft_reset(SOFT_RST_CIF0, true); + udelay(5); + cru_set_soft_reset(SOFT_RST_CIF0, false); + //pmu_set_idle_request(IDLE_REQ_VIO, false); + + }else{ + //pmu_set_idle_request(IDLE_REQ_VIO, true); + cru_set_soft_reset(SOFT_RST_CIF1, true); + udelay(5); + cru_set_soft_reset(SOFT_RST_CIF1, false); + //pmu_set_idle_request(IDLE_REQ_VIO, false); + } #elif defined(CONFIG_ARCH_RK3188) // pmu_set_idle_request(IDLE_REQ_VIO, true); cru_set_soft_reset(SOFT_RST_CIF0, true); @@ -1859,10 +1899,9 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix // pmu_set_idle_request(IDLE_REQ_VIO, false); #endif - } write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */ write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200); //capture complete interrupt enable -#endif + 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 */ @@ -1882,7 +1921,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)); + RKCAMERA_DG("crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR)); return; } @@ -2016,7 +2055,32 @@ static int rk_camera_set_crop(struct soc_camera_device *icd, return 0; } +static bool rk_camera_fmt_capturechk(struct v4l2_format *f) +{ + bool ret = false; + + if (f->fmt.pix.priv == 0xfefe5a5a) { + ret = true; + } + + if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + ret = true; + } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + ret = true; + } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + ret = true; + } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + ret = true; + } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + ret = true; + } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) { + ret = true; + } + if (ret == true) + RKCAMERA_DG("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height); + return ret; +} static int rk_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { @@ -2030,10 +2094,11 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_rect rect; int ret,usr_w,usr_h; int stream_on = 0; - + usr_w = pix->width; usr_h = pix->height; - RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); + + RKCAMERA_DG("enter width:%d height:%d\n",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); @@ -2056,9 +2121,11 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, mf.field = pix->field; mf.colorspace = pix->colorspace; mf.code = xlate->code; + mf.reserved[7] = pix->priv; ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); if (mf.code != xlate->code) return -EINVAL; + #ifdef CONFIG_VIDEO_RK29_WORK_IPP if ((mf.width != usr_w) || (mf.height != usr_h)) { int ratio; @@ -2086,15 +2153,13 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, 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))) { + 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); ret = -EINVAL; goto RK_CAMERA_SET_FMT_END; @@ -2107,9 +2172,10 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, pcdev->host_width = usr_w; pcdev->host_height = usr_h; #endif + icd->sense = NULL; if (!ret) { - RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__, + RKCAMERA_DG("host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n", pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h); rect.width = pcdev->host_width; rect.height = pcdev->host_height; @@ -2135,19 +2201,18 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01); #else pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate; - pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; - 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){ - 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{ - pcdev->zoominfo.a.c.left = 0; - pcdev->zoominfo.a.c.top = 0; - } - pcdev->zoominfo.vir_width = pcdev->host_width; + pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; + 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){ + 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 { + 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 up(&pcdev->zoominfo.sem); @@ -2168,7 +2233,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, } } } - RKCAMERA_DG("%s..%s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name, + RKCAMERA_DG(" %s icd width:%d user width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",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); @@ -2192,28 +2257,7 @@ RK_CAMERA_SET_FMT_END: RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); return ret; } -static bool rk_camera_fmt_capturechk(struct v4l2_format *f) -{ - bool ret = false; - - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { - ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { - ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { - ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { - ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { - ret = true; - } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) { - ret = true; - } - if (ret == true) - RKCAMERA_DG("%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, struct v4l2_format *f) { @@ -2276,10 +2320,10 @@ 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); + RKCAMERA_DG("Sensor resolution : %dx%d\n",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); + RKCAMERA_DG("user demand: %dx%d sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height); } #ifdef CONFIG_VIDEO_RK29_WORK_IPP @@ -2336,7 +2380,7 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd, } RK_CAMERA_TRY_FMT_END: - if (ret) + if (ret<0) RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); return ret; } @@ -2381,6 +2425,7 @@ 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]; int i; @@ -2391,6 +2436,15 @@ static int rk_camera_querycap(struct soc_camera_host *ici, sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation); } } + + 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); + } + 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)); @@ -2662,11 +2716,11 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable) RKCAMERA_DG("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->active = 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)); + } + RKCAMERA_DG("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%x\n",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) @@ -2675,6 +2729,7 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm struct rk_camera_dev *pcdev = ici->priv; struct rk_camera_frmivalenum *fival_list = NULL; struct v4l2_frmivalenum *fival_head = NULL; + struct rkcamera_platform_data *new_camera; int i,ret = 0,index; index = fival->index & 0x00ffffff; @@ -2714,47 +2769,64 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm fival_head = pcdev->pdata->info[i].fival; } } - - if (fival_head == NULL) { - RKCAMERA_TR("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev)); - ret = -EINVAL; - goto rk_camera_enum_frameintervals_end; - } - - i = 0; - while (fival_head->width && fival_head->height) { - if ((fival->pixel_format == fival_head->pixel_format) - && (fival->height == fival_head->height) - && (fival->width == fival_head->width)) { - if (i == index) { - break; + + if (fival_head) { + i = 0; + while (fival_head->width && fival_head->height) { + if ((fival->pixel_format == fival_head->pixel_format) + && (fival->height == fival_head->height) + && (fival->width == fival_head->width)) { + if (i == index) { + break; + } + i++; } - i++; + fival_head++; } - fival_head++; - } - 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), - 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), - fival->width,fival->height, + if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) { + memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum)); + fival->reserved[1] = (pcdev->icd_width<<16)|(pcdev->icd_height); + RKCAMERA_DG("%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), - index); - else - RKCAMERA_DG("%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); - ret = -EINVAL; + 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), + 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), + fival->width,fival->height, + fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF, + (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24), + index); + ret = -EINVAL; + goto rk_camera_enum_frameintervals_end; + } + } else { + i = 0x00; + new_camera = pcdev->pdata->register_dev_new; + while (strstr(new_camera->dev_name,"end")==NULL) { + if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) { + i = 0x01; + break; + } + new_camera++; + } + + if (i == 0x00) { + printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!", + __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev)); + } else { + fival->discrete.numerator= 1000; + fival->discrete.denominator = 15000; + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + } } } rk_camera_enum_frameintervals_end: @@ -2807,7 +2879,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 ); + RKCAMERA_DG("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", 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; @@ -2824,7 +2896,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 ); + RKCAMERA_DG("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height ); #endif return 0; @@ -2980,8 +3052,9 @@ 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, + RKCAMERA_TR("%s version: v%d.%d.%d Zoom by %s",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)) { @@ -3009,36 +3082,38 @@ static int rk_camera_probe(struct platform_device *pdev) pcdev->zoominfo.zoom_rate = 100; 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"); + + if (IS_CIF0()) { + 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 */ if (pcdev->pdata && pcdev->pdata->io_init) { pcdev->pdata->io_init(); + + if (pcdev->pdata->sensor_mclk == NULL) + pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl; } #ifdef CONFIG_VIDEO_RK29_WORK_IPP meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1); @@ -3113,9 +3188,10 @@ static int rk_camera_probe(struct platform_device *pdev) } else { pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1"); } - if (pcdev->camera_wq == NULL) - goto exit_free_irq; -//#endif + if (pcdev->camera_wq == NULL) { + RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__); + goto exit_free_irq; + } pcdev->camera_reinit_work.pcdev = pcdev; INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work); @@ -3132,13 +3208,16 @@ static int rk_camera_probe(struct platform_device *pdev) pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); - if (err) + if (err) { + RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__); goto exit_free_irq; + } pcdev->fps_timer.pcdev = pcdev; hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); pcdev->fps_timer.timer.function = rk_camera_fps_func; pcdev->icd_cb.sensor_cb = NULL; -#if ((defined(CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON)) && (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)) + +#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP) pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp; #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM) pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm; @@ -3147,7 +3226,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__); + RKCAMERA_DG("%s exit \n",__FUNCTION__); return 0; exit_free_irq: @@ -3176,15 +3255,18 @@ exit_ioremap_vipmem: iounmap(pcdev->vipmem_virbase); release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size); exit_reqmem_vip: - if(pcdev->aclk_cif) - pcdev->aclk_cif = NULL; - if(pcdev->hclk_cif) - pcdev->hclk_cif = NULL; - if(pcdev->cif_clk_in) - pcdev->cif_clk_in = NULL; - if(pcdev->cif_clk_out) - pcdev->cif_clk_out = NULL; - + if (clk) { + if (clk->pd_cif) + clk_put(clk->pd_cif); + if (clk->aclk_cif) + clk_put(clk->aclk_cif); + if (clk->hclk_cif) + clk_put(clk->hclk_cif); + if (clk->cif_clk_in) + clk_put(clk->cif_clk_in); + if (clk->cif_clk_out) + clk_put(clk->cif_clk_out); + } kfree(pcdev); exit_alloc: @@ -3263,7 +3345,6 @@ static int rk_camera_init_async(void *unused) static int __devinit rk_camera_init(void) { - RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__); kthread_run(rk_camera_init_async, NULL, "rk_camera_init"); return 0; } diff --git a/drivers/media/video/sp2518.c b/drivers/media/video/sp2518.c index bd290d9ab5f5..69cff0ebbf7f 100755 --- a/drivers/media/video/sp2518.c +++ b/drivers/media/video/sp2518.c @@ -1,136 +1,108 @@ - + +#include "generic_sensor.h" /* - * Driver for SP2518 CMOS Image Sensor from Superpix - * - * Copyright (C) 2008, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -* -* History Author Data -* First Version yuanjianping 2012-09-20 -* Set P0:0x14 = 0x40 zengchaohui 2012-09-20 -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -static int debug=0; -module_param(debug, int, S_IRUGO|S_IWUSR); - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_WARNING fmt , ## arg); } while (0) - -#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) - - -#define _CONS(a,b) a##b -#define CONS(a,b) _CONS(a,b) - -#define __STR(x) #x -#define _STR(x) __STR(x) -#define STR(x) _STR(x) - -#define MIN(x,y) ((xy) ? x: y) - -/* Sensor Driver Configuration */ -#define SENSOR_NAME RK29_CAM_SENSOR_SP2518 -#define SENSOR_V4L2_IDENT V4L2_IDENT_SP2518 -#define SENSOR_ID 0x53 -#define SENSOR_ID_REG 0x02 -#define SENSOR_MIN_WIDTH 176//640 -#define SENSOR_MIN_HEIGHT 144//480 -#define SENSOR_MAX_WIDTH 1600 -#define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 - -#define CONFIG_SENSOR_WhiteBalance 1 -#define CONFIG_SENSOR_Brightness 0 -#define CONFIG_SENSOR_Contrast 0 -#define CONFIG_SENSOR_Saturation 0 -#define CONFIG_SENSOR_Effect 1 -#define CONFIG_SENSOR_Scene 1 -#define CONFIG_SENSOR_DigitalZoom 0 -#define CONFIG_SENSOR_Focus 0 -#define CONFIG_SENSOR_Exposure 0 -#define CONFIG_SENSOR_Flash 0 -#define CONFIG_SENSOR_Mirror 0 -#define CONFIG_SENSOR_Flip 0 - -#define CONFIG_SENSOR_I2C_SPEED 100000 ///250000 /* Hz */ -/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ -#define CONFIG_SENSOR_I2C_NOSCHED 0 -#define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - -#define COLOR_TEMPERATURE_CLOUDY_DN 6500 -#define COLOR_TEMPERATURE_CLOUDY_UP 8000 -#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 -#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 -#define COLOR_TEMPERATURE_OFFICE_DN 3500 -#define COLOR_TEMPERATURE_OFFICE_UP 5000 -#define COLOR_TEMPERATURE_HOME_DN 2500 -#define COLOR_TEMPERATURE_HOME_UP 3500 - -#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) -#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - -#define SENSOR_AF_IS_ERR (0x00<<0) -#define SENSOR_AF_IS_OK (0x01<<0) -#define SENSOR_INIT_IS_ERR (0x00<<28) -#define SENSOR_INIT_IS_OK (0x01<<28) - +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*/ +static int version = KERNEL_VERSION(0,0,1); +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_SENSOR_SP2518 +#define SENSOR_V4L2_IDENT V4L2_IDENT_SP2518 +#define SENSOR_ID 0x53 +#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 800 +#define SENSOR_PREVIEW_H 600 +#define SENSOR_PREVIEW_FPS 15000 // 15fps +#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps +#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps +#define SENSOR_720P_FPS 0 +#define SENSOR_1080P_FPS 0 + +#define SENSOR_REGISTER_LEN 1 // sensor register address bytes +#define SENSOR_VALUE_LEN 1 // sensor register value bytes + +static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); +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 + +struct sensor_parameter +{ + unsigned int PreviewDummyPixels; + unsigned int CaptureDummyPixels; + unsigned int preview_exposure; + unsigned short int preview_line_width; + unsigned short int preview_gain; + + unsigned short int PreviewPclk; + unsigned short int CapturePclk; + char awb[6]; +}; + +struct specific_sensor{ + struct generic_sensor common_sensor; + //define user data below + struct sensor_parameter parameter; + +}; + +/* +* Local define +*/ //AE -#define SP2518_P0_0xf7 0x80//78 - -#define SP2518_P0_0xf8 0x74//6e - -#define SP2518_P0_0xf9 0x80//74 - -#define SP2518_P0_0xfa 0x74//6a - -//HEQ - -#define SP2518_P0_0xdd 0x80 - -#define SP2518_P0_0xde 0x95 - +#define SP2518_P0_0xf7 0x80//78 +#define SP2518_P0_0xf8 0x74//6e +#define SP2518_P0_0xf9 0x80//74 +#define SP2518_P0_0xfa 0x74//6a +//HEQ +#define SP2518_P0_0xdd 0x80 +#define SP2518_P0_0xde 0x95 //auto lum #define SP2518_NORMAL_Y0ffset 0x10 //0x0f modify by sp_yjp,20120813 -#define SP2518_LOWLIGHT_Y0ffset 0x20 - - - - - -struct reginfo -{ - u8 reg; - u8 val; -}; -///=========SP2518-modify by sp_yjp,20120529================= -/* init 640X480 VGA */ -static struct reginfo sensor_init_data[] = -{ +#define SP2518_LOWLIGHT_Y0ffset 0x20 + +/* +* 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[] = { {0xfd,0x00}, {0x1b,0x1a},//maximum drv ability //0x02 modify by sp_yjp,20120809 {0x0e,0x01}, @@ -376,11 +348,11 @@ static struct reginfo sensor_init_data[] = {0x1a,0x80}, {0x1b,0x80}, {0x43,0x80}, - //outdoor - {0x00,0xd4}, - {0x01,0xb0}, - {0x02,0x90}, - {0x03,0x78}, + //outdoor + {0x00,0xd4}, + {0x01,0xb0}, + {0x02,0x90}, + {0x03,0x78}, //d65 {0x35,0xd6},//d6;b0 {0x36,0xf0},//f0;d1;e9 @@ -435,14 +407,14 @@ static struct reginfo sensor_init_data[] = {0xc0,0xb0}, {0xc1,0xf0}, - {0xd3,0x77}, - {0xd4,0x77}, - {0xd6,0x77}, - {0xd7,0x77}, - {0xd8,0x77}, - {0xd9,0x77}, - {0xda,0x77}, - {0xdb,0x77}, + {0xd3,0x77}, + {0xd4,0x77}, + {0xd6,0x77}, + {0xd7,0x77}, + {0xd8,0x77}, + {0xd9,0x77}, + {0xda,0x77}, + {0xdb,0x77}, //uv_dif {0xfd,0x00}, {0xf3,0x03}, @@ -601,49 +573,8 @@ static struct reginfo sensor_init_data[] = {0x1b,0x1a}, {0xe7,0x03}, - {0xe7,0x00}, - - //SP2518_config_window(WINDOW_SIZE_VGA} - #if 1 // - /* - {0xfd,0x00}, - {0x4b,0x00}, - {0x4c,0x00}, - {0x47,0x00}, - {0x48,0x00}, - {0x4d,0x06}, - {0x4e,0x40}, - {0x49,0x04}, - {0x4a,0xb0}, - - {0xfd,0x01}, - {0x06,0x00}, - {0x07,0x50}, - {0x08,0x00}, - {0x09,0x50}, - {0x0a,0x01}, //480 - {0x0b,0xe0}, - {0x0c,0x02}, //640 - {0x0d,0x80}, - {0x0e,0x01}, - {0xfd,0x00}, - */ - #else //uxga - {0xfd,0x00}, - {0x47,0x00}, - {0x48,0x00}, - {0x49,0x04}, - {0x4a,0xb0}, - - {0x4b,0x00}, - {0x4c,0x00}, - {0x4d,0x06}, - {0x4e,0x40}, - - {0xfd,0x01}, - {0x0e,0x00}, - {0xfd,0x00}, - #endif + {0xe7,0x00}, + //SVGA {0xfd,0x00}, @@ -666,17 +597,14 @@ static struct reginfo sensor_init_data[] = {0x0c,0x03}, //800 {0x0d,0x20}, {0x0e,0x01}, - {0xfd,0x00}, - - - {0x5d,0x0e}, //vsync delay - {0xff,0xff}//The end flag -}; - - -/* 1600X1200 UXGA */ -static struct reginfo sensor_uxga[] = -{ + {0xfd,0x00}, + {0x5d,0x0e}, //vsync delay + + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + {0xfd,0x00}, {0x47,0x00}, {0x48,0x00}, @@ -690,43 +618,21 @@ static struct reginfo sensor_uxga[] = {0xfd,0x01}, {0x0e,0x00}, - {0xfd,0x00}, - {0xff,0xff}//The end flag -}; - - -/* 1280X1024 SXGA */ -static struct reginfo sensor_sxga[] = -{ -#if 0 - {0xfd,0x00}, - {0x47,0x00}, - {0x48,0x50}, - {0x49,0x04}, - {0x4a,0x00}, - - {0x4b,0x00}, - {0x4c,0x90}, - {0x4d,0x05}, - {0x4e,0x00}, - - {0xfd,0x01}, - {0x0e,0x00}, - {0xfd,0x00}, -#endif - {0xff,0xff} -}; - -/* 800X600 SVGA*/ -static struct reginfo sensor_svga[] = -{ - {0xfd,0x00}, - + {0xfd,0x00}, + 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[] = +{ + {0xfd,0x00}, {0x47,0x00}, {0x48,0x00}, {0x49,0x04}, - {0x4a,0xb0}, - + {0x4a,0xb0}, {0x4b,0x00}, {0x4c,0x00}, {0x4d,0x06}, @@ -741,2649 +647,608 @@ static struct reginfo sensor_svga[] = {0x0c,0x03}, //800 {0x0d,0x20}, {0x0e,0x01}, - {0xfd,0x00}, - {0xff,0xff}//The end flag -}; - -/* 640X480 VGA */ -static struct reginfo sensor_vga[] = -{ -#if 0 - {0xfd,0x00}, - - {0x47,0x00}, - {0x48,0x00}, - {0x49,0x04}, - {0x4a,0xb0}, - - {0x4b,0x00}, - {0x4c,0x00}, - {0x4d,0x06}, - {0x4e,0x40}, - - {0xfd,0x01}, - {0x06,0x00}, - {0x07,0x50}, - {0x08,0x00}, - {0x09,0x50}, - {0x0a,0x01}, //480 - {0x0b,0xe0}, - {0x0c,0x02}, //640 - {0x0d,0x80}, - {0x0e,0x01}, - {0xfd,0x00}, -#endif - {0xff,0xff}//The end flag - - -}; -///=========SP2518-modify by sp_yjp,20120529================= - -/* 352X288 CIF */ -static struct reginfo sensor_cif[] = -{ - {0xfd, 0x00},{0xff,0xff} -}; - -/* 320*240 QVGA */ -static struct reginfo sensor_qvga[] = -{ -#if 0 - {0xfd,0x00}, - - {0x47,0x00}, - {0x48,0x00}, - {0x49,0x04}, - {0x4a,0xb0}, - {0x4b,0x00}, - {0x4c,0x00}, - {0x4d,0x06}, - {0x4e,0x40}, - - {0xfd,0x01}, - - {0x06,0x00}, - {0x07,0xa0}, - {0x08,0x00}, - {0x09,0xa0}, - - {0x0a,0x00}, //240 - {0x0b,0xf0}, - {0x0c,0x01}, //320 - {0x0d,0x40}, - - {0x0e,0x01}, - {0xfd,0x00}, -#endif - {0xff,0xff}//The end flag -}; - -/* 176X144 QCIF*/ -static struct reginfo sensor_qcif[] = -{ - //{0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_ClrFmt_YUYV[]= -{ - //{0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_ClrFmt_UYVY[]= -{ - //{0xfd, 0x00}, - {0xff,0xff} -}; - -///=========SP2518-modify by sp_yjp,20120529================= - -#if CONFIG_SENSOR_WhiteBalance -static struct reginfo sensor_WhiteB_Auto[]= -{ - {0xfd, 0x01}, + {0xfd,0x00}, + + 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[]={ + SensorRegVal(0x02,0), + 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[]= +{ + {0xfd, 0x01}, {0x28, 0xce}, {0x29, 0x8a}, {0xfd, 0x00}, {0x32, 0x0d}, - {0xfd, 0x00}, - {0xff, 0xff} -}; -/* Cloudy Colour Temperature : 6500K - 8000K */ -static struct reginfo sensor_WhiteB_Cloudy[]= -{ - {0xfd,0x00}, + {0xfd, 0x00}, + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + {0xfd,0x00}, {0x32,0x05}, {0xfd,0x01}, {0x28,0xe2}, {0x29,0x82}, {0xfd,0x00}, - {0xfd,0x00}, - {0xff,0xff} -}; -/* ClearDay Colour Temperature : 5000K - 6500K */ -static struct reginfo sensor_WhiteB_ClearDay[]= -{ - {0xfd,0x00}, + {0xfd,0x00}, + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + {0xfd,0x00}, {0x32,0x05}, {0xfd,0x01}, {0x28,0xc1}, {0x29,0x88}, {0xfd,0x00}, - {0xfd,0x00}, - {0xff,0xff} -}; -/* Office Colour Temperature : 3500K - 5000K */ -static struct reginfo sensor_WhiteB_TungstenLamp1[]= -{ - {0xfd,0x00}, + {0xfd,0x00}, + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + {0xfd,0x00}, {0x32,0x05}, {0xfd,0x01}, {0x28,0x7b}, {0x29,0xd3}, {0xfd,0x00}, - {0xfd,0x00}, - {0xff,0xff} - -}; -/* Home Colour Temperature : 2500K - 3500K */ -static struct reginfo sensor_WhiteB_TungstenLamp2[]= -{ - {0xfd,0x00}, - {0x32,0x05}, - {0xfd,0x01}, - {0x28,0xae}, - {0x29,0xcc}, - {0xfd,0x00}, - {0xfd,0x00}, - {0xff,0xff} -}; -static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, - sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, -}; -#endif - - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Brightness -static struct reginfo sensor_Brightness0[]= -{ - {0xfd, 0x00}, - {0xdc, 0xe0}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Brightness1[]= -{ - {0xfd, 0x00}, - {0xdc, 0xf0}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Brightness2[]= -{ - {0xfd, 0x00}, - {0xdc, 0x00}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Brightness3[]= -{ - {0xfd, 0x00}, - {0xdc, 0x10}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Brightness4[]= -{ - {0xfd, 0x00}, - {0xdc, 0x20}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Brightness5[]= -{ - {0xfd, 0x00}, - {0xdc, 0x30}, - {0xff, 0xff} -}; -static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, - sensor_Brightness4, sensor_Brightness5,NULL, -}; - -#endif - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Effect -static struct reginfo sensor_Effect_Normal[] = -{ - {0xfd, 0x00}, + {0xfd,0x00}, + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + {0x3406, 0x01}, + {0x3400, 0x04}, + {0x3401, 0x58}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x07}, + {0x3405, 0x24}, + 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[] = +{ + {0xfd, 0x00}, {0x62, 0x00}, {0x63, 0x80}, - {0x64, 0x80}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Effect_WandB[] = -{ - {0xfd, 0x00}, + {0x64, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + {0xfd, 0x00}, {0x62, 0x20}, {0x63, 0x80}, - {0x64, 0x80}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Effect_Sepia[] = -{ - {0xfd, 0x00}, + {0x64, 0x80}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + {0xfd, 0x00}, {0x62, 0x10}, {0x63, 0xb0}, - {0x64, 0x40}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Effect_Negative[] = -{ - {0xfd, 0x00}, + {0x64, 0x40}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + {0xfd, 0x00}, {0x62, 0x04}, {0x63, 0x80}, - {0x64, 0x80}, - {0xff, 0xff} -}; -static struct reginfo sensor_Effect_Bluish[] = -{ - {0xfd, 0x00}, + {0x64, 0x80}, + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + {0xfd, 0x00}, {0x62, 0x10}, {0x63, 0x80}, - {0x64, 0xb0}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Effect_Green[] = -{ - {0xfd, 0x00}, + {0x64, 0xb0}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + {0xfd, 0x00}, {0x62, 0x10}, {0x63, 0x50}, - {0x64, 0x50}, - {0xff, 0xff} -}; -static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, - sensor_Effect_Bluish, sensor_Effect_Green,NULL, -}; -#endif + {0x64, 0x50}, + 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[] = +{ + {0xfd, 0x00}, + {0xb2,SP2518_NORMAL_Y0ffset}, + {0xb3,0x1f}, -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Exposure -static struct reginfo sensor_Exposure0[]= -{ - //level -3 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7-0x18+0x04}, - {0xf7,SP2518_P0_0xf7-0x18}, - {0xf8,SP2518_P0_0xf8-0x18}, - {0xec,SP2518_P0_0xf8-0x18-0x04}, - {0xef,SP2518_P0_0xf9-0x18+0x04}, - {0xf9,SP2518_P0_0xf9-0x18}, - {0xfa,SP2518_P0_0xfa-0x18}, - {0xee,SP2518_P0_0xfa-0x18-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; + //SP2518 UXGA 24MEclk 3PLL 50Hz fix13fps + + {0xfd,0x00}, + {0x03,0x03}, + {0x04,0xf6}, + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x00}, + {0x0a,0x8b}, + {0x2f,0x00}, + {0x30,0x08}, + {0xf0,0xa9}, + {0xf1,0x00}, + {0xfd,0x01}, + {0x90,0x07}, + {0x92,0x01}, + {0x98,0xa9}, + {0x99,0x00}, + {0x9a,0x01}, + {0x9b,0x00}, + {0xfd,0x01}, + {0xce,0x9f}, + {0xcf,0x04}, + {0xd0,0x9f}, + {0xd1,0x04}, + {0xd7,0xa5}, + {0xd8,0x00}, + {0xd9,0xa9}, + {0xda,0x00}, + {0xfd,0x00}, + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + {0xfd,0x00}, + {0xb2,SP2518_LOWLIGHT_Y0ffset}, + {0xb3,0x1f}, -static struct reginfo sensor_Exposure1[]= + //SP2518 UXGA 24MEclk 3PLL 50Hz fix 6fps + {0xfd , 0x00}, + {0x03 , 0x01}, + {0x04 , 0xfe}, + {0x05 , 0x00}, + {0x06 , 0x6d}, + {0x07 , 0x00}, + {0x08 , 0x6d}, + {0x09 , 0x04}, + {0x0a , 0xa8}, + {0xf0 , 0x55}, + {0xf1 , 0x00}, + {0xfd , 0x01}, + {0x90 , 0x10}, + {0x92 , 0x01}, + {0x98 , 0x55}, + {0x99 , 0x00}, + {0x9a , 0x01}, + {0x9b , 0x00}, + ///Status + {0xfd , 0x01}, + {0xce , 0x50}, + {0xcf , 0x05}, + {0xd0 , 0x50}, + {0xd1 , 0x05}, + {0xd7 , 0x57},//51 + {0xd8 , 0x00}, + {0xd9 , 0x5b},//55 + {0xda , 0x00}, + + {0xfd,0x00}, + 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[] = +{ +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; +static struct soc_camera_ops sensor_ops; + + +/* +********************************************************** +* 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) +{ + + SENSOR_DG("%s",__FUNCTION__); + + + return 0; +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + //struct generic_sensor *sensor = to_generic_sensor(client); + + SENSOR_DG("%s",__FUNCTION__); + + 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 0; +} +/* +* 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_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) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) { - //level -2 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7-0x10+0x04}, - {0xf7,SP2518_P0_0xf7-0x10}, - {0xf8,SP2518_P0_0xf8-0x10}, - {0xec,SP2518_P0_0xf8-0x10-0x04}, - {0xef,SP2518_P0_0xf9-0x10+0x04}, - {0xf9,SP2518_P0_0xf9-0x10}, - {0xfa,SP2518_P0_0xfa-0x10}, - {0xee,SP2518_P0_0xfa-0x10-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Exposure2[]= -{ - //level -1 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7-0x08+0x04}, - {0xf7,SP2518_P0_0xf7-0x08}, - {0xf8,SP2518_P0_0xf8-0x08}, - {0xec,SP2518_P0_0xf8-0x08-0x04}, - {0xef,SP2518_P0_0xf9-0x08+0x04}, - {0xf9,SP2518_P0_0xf9-0x08}, - {0xfa,SP2518_P0_0xfa-0x08}, - {0xee,SP2518_P0_0xfa-0x08-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Exposure3[]= -{ - //level 0 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7+0x04}, - {0xf7,SP2518_P0_0xf7}, - {0xf8,SP2518_P0_0xf8}, - {0xec,SP2518_P0_0xf8-0x04}, - {0xef,SP2518_P0_0xf9+0x04}, - {0xf9,SP2518_P0_0xf9}, - {0xfa,SP2518_P0_0xfa}, - {0xee,SP2518_P0_0xfa-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Exposure4[]= -{ - //level +1 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7+0x08+0x04}, - {0xf7,SP2518_P0_0xf7+0x08}, - {0xf8,SP2518_P0_0xf8+0x08}, - {0xec,SP2518_P0_0xf8+0x08-0x04}, - {0xef,SP2518_P0_0xf9+0x08+0x04}, - {0xf9,SP2518_P0_0xf9+0x08}, - {0xfa,SP2518_P0_0xfa+0x08}, - {0xee,SP2518_P0_0xfa+0x08-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Exposure5[]= -{ - //level +2 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7+0x10+0x04}, - {0xf7,SP2518_P0_0xf7+0x10}, - {0xf8,SP2518_P0_0xf8+0x10}, - {0xec,SP2518_P0_0xf8+0x10-0x04}, - {0xef,SP2518_P0_0xf9+0x10+0x04}, - {0xf9,SP2518_P0_0xf9+0x10}, - {0xfa,SP2518_P0_0xfa+0x10}, - {0xee,SP2518_P0_0xfa+0x10-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Exposure6[]= -{ - //level +3 - {0xfd,0x00}, - {0xed,SP2518_P0_0xf7+0x18+0x04}, - {0xf7,SP2518_P0_0xf7+0x18}, - {0xf8,SP2518_P0_0xf8+0x18}, - {0xec,SP2518_P0_0xf8+0x18-0x04}, - {0xef,SP2518_P0_0xf9+0x18+0x04}, - {0xf9,SP2518_P0_0xf9+0x18}, - {0xfa,SP2518_P0_0xfa+0x18}, - {0xee,SP2518_P0_0xfa+0x18-0x04}, - - {0xfd, 0x00}, - {0xff,0xff} -}; - -static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, - sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, -}; -#endif - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Saturation -static struct reginfo sensor_Saturation0[]= -{ - {0xfd, 0x00}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Saturation1[]= -{ - {0xfd, 0x00}, - {0xff, 0xff} -}; - -static struct reginfo sensor_Saturation2[]= -{ - {0xfd, 0x00}, - {0xff, 0xff} -}; -static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; - -#endif - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Contrast -static struct reginfo sensor_Contrast0[]= -{ - //level -3 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd-0x30}, - {0xde , SP2518_P0_0xde-0x30}, - {0xff , 0xff} -}; - -static struct reginfo sensor_Contrast1[]= -{ - //level -2 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd-0x20}, - {0xde , SP2518_P0_0xde-0x20}, - {0xff , 0xff} -}; - -static struct reginfo sensor_Contrast2[]= -{ - //level -1 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd-0x10}, - {0xde , SP2518_P0_0xde-0x10}, - {0xff , 0xff} -}; - -static struct reginfo sensor_Contrast3[]= -{ - //level 0 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd}, - {0xde , SP2518_P0_0xde}, - {0xff , 0xff} -}; - -static struct reginfo sensor_Contrast4[]= -{ - //level +1 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd+0x10}, - {0xde , SP2518_P0_0xde+0x10}, - {0xff , 0xff} -}; - - -static struct reginfo sensor_Contrast5[]= -{ - //level +2 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd+0x20}, - {0xde , SP2518_P0_0xde+0x20}, - {0xff , 0xff} -}; - -static struct reginfo sensor_Contrast6[]= -{ - //level +3 - {0xfd , 0x00}, - {0xdd , SP2518_P0_0xdd+0x30}, - {0xde , SP2518_P0_0xde+0x30}, - {0xff , 0xff} -}; - - - - -static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, - sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, -}; - -#endif - - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Mirror -static struct reginfo sensor_MirrorOn[]= -{ - {0xfd, 0x00}, - {0x31, 0x30}, - {0xff, 0xff} -}; - -static struct reginfo sensor_MirrorOff[]= -{ - {0xfd, 0x00}, - {0x31, 0x10}, - {0xff, 0xff} -}; -static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; -#endif -#if CONFIG_SENSOR_Flip -static struct reginfo sensor_FlipOn[]= -{ - {0xfd, 0x00}, - {0x31, 0x50}, - {0xff, 0xff} -}; - -static struct reginfo sensor_FlipOff[]= -{ - {0xfd, 0x00}, - {0x31, 0x10}, - {0xff, 0xff} -}; -static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; - -#endif - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_Scene//? zch -static struct reginfo sensor_SceneAuto[] = -{ - #if 1 - {0xfd, 0x00}, - {0xb2,SP2518_NORMAL_Y0ffset}, - {0xb3,0x1f}, - - //SP2518 UXGA 24MEclk 3PLL 50Hz fix13fps - - {0xfd,0x00}, - {0x03,0x03}, - {0x04,0xf6}, - {0x05,0x00}, - {0x06,0x00}, - {0x07,0x00}, - {0x08,0x00}, - {0x09,0x00}, - {0x0a,0x8b}, - {0x2f,0x00}, - {0x30,0x08}, - {0xf0,0xa9}, - {0xf1,0x00}, - {0xfd,0x01}, - {0x90,0x07}, - {0x92,0x01}, - {0x98,0xa9}, - {0x99,0x00}, - {0x9a,0x01}, - {0x9b,0x00}, - {0xfd,0x01}, - {0xce,0x9f}, - {0xcf,0x04}, - {0xd0,0x9f}, - {0xd1,0x04}, - {0xd7,0xa5}, - {0xd8,0x00}, - {0xd9,0xa9}, - {0xda,0x00}, - {0xfd,0x00}, - - #endif - - {0xfd, 0x00}, - {0xff, 0xff} -}; - -static struct reginfo sensor_SceneNight[] = -{ - #if 1 - {0xfd,0x00}, - {0xb2,SP2518_LOWLIGHT_Y0ffset}, - {0xb3,0x1f}, - - //SP2518 UXGA 24MEclk 3PLL 50Hz fix 6fps - {0xfd , 0x00}, - {0x03 , 0x01}, - {0x04 , 0xfe}, - {0x05 , 0x00}, - {0x06 , 0x6d}, - {0x07 , 0x00}, - {0x08 , 0x6d}, - {0x09 , 0x04}, - {0x0a , 0xa8}, - {0xf0 , 0x55}, - {0xf1 , 0x00}, - {0xfd , 0x01}, - {0x90 , 0x10}, - {0x92 , 0x01}, - {0x98 , 0x55}, - {0x99 , 0x00}, - {0x9a , 0x01}, - {0x9b , 0x00}, - ///Status - {0xfd , 0x01}, - {0xce , 0x50}, - {0xcf , 0x05}, - {0xd0 , 0x50}, - {0xd1 , 0x05}, - {0xd7 , 0x57},//51 - {0xd8 , 0x00}, - {0xd9 , 0x5b},//55 - {0xda , 0x00}, - #endif - - {0xfd,0x00}, - {0xff,0xff} -}; - - - -static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; - -#endif - -///=========SP2518-modify by sp_yjp,20120529================= -#if CONFIG_SENSOR_DigitalZoom -static struct reginfo sensor_Zoom0[] = -{ - {0xfd,0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Zoom1[] = -{ - {0xfd,0x00}, - {0xff,0xff} -}; - -static struct reginfo sensor_Zoom2[] = -{ - {0xfd,0x00}, - {0xff,0xff} -}; - - -static struct reginfo sensor_Zoom3[] = -{ - {0xfd,0x00}, - {0xff,0xff} -}; -static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; -#endif - - -///=========SP2518-modify by sp_yjp,20120529================= -static const struct v4l2_querymenu sensor_menus[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, - { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Effect - { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, - { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Scene - { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, - #endif - - #if CONFIG_SENSOR_Flash - { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, - { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, - #endif -}; - -static const struct v4l2_queryctrl sensor_controls[] = -{ - #if CONFIG_SENSOR_WhiteBalance - { - .id = V4L2_CID_DO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "White Balance Control", - .minimum = 0, - .maximum = 4, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Brightness - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness Control", - .minimum = -3, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Effect - { - .id = V4L2_CID_EFFECT, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Effect Control", - .minimum = 0, - .maximum = 5, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Exposure - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure Control", - .minimum = 0, - .maximum = 6, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Saturation - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation Control", - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Contrast - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast Control", - .minimum = -3, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Mirror - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Flip - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - #endif - - #if CONFIG_SENSOR_Scene - { - .id = V4L2_CID_SCENE, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Scene Control", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_DigitalZoom - { - .id = V4L2_CID_ZOOM_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_ZOOM_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "DigitalZoom Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif - - #if CONFIG_SENSOR_Focus - { - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = -1, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Focus Control", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 125, - }, - #endif - - #if CONFIG_SENSOR_Flash - { - .id = V4L2_CID_FLASH, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Flash Control", - .minimum = 0, - .maximum = 3, - .step = 1, - .default_value = 0, - }, - #endif -}; - -static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); -static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); -static int sensor_resume(struct soc_camera_device *icd); -static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); -static int sensor_deactivate(struct i2c_client *client); - -static struct soc_camera_ops sensor_ops = -{ - .suspend = sensor_suspend, - .resume = sensor_resume, - .set_bus_param = sensor_set_bus_param, - .query_bus_param = sensor_query_bus_param, - .controls = sensor_controls, - .menus = sensor_menus, - .num_controls = ARRAY_SIZE(sensor_controls), - .num_menus = ARRAY_SIZE(sensor_menus), -}; - -/* only one fixed colorspace per pixelcode */ -struct sensor_datafmt { - enum v4l2_mbus_pixelcode code; - enum v4l2_colorspace colorspace; -}; - -/* Find a data format by a pixel code in an array */ -static const struct sensor_datafmt *sensor_find_datafmt( - enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, - int n) -{ - int i; - for (i = 0; i < n; i++) - if (fmt[i].code == code) - return fmt + i; - - return NULL; -} - -static const struct sensor_datafmt sensor_colour_fmts[] = { - {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} -}; - -typedef struct sensor_info_priv_s -{ - int whiteBalance; - int brightness; - int contrast; - int saturation; - int effect; - int scene; - int digitalzoom; - int focus; - int flash; - int exposure; - bool snap2preview; - bool video2preview; - unsigned char mirror; /* HFLIP */ - unsigned char flip; /* VFLIP */ - unsigned int winseqe_cur_addr; - struct sensor_datafmt fmt; - unsigned int funmodule_state; -} sensor_info_priv_t; - -struct sensor -{ - struct v4l2_subdev subdev; - struct i2c_client *client; - sensor_info_priv_t info_priv; - int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ -#if CONFIG_SENSOR_I2C_NOSCHED - atomic_t tasklock_cnt; -#endif - struct rk29camera_platform_data *sensor_io_request; - struct rk29camera_gpio_res *sensor_gpio_res; -}; - -static struct sensor* to_sensor(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct sensor, subdev); -} - -static int sensor_task_lock(struct i2c_client *client, int lock) -{ -#if CONFIG_SENSOR_I2C_NOSCHED - int cnt = 3; - struct sensor *sensor = to_sensor(client); - - if (lock) { - if (atomic_read(&sensor->tasklock_cnt) == 0) { - while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { - SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); - msleep(35); - cnt--; - } - if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { - SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); - goto sensor_task_lock_err; - } - preempt_disable(); - } - - atomic_add(1, &sensor->tasklock_cnt); - } else { - if (atomic_read(&sensor->tasklock_cnt) > 0) { - atomic_sub(1, &sensor->tasklock_cnt); - - if (atomic_read(&sensor->tasklock_cnt) == 0) - preempt_enable(); - } - } return 0; -sensor_task_lock_err: - return -1; -#else - return 0; -#endif - } -/* sensor register write */ -static int sensor_write(struct i2c_client *client, u8 reg, u8 val) -{ - int err,cnt; - u8 buf[2]; - struct i2c_msg msg[1]; - - buf[0] = reg & 0xFF; - buf[1] = val; - - msg->addr = client->addr; - msg->flags = client->flags; - msg->buf = buf; - msg->len = sizeof(buf); - msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 3; - err = -EAGAIN; - - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 1); - - if (err >= 0) { - return 0; - } else { - SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); - udelay(10); - } - } - - return err; -} - -/* sensor register read */ -static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) -{ - int err,cnt; - //u8 buf[2]; - u8 buf[1]; - struct i2c_msg msg[2]; - - //buf[0] = reg >> 8; - buf[0] = reg; - buf[1] = reg & 0xFF; - - msg[0].addr = client->addr; - msg[0].flags = client->flags; - msg[0].buf = buf; - msg[0].len = sizeof(buf); - msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - msg[1].addr = client->addr; - msg[1].flags = client->flags|I2C_M_RD; - msg[1].buf = buf; - msg[1].len = 1; - msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ - msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ - - cnt = 1; - err = -EAGAIN; - while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ - err = i2c_transfer(client->adapter, msg, 2); - - if (err >= 0) { - *val = buf[0]; - return 0; - } else { - SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); - udelay(10); - } - } - - return err; -} - -/* write a array of registers */ -#if 1 -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - - //for(i=0; i < sizeof(sensor_init_data) / 2;i++) - while((regarray[i].reg != 0xff) || (regarray[i].val != 0xff)) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - i++; - } - - return 0; -} -#else -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) -{ - int err; - int i = 0; - u8 val_read; - while (regarray[i].reg != 0) - { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - err = sensor_read(client, regarray[i].reg, &val_read); - SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); - i++; - } - return 0; -} -#endif - -#if CONFIG_SENSOR_I2C_RDWRCHK -static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) -{ - int ret; - int i = 0; - - u8 value; - - SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); - for(i=0;ipowerdown) { - ret = icl->powerdown(icd->pdev, on); - if (ret == RK29_CAM_IO_SUCCESS) { - if (on == 0) { - mdelay(20); // 2 modify by sp_yjp,20120831 - if (icl->reset) - icl->reset(icd->pdev); - mdelay(50); // add by sp_yjp,20120831 - } - } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { - ret = -ENODEV; - goto sensor_power_end; - } - } - break; - } - case Sensor_Flash: - { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { - sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); - } - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_power_end: - return ret; -} - -static int sensor_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - const struct sensor_datafmt *fmt; - int ret; - - SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - msleep(10); - if (sensor_ioctrl(icd, Sensor_PowerDown, 1) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - msleep(10); - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_INIT_ERR; - } - msleep(10); - - /* soft reset */ - if (sensor_task_lock(client,1)<0) - goto sensor_INIT_ERR; - /* ret = sensor_write(client, 0x12, 0x80); - if (ret != 0) - { - SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_INIT_ERR; - } - - mdelay(5); */ //delay 5 microseconds - - ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { - SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); - goto sensor_INIT_ERR; - } - - sensor_task_lock(client,0); - - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); - ret = -EINVAL; - goto sensor_INIT_ERR; - } - sensor->info_priv.fmt = *fmt; - - /* sensor sensor information for initialization */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - if (qctrl) - sensor->info_priv.whiteBalance = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); - if (qctrl) - sensor->info_priv.brightness = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - if (qctrl) - sensor->info_priv.effect = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); - if (qctrl) - sensor->info_priv.exposure = qctrl->default_value; - - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); - if (qctrl) - sensor->info_priv.saturation = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); - if (qctrl) - sensor->info_priv.contrast = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); - if (qctrl) - sensor->info_priv.mirror = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); - if (qctrl) - sensor->info_priv.flip = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); - if (qctrl) - sensor->info_priv.scene = qctrl->default_value; - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl) - sensor->info_priv.digitalzoom = qctrl->default_value; - - /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ - #if CONFIG_SENSOR_Focus - sensor_set_focus(); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (qctrl) - sensor->info_priv.focus = qctrl->default_value; - #endif - - #if CONFIG_SENSOR_Flash - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); - if (qctrl) - sensor->info_priv.flash = qctrl->default_value; - #endif - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; - return 0; -sensor_INIT_ERR: - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - sensor_task_lock(client,0); - sensor_deactivate(client); - return ret; -} - -static int sensor_deactivate(struct i2c_client *client) -{ - struct soc_camera_device *icd = client->dev.platform_data; - //u8 reg_val; - struct sensor *sensor = to_sensor(client); - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - - /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); - msleep(100); - - /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; - - return 0; -} -static struct reginfo sensor_power_down_sequence[]= -{ - {0xfd,0x00},{0xff,0xff} -}; -static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) -{ - int ret; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if (pm_msg.event == PM_EVENT_SUSPEND) { - SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); - ret = sensor_write_array(client, sensor_power_down_sequence) ; - if (ret != 0) { - SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); - return ret; - } else { - ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); - if (ret < 0) { - SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - } - } else { - SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - return 0; -} - -static int sensor_resume(struct soc_camera_device *icd) -{ - int ret; - - ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); - if (ret < 0) { - SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); - - return 0; - -} - -static int sensor_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - - return 0; -} - -static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SENSOR_BUS_PARAM; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - - mf->width = icd->user_width; - mf->height = icd->user_height; - mf->code = sensor->info_priv.fmt.code; - mf->colorspace = sensor->info_priv.fmt.colorspace; - mf->field = V4L2_FIELD_NONE; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1024) && (mf->height == 768)) { - ret = true; - } else if ((mf->width == 1280) && (mf->height == 1024)) { - ret = true; - } else if ((mf->width == 1600) && (mf->height == 1200)) { - ret = true; - } else if ((mf->width == 2048) && (mf->height == 1536)) { - ret = true; - } else if ((mf->width == 2592) && (mf->height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - bool ret = false; - - if ((mf->width == 1280) && (mf->height == 720)) { - ret = true; - } else if ((mf->width == 1920) && (mf->height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct sensor_datafmt *fmt; - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - int ret=0, set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (!fmt) { - ret = -EINVAL; - goto sensor_s_fmt_end; - } - - if (sensor->info_priv.fmt.code != mf->code) { - switch (mf->code) - { - case V4L2_MBUS_FMT_YUYV8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_MBUS_FMT_UYVY8_2X8: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.fmt.code = mf->code; - sensor->info_priv.fmt.colorspace= mf->colorspace; - SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); - } else { - SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); - } - } - - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=0xff)) - { - winseqe_set_addr = sensor_qcif; - set_w = 176; - set_h = 144; - } - else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=0xff)) - { - winseqe_set_addr = sensor_qvga; - set_w = 320; - set_h = 240; - } - else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff)) - { - winseqe_set_addr = sensor_cif; - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=0xff)) - { - winseqe_set_addr = sensor_vga; - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600))) - { - if (sensor_svga[0].reg!=0xff) { - winseqe_set_addr = sensor_svga; - set_w = 800-16; - set_h = 600-12; - } else if (sensor_vga[0].reg!=0xff) { - winseqe_set_addr = sensor_vga; - set_w = 640-16; - set_h = 480-12; - } else if (sensor_uxga[0].reg!=0xff) { - winseqe_set_addr = sensor_uxga; - set_w = 1600-16; - set_h = 1200-12; - } - } - else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff)) - { - winseqe_set_addr = sensor_sxga; - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff)) - { - winseqe_set_addr = sensor_uxga; - set_w = 1600; - set_h = 1200; - } - else - { - winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); - } - printk("%s(%d): %dx%d -> %dx%d\n",__FUNCTION__,__LINE__, mf->width,mf->height,set_w,set_h); - - printk("win: %p %p %p %p %p %p\n",winseqe_set_addr,sensor->info_priv.winseqe_cur_addr, - sensor_uxga,sensor_svga,sensor_vga,sensor_sxga); - - - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_On); - SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); - } - } else { /* ddl@rock-chips.com : Video */ - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); - } - } - #endif - ret |= sensor_write_array(client, winseqe_set_addr); - if (ret != 0) { - SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); - #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,mf) == true) { - if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); - } - } - #endif - goto sensor_s_fmt_end; - } - - sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - - if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - if (sensor->info_priv.whiteBalance != 0) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - } - sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - sensor->info_priv.video2preview = true; - } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); - sensor_set_effect(icd, qctrl,sensor->info_priv.effect); - qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); - sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); - msleep(600); - sensor->info_priv.video2preview = false; - sensor->info_priv.snap2preview = false; - } - - SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - } - else - { - SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); - } - - mf->width = set_w; - mf->height = set_h; - -sensor_s_fmt_end: - return ret; -} - -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct sensor_datafmt *fmt; - int ret = 0,set_w,set_h; - - fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, - ARRAY_SIZE(sensor_colour_fmts)); - if (fmt == NULL) { - fmt = &sensor->info_priv.fmt; - mf->code = fmt->code; - } - - if (mf->height > SENSOR_MAX_HEIGHT) - mf->height = SENSOR_MAX_HEIGHT; - else if (mf->height < SENSOR_MIN_HEIGHT) - mf->height = SENSOR_MIN_HEIGHT; - - if (mf->width > SENSOR_MAX_WIDTH) - mf->width = SENSOR_MAX_WIDTH; - else if (mf->width < SENSOR_MIN_WIDTH) - mf->width = SENSOR_MIN_WIDTH; - - - if ((mf->width == 320) && (mf->height == 240)) { - printk("%s(%d): qvga ERROR\n",__FUNCTION__,__LINE__); - return -1; - } - set_w = mf->width; - set_h = mf->height; - - if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=0xff)) - { - set_w = 176; - set_h = 144; - } - else if (((set_w == 320) && (set_h == 240)))// && (sensor_qvga[0].reg!=0xff)) - { - set_w = 320; - set_h = 240; - ret = -1; - } - else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff)) - { - set_w = 352; - set_h = 288; - } - else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=0xff)) - { - set_w = 640; - set_h = 480; - } - else if (((set_w <= 800) && (set_h <= 600))) - { - if (sensor_svga[0].reg!=0xff) { - set_w = 800-16; - set_h = 600-12; - } else if (sensor_vga[0].reg!=0xff) { - set_w = 640-16; - set_h = 480-12; - } else if (sensor_uxga[0].reg!=0xff) { - set_w = 1600-16; - set_h = 1200-12; - } - } - else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff)) - { - set_w = 1280; - set_h = 1024; - } - else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff)) - { - set_w = 1600; - set_h = 1200; - } - else - { - set_w = SENSOR_INIT_WIDTH; - set_h = SENSOR_INIT_HEIGHT; - } - - mf->width = set_w; - mf->height = set_h; - - mf->colorspace = fmt->colorspace; - - return ret; -} - - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ - id->revision = 0; - - return 0; -} -#if CONFIG_SENSOR_Brightness -static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Effect -static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Exposure -static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Saturation -static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Contrast -static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Mirror -static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flip -static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Scene -static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_WhiteBalance -static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) - { - if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) - { - if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - } - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - int digitalzoom_cur, digitalzoom_total; - - qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); - if (qctrl_info) - return -EINVAL; - - digitalzoom_cur = sensor->info_priv.digitalzoom; - digitalzoom_total = qctrl_info->maximum; - - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) - { - SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) - { - SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); - return -EINVAL; - } - - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) - { - *value = digitalzoom_total - digitalzoom_cur; - } - - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) - { - *value = 0 - digitalzoom_cur; - } - - digitalzoom_cur += *value; - - if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) - { - if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) - { - SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); - return -EINVAL; - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); - return 0; - } - - return -EINVAL; -} -#endif -#if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); - return 0; - } - - SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); - return -EINVAL; -} -#endif - -static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { - case V4L2_CID_BRIGHTNESS: - { - ctrl->value = sensor->info_priv.brightness; - break; - } - case V4L2_CID_SATURATION: - { - ctrl->value = sensor->info_priv.saturation; - break; - } - case V4L2_CID_CONTRAST: - { - ctrl->value = sensor->info_priv.contrast; - break; - } - case V4L2_CID_DO_WHITE_BALANCE: - { - ctrl->value = sensor->info_priv.whiteBalance; - break; - } - case V4L2_CID_EXPOSURE: - { - ctrl->value = sensor->info_priv.exposure; - break; - } - case V4L2_CID_HFLIP: - { - ctrl->value = sensor->info_priv.mirror; - break; - } - case V4L2_CID_VFLIP: - { - ctrl->value = sensor->info_priv.flip; - break; - } - default : - break; - } - return 0; -} - - - -static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - const struct v4l2_queryctrl *qctrl; - - - qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); - return -EINVAL; - } - - switch (ctrl->id) - { -#if CONFIG_SENSOR_Brightness - case V4L2_CID_BRIGHTNESS: - { - if (ctrl->value != sensor->info_priv.brightness) - { - if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.brightness = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Exposure - case V4L2_CID_EXPOSURE: - { - if (ctrl->value != sensor->info_priv.exposure) - { - if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.exposure = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Saturation - case V4L2_CID_SATURATION: - { - if (ctrl->value != sensor->info_priv.saturation) - { - if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.saturation = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Contrast - case V4L2_CID_CONTRAST: - { - if (ctrl->value != sensor->info_priv.contrast) - { - if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.contrast = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_WhiteBalance - case V4L2_CID_DO_WHITE_BALANCE: - { - if (ctrl->value != sensor->info_priv.whiteBalance) - { - if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) - { - return -EINVAL; - } - sensor->info_priv.whiteBalance = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Mirror - case V4L2_CID_HFLIP: - { - if (ctrl->value != sensor->info_priv.mirror) - { - if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.mirror = ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Flip - case V4L2_CID_VFLIP: - { - if (ctrl->value != sensor->info_priv.flip) - { - if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flip = ctrl->value; - } - break; - } -#endif - default: - break; - } - - return 0; -} -static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - switch (ext_ctrl->id) - { - case V4L2_CID_SCENE: - { - ext_ctrl->value = sensor->info_priv.scene; - break; - } - case V4L2_CID_EFFECT: - { - ext_ctrl->value = sensor->info_priv.effect; - break; - } - case V4L2_CID_ZOOM_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.digitalzoom; - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FOCUS_ABSOLUTE: - { - ext_ctrl->value = sensor->info_priv.focus; - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - return -EINVAL; - } - case V4L2_CID_FLASH: - { - ext_ctrl->value = sensor->info_priv.flash; - break; - } - default : - break; - } - return 0; -} -static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) -{ - const struct v4l2_queryctrl *qctrl; - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - int val_offset; - - qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); - - if (!qctrl) - { - SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); - return -EINVAL; - } - - val_offset = 0; - switch (ext_ctrl->id) - { -#if CONFIG_SENSOR_Scene - case V4L2_CID_SCENE: - { - if (ext_ctrl->value != sensor->info_priv.scene) - { - if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.scene = ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_Effect - case V4L2_CID_EFFECT: - { - if (ext_ctrl->value != sensor->info_priv.effect) - { - if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.effect= ext_ctrl->value; - } - break; - } -#endif -#if CONFIG_SENSOR_DigitalZoom - case V4L2_CID_ZOOM_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.digitalzoom) - { - val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; - - if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += val_offset; - - SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - - break; - } - case V4L2_CID_ZOOM_RELATIVE: - { - if (ext_ctrl->value) - { - if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.digitalzoom += ext_ctrl->value; - - SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); - } - break; - } -#endif -#if CONFIG_SENSOR_Focus - case V4L2_CID_FOCUS_ABSOLUTE: - { - if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) - return -EINVAL; - - if (ext_ctrl->value != sensor->info_priv.focus) - { - val_offset = ext_ctrl->value -sensor->info_priv.focus; - - sensor->info_priv.focus += val_offset; - } - - break; - } - case V4L2_CID_FOCUS_RELATIVE: - { - if (ext_ctrl->value) - { - sensor->info_priv.focus += ext_ctrl->value; - - SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); - } - break; - } -#endif -#if CONFIG_SENSOR_Flash - case V4L2_CID_FLASH: - { - if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) - return -EINVAL; - sensor->info_priv.flash = ext_ctrl->value; - - SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); - break; - } -#endif - default: - break; - } - - return 0; -} - -static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - int i, error_cnt=0, error_idx=-1; - - - for (i=0; icount; i++) { - if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { - error_cnt++; - error_idx = i; - } - } - - if (error_cnt > 1) - error_idx = ext_ctrl->count; - - if (error_idx != -1) { - ext_ctrl->error_idx = error_idx; - return -EINVAL; - } else { - return 0; - } -} - -/* Interface active, can use i2c. If it fails, it can indeed mean, that - * this wasn't our capture interface, so, we wait for the right one */ -static int sensor_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - char pid = 0; - int ret; - struct sensor *sensor = to_sensor(client); - - /* We must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) - return -ENODEV; - - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - msleep(10); - if (sensor_ioctrl(icd, Sensor_PowerDown, 1) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - msleep(10); - if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - ret = -ENODEV; - goto sensor_video_probe_err; - } - msleep(10); - - /* check if it is an sensor sensor */ - ////////ret = sensor_read(client, 0x00, &pid); - ret = sensor_read(client, SENSOR_ID_REG, &pid); - if (ret != 0) { - SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); - ret = -ENODEV; - goto sensor_video_probe_err; - } - - SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); -#if 1 - if (pid == SENSOR_ID) { - sensor->model = SENSOR_V4L2_IDENT; - } else { - SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); - ret = -ENODEV; - goto sensor_video_probe_err; - } -#else - sensor->model = SENSOR_V4L2_IDENT; - -#endif - return 0; - -sensor_video_probe_err: - - return ret; -} - -static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - int ret = 0; - - int i; - - - SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - switch (cmd) - { - case RK29_CAM_SUBDEV_DEACTIVATE: - { - sensor_deactivate(client); - break; - } - - case RK29_CAM_SUBDEV_IOREQUEST: - { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - sensor->sensor_gpio_res = NULL; - for (i=0; isensor_io_request->gpio_res[i].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; - } - } - if (sensor->sensor_gpio_res == NULL) { - SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } - /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control - for this project */ - #if CONFIG_SENSOR_Flash - if (sensor->sensor_gpio_res) { - if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { - for (i = 0; i < icd->ops->num_controls; i++) { - if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); - } - } - sensor->info_priv.flash = 0xff; - SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); - } - } - #endif - break; - } - default: - { - SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); - break; - } - } -sensor_ioctl_end: - return ret; - -} -static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(sensor_colour_fmts)) - return -EINVAL; - - *code = sensor_colour_fmts[index].code; - return 0; -} -static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { - .init = sensor_init, - .g_ctrl = sensor_g_control, - .s_ctrl = sensor_s_control, - .g_ext_ctrls = sensor_g_ext_controls, - .s_ext_ctrls = sensor_s_ext_controls, - .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, -}; - -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_mbus_fmt = sensor_s_fmt, - .g_mbus_fmt = sensor_g_fmt, - .try_mbus_fmt = sensor_try_fmt, - .enum_mbus_fmt = sensor_enum_fmt, -}; - -static struct v4l2_subdev_ops sensor_subdev_ops = { - .core = &sensor_subdev_core_ops, - .video = &sensor_subdev_video_ops, -}; - -static int sensor_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct sensor *sensor; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); - if (!icd) { - dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - dev_warn(&adapter->dev, - "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); - return -EIO; - } - - sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); - - /* Second stage probe - when a capture adapter is there */ - icd->ops = &sensor_ops; - - sensor->info_priv.fmt = sensor_colour_fmts[0]; - - #if CONFIG_SENSOR_I2C_NOSCHED - atomic_set(&sensor->tasklock_cnt,0); - #endif - - ret = sensor_video_probe(icd, client); - if (ret < 0) { - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - kfree(sensor); - sensor = NULL; - } - SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); - return ret; -} - -static int sensor_remove(struct i2c_client *client) -{ - struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - i2c_set_clientdata(client, NULL); - client->driver = NULL; - kfree(sensor); - sensor = NULL; - return 0; -} - -static const struct i2c_device_id sensor_id[] = { - {SENSOR_NAME_STRING(), 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sensor_id); - -static struct i2c_driver sensor_i2c_driver = { - .driver = { - .name = SENSOR_NAME_STRING(), - }, - .probe = sensor_probe, - .remove = sensor_remove, - .id_table = sensor_id, -}; - -static int __init sensor_mod_init(void) -{ - printk("\n*****************%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); -#ifdef CONFIG_SOC_CAMERA_FCAM - return 0; -#else - return i2c_add_driver(&sensor_i2c_driver); -#endif -} - -static void __exit sensor_mod_exit(void) -{ - i2c_del_driver(&sensor_i2c_driver); -} - -device_initcall_sync(sensor_mod_init); -module_exit(sensor_mod_exit); - -MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); -MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); -/* -struct cam_sensor_info cam_sensor_info_SP2518={ - "SP2518", - 1, - 1, - 0x30>>1, - 0, - SENSOR_ID_REG, - SENSOR_ID, - 0xff, - 0xff, - - &sensor_ops, - &sensor_subdev_ops, - sensor_deactivate, - sensor_read, - sensor_write, - 0, - sensor_video_probe, -}; - -EXPORT_SYMBOL_GPL(cam_sensor_info_SP2518); -*/ - - - +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; + +} +static int sensor_mirror_cb (struct i2c_client *client, int mirror) +{ + int err = 0; + + SENSOR_DG("mirror: %d",mirror); + + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_mirror_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value); + return 0; +} + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + SENSOR_DG("flip: %d",flip); + + return err; +} +/* +* 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) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (sensor_flip_cb(client,ext_ctrl->value) != 0) + SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value); + + SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value); + return 0; +} +/* +* 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_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){ + 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) +{ + 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/sp2518_old.c b/drivers/media/video/sp2518_old.c new file mode 100755 index 000000000000..bd290d9ab5f5 --- /dev/null +++ b/drivers/media/video/sp2518_old.c @@ -0,0 +1,3389 @@ + +/* + * Driver for SP2518 CMOS Image Sensor from Superpix + * + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +* +* History Author Data +* First Version yuanjianping 2012-09-20 +* Set P0:0x14 = 0x40 zengchaohui 2012-09-20 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static int debug=0; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + + +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#define MIN(x,y) ((xy) ? x: y) + +/* Sensor Driver Configuration */ +#define SENSOR_NAME RK29_CAM_SENSOR_SP2518 +#define SENSOR_V4L2_IDENT V4L2_IDENT_SP2518 +#define SENSOR_ID 0x53 +#define SENSOR_ID_REG 0x02 +#define SENSOR_MIN_WIDTH 176//640 +#define SENSOR_MIN_HEIGHT 144//480 +#define SENSOR_MAX_WIDTH 1600 +#define SENSOR_MAX_HEIGHT 1200 +#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT 600 +#define SENSOR_INIT_WINSEQADR sensor_svga +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 + +#define CONFIG_SENSOR_WhiteBalance 1 +#define CONFIG_SENSOR_Brightness 0 +#define CONFIG_SENSOR_Contrast 0 +#define CONFIG_SENSOR_Saturation 0 +#define CONFIG_SENSOR_Effect 1 +#define CONFIG_SENSOR_Scene 1 +#define CONFIG_SENSOR_DigitalZoom 0 +#define CONFIG_SENSOR_Focus 0 +#define CONFIG_SENSOR_Exposure 0 +#define CONFIG_SENSOR_Flash 0 +#define CONFIG_SENSOR_Mirror 0 +#define CONFIG_SENSOR_Flip 0 + +#define CONFIG_SENSOR_I2C_SPEED 100000 ///250000 /* Hz */ +/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ +#define CONFIG_SENSOR_I2C_NOSCHED 0 +#define CONFIG_SENSOR_I2C_RDWRCHK 0 + +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ + SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) + +#define COLOR_TEMPERATURE_CLOUDY_DN 6500 +#define COLOR_TEMPERATURE_CLOUDY_UP 8000 +#define COLOR_TEMPERATURE_CLEARDAY_DN 5000 +#define COLOR_TEMPERATURE_CLEARDAY_UP 6500 +#define COLOR_TEMPERATURE_OFFICE_DN 3500 +#define COLOR_TEMPERATURE_OFFICE_UP 5000 +#define COLOR_TEMPERATURE_HOME_DN 2500 +#define COLOR_TEMPERATURE_HOME_UP 3500 + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + +//AE +#define SP2518_P0_0xf7 0x80//78 + +#define SP2518_P0_0xf8 0x74//6e + +#define SP2518_P0_0xf9 0x80//74 + +#define SP2518_P0_0xfa 0x74//6a + +//HEQ + +#define SP2518_P0_0xdd 0x80 + +#define SP2518_P0_0xde 0x95 + +//auto lum +#define SP2518_NORMAL_Y0ffset 0x10 //0x0f modify by sp_yjp,20120813 +#define SP2518_LOWLIGHT_Y0ffset 0x20 + + + + + +struct reginfo +{ + u8 reg; + u8 val; +}; +///=========SP2518-modify by sp_yjp,20120529================= +/* init 640X480 VGA */ +static struct reginfo sensor_init_data[] = +{ + {0xfd,0x00}, + {0x1b,0x1a},//maximum drv ability //0x02 modify by sp_yjp,20120809 + {0x0e,0x01}, + + {0x0f,0x2f}, + {0x10,0x2e}, + {0x11,0x00}, + {0x12,0x4f}, + {0x14,0x40},// 0x20 zch 20120920 + {0x16,0x02}, + {0x17,0x10}, + {0x1a,0x1f}, + {0x1e,0x81}, + {0x21,0x00}, + {0x22,0x1b}, + {0x25,0x10}, + {0x26,0x25}, + {0x27,0x6d}, + {0x2c,0x23},//31 Ronlus remove balck dot0x45}, + {0x2d,0x75}, + {0x2e,0x38},//sxga 0x18 + + {0x31,0x10},//mirror upside down + {0x44,0x03}, + {0x6f,0x00}, + {0xa0,0x04}, + {0x5f,0x01}, + {0x32,0x00}, + {0xfd,0x01}, + {0x2c,0x00}, + {0x2d,0x00}, + {0xfd,0x00}, + {0xfb,0x83}, + {0xf4,0x09}, + //Pregain + {0xfd,0x01}, + {0xc6,0x90}, + {0xc7,0x90}, + {0xc8,0x90}, + {0xc9,0x90}, + //blacklevel + {0xfd,0x00}, + {0x65,0x08}, + {0x66,0x08}, + {0x67,0x08}, + {0x68,0x08}, + + //bpc + {0x46,0xff}, + //rpc + {0xfd,0x00}, + {0xe0,0x6c}, + {0xe1,0x54}, + {0xe2,0x48}, + {0xe3,0x40}, + {0xe4,0x40}, + {0xe5,0x3e}, + {0xe6,0x3e}, + {0xe8,0x3a}, + {0xe9,0x3a}, + {0xea,0x3a}, + {0xeb,0x38}, + {0xf5,0x38}, + {0xf6,0x38}, + {0xfd,0x01}, + {0x94,0xc0},//f8 + {0x95,0x38}, + {0x9c,0x6c}, + {0x9d,0x38}, + #if 0 + ///SP2518 UXGA 24MEclk 3±¶Æµ 1·ÖƵ 50Hz fix 10fps + {0xfd , 0x00}, + {0x03 , 0x03}, + {0x04 , 0x66}, + {0x05 , 0x00}, + {0x06 , 0x8b}, + {0x07 , 0x00}, + {0x08 , 0x8b}, + {0x09 , 0x01}, + {0x0a , 0x3b}, + {0x2f , 0x00}, + {0x30 , 0x08}, + {0xf0 , 0x91}, + {0xf1 , 0x00}, + {0xfd , 0x01}, + {0x90 , 0x0a}, + {0x92 , 0x01}, + {0x98 , 0x91}, + {0x99 , 0x00}, + {0x9a , 0x01}, + {0x9b , 0x00}, + ///Status + {0xfd , 0x01}, + {0xce , 0xaa}, + {0xcf , 0x05}, + {0xd0 , 0xaa}, + {0xd1 , 0x05}, + {0xd7 , 0x93},//8d + {0xd8 , 0x00}, + {0xd9 , 0x97},//91 + {0xda , 0x00}, + {0xfd , 0x00}, + #endif + + #if 1 + /*24*3pll 13-13fps 50hz*/ + + {0xfd,0x00}, + {0x03,0x03}, + {0x04,0xf6}, + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x00}, + {0x0a,0x8b}, + {0x2f,0x00}, + {0x30,0x08}, + {0xf0,0xa9}, + {0xf1,0x00}, + {0xfd,0x01}, + {0x90,0x07}, + {0x92,0x01}, + {0x98,0xa9}, + {0x99,0x00}, + {0x9a,0x01}, + {0x9b,0x00}, + {0xfd,0x01}, + {0xce,0x9f}, + {0xcf,0x04}, + {0xd0,0x9f}, + {0xd1,0x04}, + {0xd7,0xa5}, + {0xd8,0x00}, + {0xd9,0xa9}, + {0xda,0x00}, + {0xfd,0x00}, + + #endif + + {0xfd,0x01}, + {0xca,0x30},//mean dummy2low + {0xcb,0x50},//mean low2dummy + {0xcc,0xc0},//f8;rpc low + {0xcd,0xc0},//rpc dummy + {0xd5,0x80},//mean normal2dummy + {0xd6,0x90},//mean dummy2normal + {0xfd,0x00}, + + //lens shading + {0xfd,0x00}, + {0xa1,0x20}, + {0xa2,0x20}, + {0xa3,0x20}, + {0xa4,0xff}, + {0xa5,0x80}, + {0xa6,0x80}, + {0xfd,0x01}, + {0x64,0x1e},//28 + {0x65,0x1c},//25 + {0x66,0x1c},//2a + {0x67,0x16},//25 + {0x68,0x1c},//25 + {0x69,0x1c},//29 + {0x6a,0x1a},//28 + {0x6b,0x16},//20 + {0x6c,0x1a},//22 + {0x6d,0x1a},//22 + {0x6e,0x1a},//22 + {0x6f,0x16},//1c + {0xb8,0x04},//0a + {0xb9,0x13},//0a + {0xba,0x00},//23 + {0xbb,0x03},//14 + {0xbc,0x03},//08 + {0xbd,0x11},//08 + {0xbe,0x00},//12 + {0xbf,0x02},//00 + {0xc0,0x04},//05 + {0xc1,0x0e},//05 + {0xc2,0x00},//18 + {0xc3,0x05},//08 + //raw filter + {0xfd,0x01}, + {0xde,0x0f}, + {0xfd,0x00}, + {0x57,0x08},//raw_dif_thr + {0x58,0x08},//a + {0x56,0x08},//a + {0x59,0x10}, + + {0x5a,0xa0},//raw_rb_fac_outdoor + {0xc4,0xa0},//60raw_rb_fac_indoor + {0x43,0xa0},//40raw_rb_fac_dummy + {0xad,0x40},//raw_rb_fac_low + + {0x4f,0xa0},//raw_gf_fac_outdoor + {0xc3,0xa0},//60raw_gf_fac_indoor + {0x3f,0xa0},//40raw_gf_fac_dummy + {0x42,0x40},//raw_gf_fac_low + {0xc2,0x15}, + + {0xb6,0x80},//raw_gflt_fac_outdoor + {0xb7,0x80},//60raw_gflt_fac_normal + {0xb8,0x40},//40raw_gflt_fac_dummy + {0xb9,0x20},//raw_gflt_fac_low + + {0xfd,0x01}, + {0x50,0x0c},//raw_grgb_thr + {0x51,0x0c}, + {0x52,0x10}, + {0x53,0x10}, + {0xfd,0x00}, + // awb1 + {0xfd,0x01}, + {0x11,0x10}, + {0x12,0x1f}, + {0x16,0x1c}, + {0x18,0x00}, + {0x19,0x00}, + {0x1b,0x96}, + {0x1a,0x9a},//95 + {0x1e,0x2f}, + {0x1f,0x29}, + {0x20,0xff}, + {0x22,0xff}, + {0x28,0xce}, + {0x29,0x8a}, + {0xfd,0x00}, + {0xe7,0x03}, + {0xe7,0x00}, + {0xfd,0x01}, + {0x2a,0xf0}, + {0x2b,0x10}, + {0x2e,0x04}, + {0x2f,0x18}, + {0x21,0x60}, + {0x23,0x60}, + {0x8b,0xab}, + {0x8f,0x12}, + //awb2 + {0xfd,0x01}, + {0x1a,0x80}, + {0x1b,0x80}, + {0x43,0x80}, + //outdoor + {0x00,0xd4}, + {0x01,0xb0}, + {0x02,0x90}, + {0x03,0x78}, + //d65 + {0x35,0xd6},//d6;b0 + {0x36,0xf0},//f0;d1;e9 + {0x37,0x7a},//8a;70 + {0x38,0x9a},//dc;9a;af + //indoor + {0x39,0xab}, + {0x3a,0xca}, + {0x3b,0xa3}, + {0x3c,0xc1}, + //f + {0x31,0x82},//7d + {0x32,0xa5},//a0;74 + {0x33,0xd6},//d2 + {0x34,0xec},//e8 + {0x3d,0xa5},//a7;88 + {0x3e,0xc2},//be;bb + {0x3f,0xa7},//b3;ad + {0x40,0xc5},//c5;d0 + //Color Correction + {0xfd,0x01}, + {0x1c,0xc0}, + {0x1d,0x95}, + {0xa0,0xa6},//b8 + {0xa1,0xda},//;d5 + {0xa2,0x00},//;f2 + {0xa3,0x06},//;e8 + {0xa4,0xb2},//;95 + {0xa5,0xc7},//;03 + {0xa6,0x00},//;f2 + {0xa7,0xce},//;c4 + {0xa8,0xb2},//;ca + {0xa9,0x0c},//;3c + {0xaa,0x30},//;03 + {0xab,0x0c},//;0f + {0xac,0xc0},//b8 + {0xad,0xc0},//d5 + {0xae,0x00},//f2 + {0xaf,0xf2},//e8 + {0xb0,0xa6},//95 + {0xb1,0xe8},//03 + {0xb2,0x00},//f2 + {0xb3,0xe7},//c4 + {0xb4,0x99},//ca + {0xb5,0x0c},//3c + {0xb6,0x33},//03 + {0xb7,0x0c},//0f + //Saturation + {0xfd,0x00}, + {0xbf,0x01}, + {0xbe,0xbb}, + {0xc0,0xb0}, + {0xc1,0xf0}, + + {0xd3,0x77}, + {0xd4,0x77}, + {0xd6,0x77}, + {0xd7,0x77}, + {0xd8,0x77}, + {0xd9,0x77}, + {0xda,0x77}, + {0xdb,0x77}, + //uv_dif + {0xfd,0x00}, + {0xf3,0x03}, + {0xb0,0x00}, + {0xb1,0x23}, + //gamma1 + {0xfd,0x00},// + {0x8b,0x0 },//0 ;0 + {0x8c,0xA },//14;A + {0x8d,0x13},//24;13 + {0x8e,0x25},//3a;25 + {0x8f,0x43},//59;43 + {0x90,0x5D},//6f;5D + {0x91,0x74},//84;74 + {0x92,0x88},//95;88 + {0x93,0x9A},//a3;9A + {0x94,0xA9},//b1;A9 + {0x95,0xB5},//be;B5 + {0x96,0xC0},//c7;C0 + {0x97,0xCA},//d1;CA + {0x98,0xD4},//d9;D4 + {0x99,0xDD},//e1;DD + {0x9a,0xE6},//e9;E6 + {0x9b,0xEF},//f1;EF + {0xfd,0x01},//01;01 + {0x8d,0xF7},//f9;F7 + {0x8e,0xFF},//ff;FF + //gamma2 + {0xfd,0x00},// + {0x78,0x0 },//0 + {0x79,0xA },//14 + {0x7a,0x13},//24 + {0x7b,0x25},//3a + {0x7c,0x43},//59 + {0x7d,0x5D},//6f + {0x7e,0x74},//84 + {0x7f,0x88},//95 + {0x80,0x9A},//a3 + {0x81,0xA9},//b1 + {0x82,0xB5},//be + {0x83,0xC0},//c7 + {0x84,0xCA},//d1 + {0x85,0xD4},//d9 + {0x86,0xDD},//e1 + {0x87,0xE6},//e9 + {0x88,0xEF},//f1 + {0x89,0xF7},//f9 + {0x8a,0xFF},//ff + /*//¹â°ß¹ý¶ÈºÃ + //gamma1 + {0xfd,0x00}, + {0x8b,0x00}, + {0x8c,0x14}, + {0x8d,0x24}, + {0x8e,0x3A}, + {0x8f,0x59}, + {0x90,0x70}, + {0x91,0x85}, + {0x92,0x96}, + {0x93,0xA6}, + {0x94,0xB3}, + {0x95,0xBE}, + {0x96,0xC9}, + {0x97,0xD2}, + {0x98,0xDB}, + {0x99,0xE3}, + {0x9a,0xEB}, + {0x9b,0xF2}, + {0xfd,0x01}, + {0x8d,0xF9}, + {0x8e,0xFF}, + //gamma2 + {0xfd,0x00}, + {0x78,0x00}, + {0x79,0x14}, + {0x7a,0x24}, + {0x7b,0x3A}, + {0x7c,0x59}, + {0x7d,0x70}, + {0x7e,0x85}, + {0x7f,0x96}, + {0x80,0xA6}, + {0x81,0xB3}, + {0x82,0xBE}, + {0x83,0xC9}, + {0x84,0xD2}, + {0x85,0xDB}, + {0x86,0xE3}, + {0x87,0xEB}, + {0x88,0xF2}, + {0x89,0xF9}, + {0x8a,0xFF}, +*/ + //gamma_ae + {0xfd,0x01}, + {0x96,0x46}, + {0x97,0x14}, + {0x9f,0x06}, + //HEQ + {0xfd,0x00},// + {0xdd,SP2518_P0_0xdd},//0x80 + {0xde,SP2518_P0_0xde},//a0 + {0xdf,0x80},// + //Ytarget + {0xfd,0x00},// + {0xec,0x70},//6a + {0xed,0x86},//7c + {0xee,0x70},//65 + {0xef,0x86},//78 + {0xf7,0x80},//78 + {0xf8,0x74},//6e + {0xf9,0x80},//74 + {0xfa,0x74},//6a + //sharpen + {0xfd,0x01}, + {0xdf,0x0f}, + {0xe5,0x10}, + {0xe7,0x10}, + {0xe8,0x20}, + {0xec,0x20}, + {0xe9,0x20}, + {0xed,0x20}, + {0xea,0x10}, + {0xef,0x10}, + {0xeb,0x10}, + {0xf0,0x10}, + //;gw + {0xfd,0x01},// + {0x70,0x76},// + {0x7b,0x40},// + {0x81,0x30},// + //;Y_offset + {0xfd,0x00}, + {0xb2,0X10}, + {0xb3,0x1f}, + {0xb4,0x30}, + {0xb5,0x50}, + //;CNR + {0xfd,0x00}, + {0x5b,0x20}, + {0x61,0x80}, + {0x77,0x80}, + {0xca,0x80}, + //;YNR + {0xab,0x00}, + {0xac,0x02}, + {0xae,0x08}, + {0xaf,0x20}, + {0xfd,0x00}, + {0x31,0x10}, + {0x32,0x0d}, + {0x33,0xcf},//ef + {0x34,0x7f},//3f + + {0x35,0x40},//3 + + {0x1b,0x1a}, + {0xe7,0x03}, + {0xe7,0x00}, + + //SP2518_config_window(WINDOW_SIZE_VGA} + #if 1 // + /* + {0xfd,0x00}, + {0x4b,0x00}, + {0x4c,0x00}, + {0x47,0x00}, + {0x48,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0xfd,0x01}, + {0x06,0x00}, + {0x07,0x50}, + {0x08,0x00}, + {0x09,0x50}, + {0x0a,0x01}, //480 + {0x0b,0xe0}, + {0x0c,0x02}, //640 + {0x0d,0x80}, + {0x0e,0x01}, + {0xfd,0x00}, + */ + #else //uxga + {0xfd,0x00}, + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + + {0xfd,0x01}, + {0x0e,0x00}, + {0xfd,0x00}, + #endif + //SVGA + {0xfd,0x00}, + + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + {0xfd,0x01}, + {0x06,0x00}, + {0x07,0x40}, + {0x08,0x00}, + {0x09,0x40}, + {0x0a,0x02}, //600 + {0x0b,0x58}, + {0x0c,0x03}, //800 + {0x0d,0x20}, + {0x0e,0x01}, + {0xfd,0x00}, + + + {0x5d,0x0e}, //vsync delay + {0xff,0xff}//The end flag +}; + + +/* 1600X1200 UXGA */ +static struct reginfo sensor_uxga[] = +{ + {0xfd,0x00}, + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + + {0xfd,0x01}, + {0x0e,0x00}, + {0xfd,0x00}, + {0xff,0xff}//The end flag +}; + + +/* 1280X1024 SXGA */ +static struct reginfo sensor_sxga[] = +{ +#if 0 + {0xfd,0x00}, + {0x47,0x00}, + {0x48,0x50}, + {0x49,0x04}, + {0x4a,0x00}, + + {0x4b,0x00}, + {0x4c,0x90}, + {0x4d,0x05}, + {0x4e,0x00}, + + {0xfd,0x01}, + {0x0e,0x00}, + {0xfd,0x00}, +#endif + {0xff,0xff} +}; + +/* 800X600 SVGA*/ +static struct reginfo sensor_svga[] = +{ + {0xfd,0x00}, + + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + {0xfd,0x01}, + {0x06,0x00}, + {0x07,0x40}, + {0x08,0x00}, + {0x09,0x40}, + {0x0a,0x02}, //600 + {0x0b,0x58}, + {0x0c,0x03}, //800 + {0x0d,0x20}, + {0x0e,0x01}, + {0xfd,0x00}, + {0xff,0xff}//The end flag +}; + +/* 640X480 VGA */ +static struct reginfo sensor_vga[] = +{ +#if 0 + {0xfd,0x00}, + + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + + {0xfd,0x01}, + {0x06,0x00}, + {0x07,0x50}, + {0x08,0x00}, + {0x09,0x50}, + {0x0a,0x01}, //480 + {0x0b,0xe0}, + {0x0c,0x02}, //640 + {0x0d,0x80}, + {0x0e,0x01}, + {0xfd,0x00}, +#endif + {0xff,0xff}//The end flag + + +}; +///=========SP2518-modify by sp_yjp,20120529================= + +/* 352X288 CIF */ +static struct reginfo sensor_cif[] = +{ + {0xfd, 0x00},{0xff,0xff} +}; + +/* 320*240 QVGA */ +static struct reginfo sensor_qvga[] = +{ +#if 0 + {0xfd,0x00}, + + {0x47,0x00}, + {0x48,0x00}, + {0x49,0x04}, + {0x4a,0xb0}, + {0x4b,0x00}, + {0x4c,0x00}, + {0x4d,0x06}, + {0x4e,0x40}, + + {0xfd,0x01}, + + {0x06,0x00}, + {0x07,0xa0}, + {0x08,0x00}, + {0x09,0xa0}, + + {0x0a,0x00}, //240 + {0x0b,0xf0}, + {0x0c,0x01}, //320 + {0x0d,0x40}, + + {0x0e,0x01}, + {0xfd,0x00}, +#endif + {0xff,0xff}//The end flag +}; + +/* 176X144 QCIF*/ +static struct reginfo sensor_qcif[] = +{ + //{0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_ClrFmt_YUYV[]= +{ + //{0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_ClrFmt_UYVY[]= +{ + //{0xfd, 0x00}, + {0xff,0xff} +}; + +///=========SP2518-modify by sp_yjp,20120529================= + +#if CONFIG_SENSOR_WhiteBalance +static struct reginfo sensor_WhiteB_Auto[]= +{ + {0xfd, 0x01}, + {0x28, 0xce}, + {0x29, 0x8a}, + {0xfd, 0x00}, + {0x32, 0x0d}, + {0xfd, 0x00}, + {0xff, 0xff} +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct reginfo sensor_WhiteB_Cloudy[]= +{ + {0xfd,0x00}, + {0x32,0x05}, + {0xfd,0x01}, + {0x28,0xe2}, + {0x29,0x82}, + {0xfd,0x00}, + {0xfd,0x00}, + {0xff,0xff} +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct reginfo sensor_WhiteB_ClearDay[]= +{ + {0xfd,0x00}, + {0x32,0x05}, + {0xfd,0x01}, + {0x28,0xc1}, + {0x29,0x88}, + {0xfd,0x00}, + {0xfd,0x00}, + {0xff,0xff} +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct reginfo sensor_WhiteB_TungstenLamp1[]= +{ + {0xfd,0x00}, + {0x32,0x05}, + {0xfd,0x01}, + {0x28,0x7b}, + {0x29,0xd3}, + {0xfd,0x00}, + {0xfd,0x00}, + {0xff,0xff} + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct reginfo sensor_WhiteB_TungstenLamp2[]= +{ + {0xfd,0x00}, + {0x32,0x05}, + {0xfd,0x01}, + {0x28,0xae}, + {0x29,0xcc}, + {0xfd,0x00}, + {0xfd,0x00}, + {0xff,0xff} +}; +static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; +#endif + + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Brightness +static struct reginfo sensor_Brightness0[]= +{ + {0xfd, 0x00}, + {0xdc, 0xe0}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Brightness1[]= +{ + {0xfd, 0x00}, + {0xdc, 0xf0}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Brightness2[]= +{ + {0xfd, 0x00}, + {0xdc, 0x00}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Brightness3[]= +{ + {0xfd, 0x00}, + {0xdc, 0x10}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Brightness4[]= +{ + {0xfd, 0x00}, + {0xdc, 0x20}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Brightness5[]= +{ + {0xfd, 0x00}, + {0xdc, 0x30}, + {0xff, 0xff} +}; +static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Effect +static struct reginfo sensor_Effect_Normal[] = +{ + {0xfd, 0x00}, + {0x62, 0x00}, + {0x63, 0x80}, + {0x64, 0x80}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Effect_WandB[] = +{ + {0xfd, 0x00}, + {0x62, 0x20}, + {0x63, 0x80}, + {0x64, 0x80}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Effect_Sepia[] = +{ + {0xfd, 0x00}, + {0x62, 0x10}, + {0x63, 0xb0}, + {0x64, 0x40}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Effect_Negative[] = +{ + {0xfd, 0x00}, + {0x62, 0x04}, + {0x63, 0x80}, + {0x64, 0x80}, + {0xff, 0xff} +}; +static struct reginfo sensor_Effect_Bluish[] = +{ + {0xfd, 0x00}, + {0x62, 0x10}, + {0x63, 0x80}, + {0x64, 0xb0}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Effect_Green[] = +{ + {0xfd, 0x00}, + {0x62, 0x10}, + {0x63, 0x50}, + {0x64, 0x50}, + {0xff, 0xff} +}; +static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Exposure +static struct reginfo sensor_Exposure0[]= +{ + //level -3 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7-0x18+0x04}, + {0xf7,SP2518_P0_0xf7-0x18}, + {0xf8,SP2518_P0_0xf8-0x18}, + {0xec,SP2518_P0_0xf8-0x18-0x04}, + {0xef,SP2518_P0_0xf9-0x18+0x04}, + {0xf9,SP2518_P0_0xf9-0x18}, + {0xfa,SP2518_P0_0xfa-0x18}, + {0xee,SP2518_P0_0xfa-0x18-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure1[]= +{ + //level -2 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7-0x10+0x04}, + {0xf7,SP2518_P0_0xf7-0x10}, + {0xf8,SP2518_P0_0xf8-0x10}, + {0xec,SP2518_P0_0xf8-0x10-0x04}, + {0xef,SP2518_P0_0xf9-0x10+0x04}, + {0xf9,SP2518_P0_0xf9-0x10}, + {0xfa,SP2518_P0_0xfa-0x10}, + {0xee,SP2518_P0_0xfa-0x10-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure2[]= +{ + //level -1 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7-0x08+0x04}, + {0xf7,SP2518_P0_0xf7-0x08}, + {0xf8,SP2518_P0_0xf8-0x08}, + {0xec,SP2518_P0_0xf8-0x08-0x04}, + {0xef,SP2518_P0_0xf9-0x08+0x04}, + {0xf9,SP2518_P0_0xf9-0x08}, + {0xfa,SP2518_P0_0xfa-0x08}, + {0xee,SP2518_P0_0xfa-0x08-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure3[]= +{ + //level 0 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7+0x04}, + {0xf7,SP2518_P0_0xf7}, + {0xf8,SP2518_P0_0xf8}, + {0xec,SP2518_P0_0xf8-0x04}, + {0xef,SP2518_P0_0xf9+0x04}, + {0xf9,SP2518_P0_0xf9}, + {0xfa,SP2518_P0_0xfa}, + {0xee,SP2518_P0_0xfa-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure4[]= +{ + //level +1 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7+0x08+0x04}, + {0xf7,SP2518_P0_0xf7+0x08}, + {0xf8,SP2518_P0_0xf8+0x08}, + {0xec,SP2518_P0_0xf8+0x08-0x04}, + {0xef,SP2518_P0_0xf9+0x08+0x04}, + {0xf9,SP2518_P0_0xf9+0x08}, + {0xfa,SP2518_P0_0xfa+0x08}, + {0xee,SP2518_P0_0xfa+0x08-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure5[]= +{ + //level +2 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7+0x10+0x04}, + {0xf7,SP2518_P0_0xf7+0x10}, + {0xf8,SP2518_P0_0xf8+0x10}, + {0xec,SP2518_P0_0xf8+0x10-0x04}, + {0xef,SP2518_P0_0xf9+0x10+0x04}, + {0xf9,SP2518_P0_0xf9+0x10}, + {0xfa,SP2518_P0_0xfa+0x10}, + {0xee,SP2518_P0_0xfa+0x10-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Exposure6[]= +{ + //level +3 + {0xfd,0x00}, + {0xed,SP2518_P0_0xf7+0x18+0x04}, + {0xf7,SP2518_P0_0xf7+0x18}, + {0xf8,SP2518_P0_0xf8+0x18}, + {0xec,SP2518_P0_0xf8+0x18-0x04}, + {0xef,SP2518_P0_0xf9+0x18+0x04}, + {0xf9,SP2518_P0_0xf9+0x18}, + {0xfa,SP2518_P0_0xfa+0x18}, + {0xee,SP2518_P0_0xfa+0x18-0x04}, + + {0xfd, 0x00}, + {0xff,0xff} +}; + +static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Saturation +static struct reginfo sensor_Saturation0[]= +{ + {0xfd, 0x00}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Saturation1[]= +{ + {0xfd, 0x00}, + {0xff, 0xff} +}; + +static struct reginfo sensor_Saturation2[]= +{ + {0xfd, 0x00}, + {0xff, 0xff} +}; +static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Contrast +static struct reginfo sensor_Contrast0[]= +{ + //level -3 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd-0x30}, + {0xde , SP2518_P0_0xde-0x30}, + {0xff , 0xff} +}; + +static struct reginfo sensor_Contrast1[]= +{ + //level -2 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd-0x20}, + {0xde , SP2518_P0_0xde-0x20}, + {0xff , 0xff} +}; + +static struct reginfo sensor_Contrast2[]= +{ + //level -1 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd-0x10}, + {0xde , SP2518_P0_0xde-0x10}, + {0xff , 0xff} +}; + +static struct reginfo sensor_Contrast3[]= +{ + //level 0 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd}, + {0xde , SP2518_P0_0xde}, + {0xff , 0xff} +}; + +static struct reginfo sensor_Contrast4[]= +{ + //level +1 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd+0x10}, + {0xde , SP2518_P0_0xde+0x10}, + {0xff , 0xff} +}; + + +static struct reginfo sensor_Contrast5[]= +{ + //level +2 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd+0x20}, + {0xde , SP2518_P0_0xde+0x20}, + {0xff , 0xff} +}; + +static struct reginfo sensor_Contrast6[]= +{ + //level +3 + {0xfd , 0x00}, + {0xdd , SP2518_P0_0xdd+0x30}, + {0xde , SP2518_P0_0xde+0x30}, + {0xff , 0xff} +}; + + + + +static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; + +#endif + + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Mirror +static struct reginfo sensor_MirrorOn[]= +{ + {0xfd, 0x00}, + {0x31, 0x30}, + {0xff, 0xff} +}; + +static struct reginfo sensor_MirrorOff[]= +{ + {0xfd, 0x00}, + {0x31, 0x10}, + {0xff, 0xff} +}; +static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,}; +#endif +#if CONFIG_SENSOR_Flip +static struct reginfo sensor_FlipOn[]= +{ + {0xfd, 0x00}, + {0x31, 0x50}, + {0xff, 0xff} +}; + +static struct reginfo sensor_FlipOff[]= +{ + {0xfd, 0x00}, + {0x31, 0x10}, + {0xff, 0xff} +}; +static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,}; + +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_Scene//? zch +static struct reginfo sensor_SceneAuto[] = +{ + #if 1 + {0xfd, 0x00}, + {0xb2,SP2518_NORMAL_Y0ffset}, + {0xb3,0x1f}, + + //SP2518 UXGA 24MEclk 3PLL 50Hz fix13fps + + {0xfd,0x00}, + {0x03,0x03}, + {0x04,0xf6}, + {0x05,0x00}, + {0x06,0x00}, + {0x07,0x00}, + {0x08,0x00}, + {0x09,0x00}, + {0x0a,0x8b}, + {0x2f,0x00}, + {0x30,0x08}, + {0xf0,0xa9}, + {0xf1,0x00}, + {0xfd,0x01}, + {0x90,0x07}, + {0x92,0x01}, + {0x98,0xa9}, + {0x99,0x00}, + {0x9a,0x01}, + {0x9b,0x00}, + {0xfd,0x01}, + {0xce,0x9f}, + {0xcf,0x04}, + {0xd0,0x9f}, + {0xd1,0x04}, + {0xd7,0xa5}, + {0xd8,0x00}, + {0xd9,0xa9}, + {0xda,0x00}, + {0xfd,0x00}, + + #endif + + {0xfd, 0x00}, + {0xff, 0xff} +}; + +static struct reginfo sensor_SceneNight[] = +{ + #if 1 + {0xfd,0x00}, + {0xb2,SP2518_LOWLIGHT_Y0ffset}, + {0xb3,0x1f}, + + //SP2518 UXGA 24MEclk 3PLL 50Hz fix 6fps + {0xfd , 0x00}, + {0x03 , 0x01}, + {0x04 , 0xfe}, + {0x05 , 0x00}, + {0x06 , 0x6d}, + {0x07 , 0x00}, + {0x08 , 0x6d}, + {0x09 , 0x04}, + {0x0a , 0xa8}, + {0xf0 , 0x55}, + {0xf1 , 0x00}, + {0xfd , 0x01}, + {0x90 , 0x10}, + {0x92 , 0x01}, + {0x98 , 0x55}, + {0x99 , 0x00}, + {0x9a , 0x01}, + {0x9b , 0x00}, + ///Status + {0xfd , 0x01}, + {0xce , 0x50}, + {0xcf , 0x05}, + {0xd0 , 0x50}, + {0xd1 , 0x05}, + {0xd7 , 0x57},//51 + {0xd8 , 0x00}, + {0xd9 , 0x5b},//55 + {0xda , 0x00}, + #endif + + {0xfd,0x00}, + {0xff,0xff} +}; + + + +static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +#endif + +///=========SP2518-modify by sp_yjp,20120529================= +#if CONFIG_SENSOR_DigitalZoom +static struct reginfo sensor_Zoom0[] = +{ + {0xfd,0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Zoom1[] = +{ + {0xfd,0x00}, + {0xff,0xff} +}; + +static struct reginfo sensor_Zoom2[] = +{ + {0xfd,0x00}, + {0xff,0xff} +}; + + +static struct reginfo sensor_Zoom3[] = +{ + {0xfd,0x00}, + {0xff,0xff} +}; +static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; +#endif + + +///=========SP2518-modify by sp_yjp,20120529================= +static const struct v4l2_querymenu sensor_menus[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,}, + { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Effect + { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,}, + { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Scene + { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,}, + #endif + + #if CONFIG_SENSOR_Flash + { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,}, + { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,}, + #endif +}; + +static const struct v4l2_queryctrl sensor_controls[] = +{ + #if CONFIG_SENSOR_WhiteBalance + { + .id = V4L2_CID_DO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "White Balance Control", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Brightness + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness Control", + .minimum = -3, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Effect + { + .id = V4L2_CID_EFFECT, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Effect Control", + .minimum = 0, + .maximum = 5, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Exposure + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure Control", + .minimum = 0, + .maximum = 6, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Saturation + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation Control", + .minimum = 0, + .maximum = 2, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Contrast + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast Control", + .minimum = -3, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Mirror + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Flip + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + #endif + + #if CONFIG_SENSOR_Scene + { + .id = V4L2_CID_SCENE, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Scene Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_DigitalZoom + { + .id = V4L2_CID_ZOOM_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif + + #if CONFIG_SENSOR_Focus + { + .id = V4L2_CID_FOCUS_RELATIVE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = -1, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_FOCUS_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Focus Control", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 125, + }, + #endif + + #if CONFIG_SENSOR_Flash + { + .id = V4L2_CID_FLASH, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Flash Control", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + }, + #endif +}; + +static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did); +static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client); +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); +static int sensor_resume(struct soc_camera_device *icd); +static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +static int sensor_deactivate(struct i2c_client *client); + +static struct soc_camera_ops sensor_ops = +{ + .suspend = sensor_suspend, + .resume = sensor_resume, + .set_bus_param = sensor_set_bus_param, + .query_bus_param = sensor_query_bus_param, + .controls = sensor_controls, + .menus = sensor_menus, + .num_controls = ARRAY_SIZE(sensor_controls), + .num_menus = ARRAY_SIZE(sensor_menus), +}; + +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} +}; + +typedef struct sensor_info_priv_s +{ + int whiteBalance; + int brightness; + int contrast; + int saturation; + int effect; + int scene; + int digitalzoom; + int focus; + int flash; + int exposure; + bool snap2preview; + bool video2preview; + unsigned char mirror; /* HFLIP */ + unsigned char flip; /* VFLIP */ + unsigned int winseqe_cur_addr; + struct sensor_datafmt fmt; + unsigned int funmodule_state; +} sensor_info_priv_t; + +struct sensor +{ + struct v4l2_subdev subdev; + struct i2c_client *client; + sensor_info_priv_t info_priv; + int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */ +#if CONFIG_SENSOR_I2C_NOSCHED + atomic_t tasklock_cnt; +#endif + struct rk29camera_platform_data *sensor_io_request; + struct rk29camera_gpio_res *sensor_gpio_res; +}; + +static struct sensor* to_sensor(const struct i2c_client *client) +{ + return container_of(i2c_get_clientdata(client), struct sensor, subdev); +} + +static int sensor_task_lock(struct i2c_client *client, int lock) +{ +#if CONFIG_SENSOR_I2C_NOSCHED + int cnt = 3; + struct sensor *sensor = to_sensor(client); + + if (lock) { + if (atomic_read(&sensor->tasklock_cnt) == 0) { + while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) { + SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING()); + msleep(35); + cnt--; + } + if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) { + SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING()); + goto sensor_task_lock_err; + } + preempt_disable(); + } + + atomic_add(1, &sensor->tasklock_cnt); + } else { + if (atomic_read(&sensor->tasklock_cnt) > 0) { + atomic_sub(1, &sensor->tasklock_cnt); + + if (atomic_read(&sensor->tasklock_cnt) == 0) + preempt_enable(); + } + } + return 0; +sensor_task_lock_err: + return -1; +#else + return 0; +#endif + +} + +/* sensor register write */ +static int sensor_write(struct i2c_client *client, u8 reg, u8 val) +{ + int err,cnt; + u8 buf[2]; + struct i2c_msg msg[1]; + + buf[0] = reg & 0xFF; + buf[1] = val; + + msg->addr = client->addr; + msg->flags = client->flags; + msg->buf = buf; + msg->len = sizeof(buf); + msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 3; + err = -EAGAIN; + + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 1); + + if (err >= 0) { + return 0; + } else { + SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val); + udelay(10); + } + } + + return err; +} + +/* sensor register read */ +static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int err,cnt; + //u8 buf[2]; + u8 buf[1]; + struct i2c_msg msg[2]; + + //buf[0] = reg >> 8; + buf[0] = reg; + buf[1] = reg & 0xFF; + + msg[0].addr = client->addr; + msg[0].flags = client->flags; + msg[0].buf = buf; + msg[0].len = sizeof(buf); + msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + msg[1].addr = client->addr; + msg[1].flags = client->flags|I2C_M_RD; + msg[1].buf = buf; + msg[1].len = 1; + msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */ + msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */ + + cnt = 1; + err = -EAGAIN; + while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ + err = i2c_transfer(client->adapter, msg, 2); + + if (err >= 0) { + *val = buf[0]; + return 0; + } else { + SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val); + udelay(10); + } + } + + return err; +} + +/* write a array of registers */ +#if 1 +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + + //for(i=0; i < sizeof(sensor_init_data) / 2;i++) + while((regarray[i].reg != 0xff) || (regarray[i].val != 0xff)) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + i++; + } + + return 0; +} +#else +static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +{ + int err; + int i = 0; + u8 val_read; + while (regarray[i].reg != 0) + { + err = sensor_write(client, regarray[i].reg, regarray[i].val); + if (err != 0) + { + SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); + return err; + } + err = sensor_read(client, regarray[i].reg, &val_read); + SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); + i++; + } + return 0; +} +#endif + +#if CONFIG_SENSOR_I2C_RDWRCHK +static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) +{ + int ret; + int i = 0; + + u8 value; + + SENSOR_DG("%s >>>>>>>>>>>>>>>>>>>>>>\n",__FUNCTION__); + for(i=0;ipowerdown) { + ret = icl->powerdown(icd->pdev, on); + if (ret == RK29_CAM_IO_SUCCESS) { + if (on == 0) { + mdelay(20); // 2 modify by sp_yjp,20120831 + if (icl->reset) + icl->reset(icd->pdev); + mdelay(50); // add by sp_yjp,20120831 + } + } else if (ret == RK29_CAM_EIO_REQUESTFAIL) { + ret = -ENODEV; + goto sensor_power_end; + } + } + break; + } + case Sensor_Flash: + { + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) { + sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on); + } + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_power_end: + return ret; +} + +static int sensor_init(struct v4l2_subdev *sd, u32 val) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; + int ret; + + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + msleep(10); + if (sensor_ioctrl(icd, Sensor_PowerDown, 1) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + msleep(10); + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_INIT_ERR; + } + msleep(10); + + /* soft reset */ + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + /* ret = sensor_write(client, 0x12, 0x80); + if (ret != 0) + { + SENSOR_TR("%s soft reset sensor failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_INIT_ERR; + } + + mdelay(5); */ //delay 5 microseconds + + ret = sensor_write_array(client, sensor_init_data); + if (ret != 0) + { + SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); + goto sensor_INIT_ERR; + } + + sensor_task_lock(client,0); + + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + + /* sensor sensor information for initialization */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + if (qctrl) + sensor->info_priv.whiteBalance = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS); + if (qctrl) + sensor->info_priv.brightness = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + if (qctrl) + sensor->info_priv.effect = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE); + if (qctrl) + sensor->info_priv.exposure = qctrl->default_value; + + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION); + if (qctrl) + sensor->info_priv.saturation = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST); + if (qctrl) + sensor->info_priv.contrast = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP); + if (qctrl) + sensor->info_priv.mirror = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP); + if (qctrl) + sensor->info_priv.flip = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE); + if (qctrl) + sensor->info_priv.scene = qctrl->default_value; + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl) + sensor->info_priv.digitalzoom = qctrl->default_value; + + /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */ + #if CONFIG_SENSOR_Focus + sensor_set_focus(); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); + if (qctrl) + sensor->info_priv.focus = qctrl->default_value; + #endif + + #if CONFIG_SENSOR_Flash + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); + if (qctrl) + sensor->info_priv.flash = qctrl->default_value; + #endif + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; +sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); + sensor_deactivate(client); + return ret; +} + +static int sensor_deactivate(struct i2c_client *client) +{ + struct soc_camera_device *icd = client->dev.platform_data; + //u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ + icd->user_width = SENSOR_INIT_WIDTH; + icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + + return 0; +} +static struct reginfo sensor_power_down_sequence[]= +{ + {0xfd,0x00},{0xff,0xff} +}; +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + int ret; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING()); + ret = sensor_write_array(client, sensor_power_down_sequence) ; + if (ret != 0) { + SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__); + return ret; + } else { + ret = sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (ret < 0) { + SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + } + } else { + SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + int ret; + + ret = sensor_ioctrl(icd, Sensor_PowerDown, 0); + if (ret < 0) { + SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING()); + + return 0; + +} + +static int sensor_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + + return 0; +} + +static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_link *icl = to_soc_camera_link(icd); + unsigned long flags = SENSOR_BUS_PARAM; + + return soc_camera_apply_sensor_flags(icl, flags); +} + +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; + struct reginfo *winseqe_set_addr=NULL; + int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=0xff)) + { + winseqe_set_addr = sensor_qcif; + set_w = 176; + set_h = 144; + } + else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=0xff)) + { + winseqe_set_addr = sensor_qvga; + set_w = 320; + set_h = 240; + } + else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff)) + { + winseqe_set_addr = sensor_cif; + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=0xff)) + { + winseqe_set_addr = sensor_vga; + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600))) + { + if (sensor_svga[0].reg!=0xff) { + winseqe_set_addr = sensor_svga; + set_w = 800-16; + set_h = 600-12; + } else if (sensor_vga[0].reg!=0xff) { + winseqe_set_addr = sensor_vga; + set_w = 640-16; + set_h = 480-12; + } else if (sensor_uxga[0].reg!=0xff) { + winseqe_set_addr = sensor_uxga; + set_w = 1600-16; + set_h = 1200-12; + } + } + else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff)) + { + winseqe_set_addr = sensor_sxga; + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff)) + { + winseqe_set_addr = sensor_uxga; + set_w = 1600; + set_h = 1200; + } + else + { + winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); + } + printk("%s(%d): %dx%d -> %dx%d\n",__FUNCTION__,__LINE__, mf->width,mf->height,set_w,set_h); + + printk("win: %p %p %p %p %p %p\n",winseqe_set_addr,sensor->info_priv.winseqe_cur_addr, + sensor_uxga,sensor_svga,sensor_vga,sensor_sxga); + + + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif + ret |= sensor_write_array(client, winseqe_set_addr); + if (ret != 0) { + SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif + goto sensor_s_fmt_end; + } + + sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } + + SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); + } + else + { + SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); + } + + mf->width = set_w; + mf->height = set_h; + +sensor_s_fmt_end: + return ret; +} + +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0,set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + + if ((mf->width == 320) && (mf->height == 240)) { + printk("%s(%d): qvga ERROR\n",__FUNCTION__,__LINE__); + return -1; + } + set_w = mf->width; + set_h = mf->height; + + if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=0xff)) + { + set_w = 176; + set_h = 144; + } + else if (((set_w == 320) && (set_h == 240)))// && (sensor_qvga[0].reg!=0xff)) + { + set_w = 320; + set_h = 240; + ret = -1; + } + else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff)) + { + set_w = 352; + set_h = 288; + } + else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=0xff)) + { + set_w = 640; + set_h = 480; + } + else if (((set_w <= 800) && (set_h <= 600))) + { + if (sensor_svga[0].reg!=0xff) { + set_w = 800-16; + set_h = 600-12; + } else if (sensor_vga[0].reg!=0xff) { + set_w = 640-16; + set_h = 480-12; + } else if (sensor_uxga[0].reg!=0xff) { + set_w = 1600-16; + set_h = 1200-12; + } + } + else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff)) + { + set_w = 1280; + set_h = 1024; + } + else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff)) + { + set_w = 1600; + set_h = 1200; + } + else + { + set_w = SENSOR_INIT_WIDTH; + set_h = SENSOR_INIT_HEIGHT; + } + + mf->width = set_w; + mf->height = set_h; + + mf->colorspace = fmt->colorspace; + + return ret; +} + + static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match.addr != client->addr) + return -ENODEV; + + id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return OV9650 identifier */ + id->revision = 0; + + return 0; +} +#if CONFIG_SENSOR_Brightness +static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Effect +static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_EffectSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Exposure +static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Saturation +static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Contrast +static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Mirror +static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flip +static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_FlipSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Scene +static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_SceneSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_WhiteBalance +static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) + { + if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL) + { + if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + } + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_DigitalZoom +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl_info; + int digitalzoom_cur, digitalzoom_total; + + qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE); + if (qctrl_info) + return -EINVAL; + + digitalzoom_cur = sensor->info_priv.digitalzoom; + digitalzoom_total = qctrl_info->maximum; + + if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + { + SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + { + SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); + return -EINVAL; + } + + if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + { + *value = digitalzoom_total - digitalzoom_cur; + } + + if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + { + *value = 0 - digitalzoom_cur; + } + + digitalzoom_cur += *value; + + if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) + { + if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0) + { + SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); + return -EINVAL; + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + return 0; + } + + return -EINVAL; +} +#endif +#if CONFIG_SENSOR_Flash +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ + if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { + if (value == 3) { /* ddl@rock-chips.com: torch */ + sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); + return 0; + } + + SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value); + return -EINVAL; +} +#endif + +static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + const struct v4l2_queryctrl *qctrl; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { + case V4L2_CID_BRIGHTNESS: + { + ctrl->value = sensor->info_priv.brightness; + break; + } + case V4L2_CID_SATURATION: + { + ctrl->value = sensor->info_priv.saturation; + break; + } + case V4L2_CID_CONTRAST: + { + ctrl->value = sensor->info_priv.contrast; + break; + } + case V4L2_CID_DO_WHITE_BALANCE: + { + ctrl->value = sensor->info_priv.whiteBalance; + break; + } + case V4L2_CID_EXPOSURE: + { + ctrl->value = sensor->info_priv.exposure; + break; + } + case V4L2_CID_HFLIP: + { + ctrl->value = sensor->info_priv.mirror; + break; + } + case V4L2_CID_VFLIP: + { + ctrl->value = sensor->info_priv.flip; + break; + } + default : + break; + } + return 0; +} + + + +static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + const struct v4l2_queryctrl *qctrl; + + + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id); + return -EINVAL; + } + + switch (ctrl->id) + { +#if CONFIG_SENSOR_Brightness + case V4L2_CID_BRIGHTNESS: + { + if (ctrl->value != sensor->info_priv.brightness) + { + if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.brightness = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Exposure + case V4L2_CID_EXPOSURE: + { + if (ctrl->value != sensor->info_priv.exposure) + { + if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.exposure = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Saturation + case V4L2_CID_SATURATION: + { + if (ctrl->value != sensor->info_priv.saturation) + { + if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.saturation = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Contrast + case V4L2_CID_CONTRAST: + { + if (ctrl->value != sensor->info_priv.contrast) + { + if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.contrast = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_WhiteBalance + case V4L2_CID_DO_WHITE_BALANCE: + { + if (ctrl->value != sensor->info_priv.whiteBalance) + { + if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0) + { + return -EINVAL; + } + sensor->info_priv.whiteBalance = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Mirror + case V4L2_CID_HFLIP: + { + if (ctrl->value != sensor->info_priv.mirror) + { + if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.mirror = ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Flip + case V4L2_CID_VFLIP: + { + if (ctrl->value != sensor->info_priv.flip) + { + if (sensor_set_flip(icd, qctrl,ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flip = ctrl->value; + } + break; + } +#endif + default: + break; + } + + return 0; +} +static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + switch (ext_ctrl->id) + { + case V4L2_CID_SCENE: + { + ext_ctrl->value = sensor->info_priv.scene; + break; + } + case V4L2_CID_EFFECT: + { + ext_ctrl->value = sensor->info_priv.effect; + break; + } + case V4L2_CID_ZOOM_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.digitalzoom; + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FOCUS_ABSOLUTE: + { + ext_ctrl->value = sensor->info_priv.focus; + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + return -EINVAL; + } + case V4L2_CID_FLASH: + { + ext_ctrl->value = sensor->info_priv.flash; + break; + } + default : + break; + } + return 0; +} +static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl) +{ + const struct v4l2_queryctrl *qctrl; + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct sensor *sensor = to_sensor(client); + int val_offset; + + qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id); + + if (!qctrl) + { + SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id); + return -EINVAL; + } + + val_offset = 0; + switch (ext_ctrl->id) + { +#if CONFIG_SENSOR_Scene + case V4L2_CID_SCENE: + { + if (ext_ctrl->value != sensor->info_priv.scene) + { + if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.scene = ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_Effect + case V4L2_CID_EFFECT: + { + if (ext_ctrl->value != sensor->info_priv.effect) + { + if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.effect= ext_ctrl->value; + } + break; + } +#endif +#if CONFIG_SENSOR_DigitalZoom + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.digitalzoom) + { + val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom; + + if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += val_offset; + + SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + + break; + } + case V4L2_CID_ZOOM_RELATIVE: + { + if (ext_ctrl->value) + { + if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.digitalzoom += ext_ctrl->value; + + SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom); + } + break; + } +#endif +#if CONFIG_SENSOR_Focus + case V4L2_CID_FOCUS_ABSOLUTE: + { + if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum)) + return -EINVAL; + + if (ext_ctrl->value != sensor->info_priv.focus) + { + val_offset = ext_ctrl->value -sensor->info_priv.focus; + + sensor->info_priv.focus += val_offset; + } + + break; + } + case V4L2_CID_FOCUS_RELATIVE: + { + if (ext_ctrl->value) + { + sensor->info_priv.focus += ext_ctrl->value; + + SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus); + } + break; + } +#endif +#if CONFIG_SENSOR_Flash + case V4L2_CID_FLASH: + { + if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0) + return -EINVAL; + sensor->info_priv.flash = ext_ctrl->value; + + SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash); + break; + } +#endif + default: + break; + } + + return 0; +} + +static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + int i, error_cnt=0, error_idx=-1; + + + for (i=0; icount; i++) { + if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) { + error_cnt++; + error_idx = i; + } + } + + if (error_cnt > 1) + error_idx = ext_ctrl->count; + + if (error_idx != -1) { + ext_ctrl->error_idx = error_idx; + return -EINVAL; + } else { + return 0; + } +} + +/* Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one */ +static int sensor_video_probe(struct soc_camera_device *icd, + struct i2c_client *client) +{ + char pid = 0; + int ret; + struct sensor *sensor = to_sensor(client); + + /* We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + msleep(10); + if (sensor_ioctrl(icd, Sensor_PowerDown, 1) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + msleep(10); + if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { + ret = -ENODEV; + goto sensor_video_probe_err; + } + msleep(10); + + /* check if it is an sensor sensor */ + ////////ret = sensor_read(client, 0x00, &pid); + ret = sensor_read(client, SENSOR_ID_REG, &pid); + if (ret != 0) { + SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING()); + ret = -ENODEV; + goto sensor_video_probe_err; + } + + SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid); +#if 1 + if (pid == SENSOR_ID) { + sensor->model = SENSOR_V4L2_IDENT; + } else { + SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid); + ret = -ENODEV; + goto sensor_video_probe_err; + } +#else + sensor->model = SENSOR_V4L2_IDENT; + +#endif + return 0; + +sensor_video_probe_err: + + return ret; +} + +static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + int ret = 0; + + int i; + + + SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + switch (cmd) + { + case RK29_CAM_SUBDEV_DEACTIVATE: + { + sensor_deactivate(client); + break; + } + + case RK29_CAM_SUBDEV_IOREQUEST: + { + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + sensor->sensor_gpio_res = NULL; + for (i=0; isensor_io_request->gpio_res[i].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i]; + } + } + if (sensor->sensor_gpio_res == NULL) { + SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } else { + SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control + for this project */ + #if CONFIG_SENSOR_Flash + if (sensor->sensor_gpio_res) { + if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { + for (i = 0; i < icd->ops->num_controls; i++) { + if (V4L2_CID_FLASH == icd->ops->controls[i].id) { + memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + } + } + sensor->info_priv.flash = 0xff; + SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING()); + } + } + #endif + break; + } + default: + { + SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); + break; + } + } +sensor_ioctl_end: + return ret; + +} +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} +static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { + .init = sensor_init, + .g_ctrl = sensor_g_control, + .s_ctrl = sensor_s_control, + .g_ext_ctrls = sensor_g_ext_controls, + .s_ext_ctrls = sensor_s_ext_controls, + .g_chip_ident = sensor_g_chip_ident, + .ioctl = sensor_ioctl, +}; + +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, +}; + +static struct v4l2_subdev_ops sensor_subdev_ops = { + .core = &sensor_subdev_core_ops, + .video = &sensor_subdev_video_ops, +}; + +static int sensor_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct sensor *sensor; + struct soc_camera_device *icd = client->dev.platform_data; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl; + int ret; + + SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__); + if (!icd) { + dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING()); + return -EINVAL; + } + + icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING()); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_I2C\n"); + return -EIO; + } + + sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops); + + /* Second stage probe - when a capture adapter is there */ + icd->ops = &sensor_ops; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + + #if CONFIG_SENSOR_I2C_NOSCHED + atomic_set(&sensor->tasklock_cnt,0); + #endif + + ret = sensor_video_probe(icd, client); + if (ret < 0) { + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + kfree(sensor); + sensor = NULL; + } + SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); + return ret; +} + +static int sensor_remove(struct i2c_client *client) +{ + struct sensor *sensor = to_sensor(client); + struct soc_camera_device *icd = client->dev.platform_data; + + icd->ops = NULL; + i2c_set_clientdata(client, NULL); + client->driver = NULL; + kfree(sensor); + sensor = NULL; + return 0; +} + +static const struct i2c_device_id sensor_id[] = { + {SENSOR_NAME_STRING(), 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sensor_id); + +static struct i2c_driver sensor_i2c_driver = { + .driver = { + .name = SENSOR_NAME_STRING(), + }, + .probe = sensor_probe, + .remove = sensor_remove, + .id_table = sensor_id, +}; + +static int __init sensor_mod_init(void) +{ + printk("\n*****************%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); +#ifdef CONFIG_SOC_CAMERA_FCAM + return 0; +#else + return i2c_add_driver(&sensor_i2c_driver); +#endif +} + +static void __exit sensor_mod_exit(void) +{ + i2c_del_driver(&sensor_i2c_driver); +} + +device_initcall_sync(sensor_mod_init); +module_exit(sensor_mod_exit); + +MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); +/* +struct cam_sensor_info cam_sensor_info_SP2518={ + "SP2518", + 1, + 1, + 0x30>>1, + 0, + SENSOR_ID_REG, + SENSOR_ID, + 0xff, + 0xff, + + &sensor_ops, + &sensor_subdev_ops, + sensor_deactivate, + sensor_read, + sensor_write, + 0, + sensor_video_probe, +}; + +EXPORT_SYMBOL_GPL(cam_sensor_info_SP2518); +*/ + + + diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h old mode 100644 new mode 100755 index 97a44f5b0c6b..ec7386d5a7cb --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -132,7 +132,7 @@ struct soc_camera_link { struct i2c_board_info *board_info; const char *module_name; void *priv; - + void *priv_usr; /* ddl@rock-chips.com: add priv_usr */ /* Optional regulators that have to be managed on power on/off events */ struct regulator_bulk_data *regulators; int num_regulators; @@ -219,7 +219,7 @@ struct soc_camera_ops { int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); const struct v4l2_queryctrl *controls; - const struct v4l2_querymenu *menus; /* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */ + struct v4l2_querymenu *menus; /* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */ int num_controls; int num_menus; /* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */ }; diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 8923b586944a..4bddbb54b68d 100755 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -350,18 +350,28 @@ enum { V4L2_IDENT_GC2015 = 64114, /* ddl@rock-chips.com : gc2015 support */ V4L2_IDENT_GC0329 = 64115, /* ddl@rock-chips.com : GC0329 support */ V4L2_IDENT_GC2035= 64116, /* ddl@rock-chips.com : GC0329 support */ + V4L2_IDENT_GC0328 = 64117, + V4L2_IDENT_SP0838 = 64120, /* ddl@rock-chips.com : SP0838 support */ - V4L2_IDENT_SP2518 = 64121, /* ddl@rock-chips.com : SP2518 support */ + V4L2_IDENT_SP2518 = 64121, /* ddl@rock-chips.com : SP2518 support */ + V4L2_IDENT_SP0718 = 64122, /* ddl@rock-chips.com : SP0718 support */ V4L2_IDENT_HI253 = 64130, /* ddl@rock-chips.com : hi253 support */ V4L2_IDENT_HI704 = 64131, /* ddl@rock-chips.com : hi704 support */ V4L2_IDENT_SIV120B = 64140, /* ddl@rock-chips.com : siv120b support */ V4L2_IDENT_SIV121D= 64141, /* ddl@rock-chips.com : sid130B support */ - + + V4L2_IDENT_HM2057 = 64150, V4L2_IDENT_HM5065 = 64151, + V4L2_IDENT_NT99160 = 64161, /* oyyf@rock-chips.com : nt99160 support */ + V4L2_IDENT_NT99340 = 64162, /* oyyf@rock-chips.com : nt99340 support */ + V4L2_IDENT_NT99252 = 64163, /* oyyf@rock-chips.com : nt99252 support */ + V4L2_IDENT_NT99240 = 64164, /* oyyf@rock-chips.com : nt99252 support */ + + /* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */ }; -- 2.34.1