#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 <plat/rk_camera.h>
+/* 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 ---------*/
#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
#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 */
#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
#include <linux/videodev2.h>
#include <media/soc_camera.h>
-
+#include <linux/i2c.h>
#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)<<RK29_CAM_POWERACTIVE_BITPOS)|((rst_active&0x01)<<RK29_CAM_RESETACTIVE_BITPOS)|((pwdn_active&0x01)<<RK29_CAM_POWERDNACTIVE_BITPOS),\
+ },\
+ .orientation = ori,\
+ .resolution = res,\
+ .mirror = mir,\
+ .i2c_rate = i2c_spd,\
+ .flash = flash_attach,\
+ .pwdn_info = ((pwdn_active&0x10)|0x01),\
+ .powerup_sequence = CONS(sensor_name,_PWRSEQ),\
+ .mclk_rate = mclk,\
+ }
+
+#define new_camera_device(sensor_name,\
+ face,\
+ pwdn_io,\
+ flash_attach,\
+ mir,\
+ i2c_chl,\
+ cif_chl) \
+ new_camera_device_ex(sensor_name,\
+ face,\
+ INVALID_VALUE,\
+ INVALID_VALUE,\
+ INVALID_VALUE,\
+ INVALID_VALUE,\
+ INVALID_VALUE,\
+ pwdn_io,\
+ CONS(sensor_name,_PWRDN_ACTIVE),\
+ flash_attach,\
+ CONS(sensor_name,_FULL_RESOLUTION),\
+ mir,i2c_chl,\
+ 100000,\
+ CONS(sensor_name,_I2C_ADDR),\
+ cif_chl,\
+ 24)
+
+#define new_camera_device_end new_camera_device_ex(end,end,\
+ INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,\
+ INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,\
+ INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE,INVALID_VALUE)
+
+
/*---------------- Camera Sensor Must Define Macro Begin ------------------------*/
#define RK29_CAM_SENSOR_OV7675 ov7675
#define RK29_CAM_SENSOR_OV9650 ov9650
#define RK29_CAM_SENSOR_GC0308 gc0308
#define RK29_CAM_SENSOR_GC0309 gc0309
#define RK29_CAM_SENSOR_GC2015 gc2015
+#define RK29_CAM_SENSOR_GC0328 gc0328
+#define RK29_CAM_SENSOR_GC0329 gc0329
+#define RK29_CAM_SENSOR_GC2035 gc2035
#define RK29_CAM_SENSOR_SIV120B siv120b
#define RK29_CAM_SENSOR_SIV121D siv121d
#define RK29_CAM_SENSOR_SID130B sid130B
#define RK29_CAM_SENSOR_HI253 hi253
#define RK29_CAM_SENSOR_HI704 hi704
#define RK29_CAM_SENSOR_NT99250 nt99250
+#define RK29_CAM_SENSOR_SP0718 sp0718
#define RK29_CAM_SENSOR_SP0838 sp0838
#define RK29_CAM_SENSOR_SP2518 sp2518
-#define RK29_CAM_SENSOR_GC0329 gc0329
#define RK29_CAM_SENSOR_S5K5CA s5k5ca
#define RK29_CAM_ISP_MTK9335 mtk9335isp
-#define RK29_CAM_SENSOR_GC2035 gc2035
+#define RK29_CAM_SENSOR_HM2057 hm2057
#define RK29_CAM_SENSOR_HM5065 hm5065
+#define RK29_CAM_SENSOR_NT99160 nt99160 //oyyf@rock-chips.com
+#define RK29_CAM_SENSOR_NT99240 nt99240 //oyyf@rock-chips.com
+#define RK29_CAM_SENSOR_NT99252 nt99252 //oyyf@rock-chips.com
+#define RK29_CAM_SENSOR_NT99340 nt99340 //oyyf@rock-chips.com
+
#define RK29_CAM_SENSOR_NAME_OV7675 "ov7675"
#define RK29_CAM_SENSOR_NAME_OV9650 "ov9650"
#define RK29_CAM_SENSOR_NAME_GC0308 "gc0308"
#define RK29_CAM_SENSOR_NAME_GC0309 "gc0309"
#define RK29_CAM_SENSOR_NAME_GC2015 "gc2015"
+#define RK29_CAM_SENSOR_NAME_GC0328 "gc0328"
+#define RK29_CAM_SENSOR_NAME_GC2035 "gc2035"
+#define RK29_CAM_SENSOR_NAME_GC0329 "gc0329"
#define RK29_CAM_SENSOR_NAME_SIV120B "siv120b"
#define RK29_CAM_SENSOR_NAME_SIV121D "siv121d"
#define RK29_CAM_SENSOR_NAME_SID130B "sid130B"
#define RK29_CAM_SENSOR_NAME_HI253 "hi253"
#define RK29_CAM_SENSOR_NAME_HI704 "hi704"
#define RK29_CAM_SENSOR_NAME_NT99250 "nt99250"
+#define RK29_CAM_SENSOR_NAME_SP0718 "sp0718"
#define RK29_CAM_SENSOR_NAME_SP0838 "sp0838"
#define RK29_CAM_SENSOR_NAME_SP2518 "sp2518"
-#define RK29_CAM_SENSOR_NAME_GC0329 "gc0329"
#define RK29_CAM_SENSOR_NAME_S5K5CA "s5k5ca"
#define RK29_CAM_ISP_NAME_MTK9335ISP "mtk9335isp"
-#define RK29_CAM_SENSOR_NAME_GC2035 "gc2035"
+#define RK29_CAM_SENSOR_NAME_HM2057 "hm2057"
#define RK29_CAM_SENSOR_NAME_HM5065 "hm5065"
+//Sensor full resolution define
#define ov7675_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define ov9650_FULL_RESOLUTION 0x130000 // 1.3 megapixel
#define ov2640_FULL_RESOLUTION 0x200000 // 2 megapixel
#else
#define gc0308_FULL_RESOLUTION 0x30000 // 0.3 megapixel#endif
#endif
-
+#define gc0328_FULL_RESOLUTION 0x30000 // 0.3 megapixel
+#define gc0307_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define gc0309_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define gc2015_FULL_RESOLUTION 0x200000 // 2 megapixel
#define siv120b_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define hi704_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define nt99250_FULL_RESOLUTION 0x200000 // 2 megapixel
+#define sp0718_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define sp0838_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define sp2518_FULL_RESOLUTION 0x200000 // 2 megapixel
#define gc0329_FULL_RESOLUTION 0x30000 // 0.3 megapixel
#define s5k5ca_FULL_RESOLUTION 0x300000 // 3 megapixel
#define mtk9335isp_FULL_RESOLUTION 0x500000 //5 megapixel
#define gc2035_FULL_RESOLUTION 0x200000 // 2 megapixel
+#define hm2057_FULL_RESOLUTION 0x200000 // 2 megapixel
#define hm5065_FULL_RESOLUTION 0x500000 // 5 megapixel
+#define nt99160_FULL_RESOLUTION 0x100000 // oyyf@rock-chips.com: 1 megapixel 1280*720
+#define nt99240_FULL_RESOLUTION 0x200000 // oyyf@rock-chips.com: 2 megapixel 1600*1200
+#define nt99252_FULL_RESOLUTION 0x200000 // oyyf@rock-chips.com: 2 megapixel 1600*1200
+#define nt99340_FULL_RESOLUTION 0x300000 // oyyf@rock-chips.com: 3 megapixel 2048*1536
+
+#define end_FULL_RESOLUTION 0x00
+
+//Sensor i2c addr define
+#define ov7675_I2C_ADDR 0x78
+#define ov9650_I2C_ADDR 0x60
+#define ov2640_I2C_ADDR 0x60
+#define ov2655_I2C_ADDR 0x60
+#define ov2659_I2C_ADDR 0x60
+#define ov7690_I2C_ADDR 0x42
+#define ov3640_I2C_ADDR 0x78
+#define ov3660_I2C_ADDR 0x78
+#define ov5640_I2C_ADDR 0x78
+#define ov5642_I2C_ADDR 0x78
+
+#define s5k6aa_I2C_ADDR 0x78 //0x5a
+#define s5k5ca_I2C_ADDR 0x78 //0x5a
+
+#define mt9d112_I2C_ADDR 0x78
+#define mt9d113_I2C_ADDR 0x78
+#define mt9t111_I2C_ADDR 0x78 // 0x7a
+
+#define mt9p111_I2C_ADDR 0x78 //0x7a
+#define gt2005_I2C_ADDR 0x78
+#define gc0307_I2C_ADDR 0x42
+#define gc0328_I2C_ADDR 0x42
+#define gc0308_I2C_ADDR 0x42
+#define gc0309_I2C_ADDR 0x42
+#define gc0329_I2C_ADDR 0x62
+#define gc2015_I2C_ADDR 0x60
+#define gc2035_I2C_ADDR 0x78
+
+#define siv120b_I2C_ADDR INVALID_VALUE
+#define siv121d_I2C_ADDR INVALID_VALUE
+#define sid130B_I2C_ADDR 0x37
+
+#define hi253_I2C_ADDR 0x40
+#define hi704_I2C_ADDR 0x60
+
+#define nt99160_I2C_ADDR 0x54
+#define nt99240_I2C_ADDR 0x6c
+#define nt99250_I2C_ADDR 0x6c
+#define nt99252_I2C_ADDR 0x6c
+#define nt99340_I2C_ADDR 0x76
+
+#define sp0718_I2C_ADDR 0x42
+#define sp0838_I2C_ADDR INVALID_VALUE
+#define sp0a19_I2C_ADDR 0x7a
+#define sp1628_I2C_ADDR 0x78
+#define sp2518_I2C_ADDR 0x60
+#define mtk9335isp_I2C_ADDR 0x50
+#define hm2057_I2C_ADDR 0x48
+#define hm5065_I2C_ADDR 0x3e
+#define end_I2C_ADDR INVALID_VALUE
+
+
+//Sensor power down active level define
+#define ov7675_PWRDN_ACTIVE 0x01
+#define ov9650_PWRDN_ACTIVE 0x01
+#define ov2640_PWRDN_ACTIVE 0x01
+#define ov2655_PWRDN_ACTIVE 0x01
+#define ov2659_PWRDN_ACTIVE 0x01
+#define ov7690_PWRDN_ACTIVE 0x01
+#define ov3640_PWRDN_ACTIVE 0x01
+#define ov3660_PWRDN_ACTIVE 0x01
+#define ov5640_PWRDN_ACTIVE 0x01
+#define ov5642_PWRDN_ACTIVE 0x01
+
+#define s5k6aa_PWRDN_ACTIVE 0x00
+#define s5k5ca_PWRDN_ACTIVE 0x00
+
+#define mt9d112_PWRDN_ACTIVE 0x01
+#define mt9d113_PWRDN_ACTIVE 0x01
+#define mt9t111_PWRDN_ACTIVE 0x01
+#define mt9p111_PWRDN_ACTIVE 0x01
+
+#define gt2005_PWRDN_ACTIVE 0x00
+#define gc0307_PWRDN_ACTIVE 0x01
+#define gc0308_PWRDN_ACTIVE 0x01
+#define gc0328_PWRDN_ACTIVE 0x01
+#define gc0309_PWRDN_ACTIVE 0x01
+#define gc0329_PWRDN_ACTIVE 0x01
+#define gc2015_PWRDN_ACTIVE 0x01
+#define gc2035_PWRDN_ACTIVE 0x01
+
+#define siv120b_PWRDN_ACTIVE INVALID_VALUE
+#define siv121d_PWRDN_ACTIVE INVALID_VALUE
+#define sid130B_PWRDN_ACTIVE 0x37
+
+#define hi253_PWRDN_ACTIVE 0x01
+#define hi704_PWRDN_ACTIVE 0x01
+
+#define nt99160_PWRDN_ACTIVE 0x01
+#define nt99240_PWRDN_ACTIVE 0x01
+#define nt99250_PWRDN_ACTIVE 0x01
+#define nt99252_PWRDN_ACTIVE 0x01
+#define nt99340_PWRDN_ACTIVE 0x01
+
+#define sp0718_PWRDN_ACTIVE 0x01
+#define sp0838_PWRDN_ACTIVE 0x01
+#define sp0a19_PWRDN_ACTIVE 0x01
+#define sp1628_PWRDN_ACTIVE 0x01
+#define sp2518_PWRDN_ACTIVE 0x01
+#define hm2057_PWRDN_ACTIVE 0x01
+#define hm5065_PWRDN_ACTIVE 0x00
+#define mtk9335isp_PWRDN_ACTIVE 0x01
+#define end_PWRDN_ACTIVE INVALID_VALUE
+
+
+//Sensor power up sequence define
+//type: bit0-bit4
+#define SENSOR_PWRSEQ_BEGIN 0x00
+#define SENSOR_PWRSEQ_AVDD 0x01
+#define SENSOR_PWRSEQ_DOVDD 0x02
+#define SENSOR_PWRSEQ_DVDD 0x03
+#define SENSOR_PWRSEQ_PWR 0x04
+#define SENSOR_PWRSEQ_HWRST 0x05
+#define SENSOR_PWRSEQ_PWRDN 0x06
+#define SENSOR_PWRSEQ_CLKIN 0x07
+#define SENSOR_PWRSEQ_END 0x0F
+
+#define SENSOR_PWRSEQ_SET(type,idx) (type<<(idx*4))
+#define SENSOR_PWRSEQ_GET(seq,idx) ((seq>>(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<<RK29_CAM_POWERACTIVE_BITPOS)
#define RK29_CAM_POWERACTIVE_H (0x01<<RK29_CAM_POWERACTIVE_BITPOS)
#define RK29_CAM_POWERACTIVE_L (0x00<<RK29_CAM_POWERACTIVE_BITPOS)
-#define RK29_CAM_RESETACTIVE_BITPOS 0x01
+//#define RK29_CAM_RESETACTIVE_BITPOS 0x01
#define RK29_CAM_RESETACTIVE_MASK (1<<RK29_CAM_RESETACTIVE_BITPOS)
#define RK29_CAM_RESETACTIVE_H (0x01<<RK29_CAM_RESETACTIVE_BITPOS)
#define RK29_CAM_RESETACTIVE_L (0x00<<RK29_CAM_RESETACTIVE_BITPOS)
-#define RK29_CAM_POWERDNACTIVE_BITPOS 0x02
+//#define RK29_CAM_POWERDNACTIVE_BITPOS 0x02
#define RK29_CAM_POWERDNACTIVE_MASK (1<<RK29_CAM_POWERDNACTIVE_BITPOS)
#define RK29_CAM_POWERDNACTIVE_H (0x01<<RK29_CAM_POWERDNACTIVE_BITPOS)
#define RK29_CAM_POWERDNACTIVE_L (0x00<<RK29_CAM_POWERDNACTIVE_BITPOS)
-#define RK29_CAM_FLASHACTIVE_BITPOS 0x03
+//#define RK29_CAM_FLASHACTIVE_BITPOS 0x03
#define RK29_CAM_FLASHACTIVE_MASK (1<<RK29_CAM_FLASHACTIVE_BITPOS)
#define RK29_CAM_FLASHACTIVE_H (0x01<<RK29_CAM_FLASHACTIVE_BITPOS)
#define RK29_CAM_FLASHACTIVE_L (0x00<<RK29_CAM_FLASHACTIVE_BITPOS)
#define RK29_CAM_SUBDEV_IOREQUEST 0x02
#define RK29_CAM_SUBDEV_CB_REGISTER 0x03
+#define Sensor_HasBeen_PwrOff(a) (a&0x01)
+#define Sensor_Support_DirectResume(a) ((a&0x10)==0x10)
+
enum rk29camera_ioctrl_cmd
{
Cam_Power,
Cam_Reset,
Cam_PowerDown,
- Cam_Flash
+ Cam_Flash,
+ Cam_Mclk
};
enum rk29sensor_power_cmd
{
+ Sensor_Power,
Sensor_Reset,
Sensor_PowerDown,
Sensor_Flash
struct platform_device device_info;
}rk_camera_device_register_info_t;
+struct rkcamera_platform_data {
+ rk_camera_device_register_info_t dev;
+ char dev_name[32];
+ struct rk29camera_gpio_res io;
+ int orientation;
+ int resolution;
+ int mirror; /* bit0: 0: mirror off
+ 1: mirror on
+ bit1: 0: flip off
+ 1: flip on
+ */
+ int i2c_rate; /* 100KHz = 100000 */
+ bool flash; /* true: the sensor attached flash;
+ false: the sensor haven't attach flash;
+
+ */
+ int pwdn_info; /* bit4: 1: sensor isn't need to be init after exit stanby, it can streaming directly
+ 0: sensor must be init after exit standby;
+
+ bit0: 1: sensor power have been turn off;
+ 0: sensor power is always on;
+ */
+
+ long powerup_sequence; /*
+ bit0-bit3 --- power up sequence first step;
+ bit4-bit7 --- power up sequence second step;
+ .....
+ */
+ int mclk_rate; /* MHz : 24/48 */
+
+};
+
struct rk29camera_platform_data {
int (*io_init)(void);
int (*io_deinit)(int sensor);
int (*iomux)(int pin);
int (*sensor_ioctrl)(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
+
+ int (*sensor_register)(void);
+ int (*sensor_mclk)(int cif_idx, int on, int clk_rate);
+
rk_sensor_user_init_data_s* sensor_init_data[RK_CAM_NUM];
struct rk29camera_gpio_res gpio_res[RK_CAM_NUM];
struct rk29camera_mem_res meminfo;
struct rk29camera_mem_res meminfo_cif1;
struct rk29camera_info info[RK_CAM_NUM];
rk_camera_device_register_info_t register_dev[RK_CAM_NUM];
+ struct rkcamera_platform_data *register_dev_new;
};
struct rk29camera_platform_ioctl_cb {
int (*sensor_power_cb)(struct rk29camera_gpio_res *res, int on);
int (*sensor_reset_cb)(struct rk29camera_gpio_res *res, int on);
int (*sensor_powerdown_cb)(struct rk29camera_gpio_res *res, int on);
- int (*sensor_flash_cb)(struct rk29camera_gpio_res *res, int on);
+ int (*sensor_flash_cb)(struct rk29camera_gpio_res *res, int on);
};
typedef struct rk29_camera_sensor_cb {
int (*sensor_cb)(void *arg);
int (*scale_crop_cb)(struct work_struct *work);
}rk29_camera_sensor_cb_s;
-
-int camera_set_platform_param(int id, int i2c, int gpio);
#endif /* __ASM_ARCH_CAMERA_H_ */
#ifdef CONFIG_VIDEO_RK29 \r
/*---------------- Camera Sensor Fixed Macro Begin ------------------------*/\r
// Below Macro is fixed, programer don't change it!!!!!!\r
-#define _CONS(a,b) a##b\r
-#define CONS(a,b) _CONS(a,b)\r
\r
-#define __STR(x) #x\r
-#define _STR(x) __STR(x)\r
-#define STR(x) _STR(x)\r
-\r
-#if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)\r
+#if defined (CONFIG_SENSOR_IIC_ADDR_0) && (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)\r
#define PMEM_SENSOR_FULL_RESOLUTION_0 CONS(CONFIG_SENSOR_0,_FULL_RESOLUTION)\r
\r
#ifdef CONFIG_SENSOR_CIF_INDEX_0\r
#define PMEM_SENSOR_FULL_RESOLUTION_CIF_1 0x00\r
#endif\r
\r
-#if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)\r
+#if defined (CONFIG_SENSOR_IIC_ADDR_1) && (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)\r
#define PMEM_SENSOR_FULL_RESOLUTION_1 CONS(CONFIG_SENSOR_1,_FULL_RESOLUTION)\r
\r
#ifdef CONFIG_SENSOR_CIF_INDEX_1\r
#endif\r
#endif\r
\r
-#ifdef CONFIG_SENSOR_IIC_ADDR_01\r
-#if (CONFIG_SENSOR_IIC_ADDR_01 != 0x00)\r
+#if defined (CONFIG_SENSOR_IIC_ADDR_01) && (CONFIG_SENSOR_IIC_ADDR_01!=0x00)\r
#define PMEM_SENSOR_FULL_RESOLUTION_01 CONS(CONFIG_SENSOR_01,_FULL_RESOLUTION)\r
\r
#ifdef CONFIG_SENSOR_CIF_INDEX_01\r
#endif\r
#endif\r
#endif\r
-#endif\r
\r
-#ifdef CONFIG_SENSOR_IIC_ADDR_02\r
-#if (CONFIG_SENSOR_IIC_ADDR_02 != 0x00)\r
+#if defined (CONFIG_SENSOR_IIC_ADDR_02) && (CONFIG_SENSOR_IIC_ADDR_02!=0x00)\r
#define PMEM_SENSOR_FULL_RESOLUTION_02 CONS(CONFIG_SENSOR_02,_FULL_RESOLUTION)\r
\r
#ifdef CONFIG_SENSOR_CIF_INDEX_02\r
#endif\r
#endif\r
#endif\r
-#endif\r
\r
#ifdef CONFIG_SENSOR_IIC_ADDR_11\r
#if (CONFIG_SENSOR_IIC_ADDR_11 != 0x00)\r
#define PMEM_CAM_NECESSARY_CIF_0 0x1400000 /* 1280*720*1.5*4(preview) + 7.5M(capture raw) + 4M(jpeg encode output) */\r
#define PMEM_CAMIPP_NECESSARY_CIF_0 0x800000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x300000)\r
-#define PMEM_CAM_NECESSARY_CIF_0 0xe00000 /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_0 0x500000\r
+#define PMEM_CAM_NECESSARY_CIF_0 0xf00000 /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_0 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x200000) /* 1280*720*1.5*4(preview) + 3M(capture raw) + 3M(jpeg encode output) */\r
#define PMEM_CAM_NECESSARY_CIF_0 0xc00000\r
#define PMEM_CAMIPP_NECESSARY_CIF_0 0x600000\r
#elif ((PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x100000) || (PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x130000))\r
-#define PMEM_CAM_NECESSARY_CIF_0 0x800000 /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_0 0x400000\r
+#define PMEM_CAM_NECESSARY_CIF_0 0xa00000 /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_0 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x30000)\r
-#define PMEM_CAM_NECESSARY_CIF_0 0x400000 /* 640*480*1.5*4(preview) + 1M(capture raw) + 1M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_0 0x400000\r
+#define PMEM_CAM_NECESSARY_CIF_0 0x600000 /* 640*480*1.5*4(preview) + 1M(capture raw) + 1M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_0 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_0 == 0x00)\r
#define PMEM_CAM_NECESSARY_CIF_0 0x00\r
#define PMEM_CAMIPP_NECESSARY_CIF_0 0x00\r
#define PMEM_CAM_NECESSARY_CIF_1 0x1400000 /* 1280*720*1.5*4(preview) + 7.5M(capture raw) + 4M(jpeg encode output) */\r
#define PMEM_CAMIPP_NECESSARY_CIF_1 0x800000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_1 == 0x300000)\r
-#define PMEM_CAM_NECESSARY_CIF_1 0xe00000 /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_1 0x500000\r
+#define PMEM_CAM_NECESSARY_CIF_1 0xf00000 /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_1 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_1== 0x200000) /* 1280*720*1.5*4(preview) + 3M(capture raw) + 3M(jpeg encode output) */\r
#define PMEM_CAM_NECESSARY_CIF_1 0xc00000\r
#define PMEM_CAMIPP_NECESSARY_CIF_1 0x600000\r
#elif ((PMEM_SENSOR_FULL_RESOLUTION_CIF_1 == 0x100000) || (PMEM_SENSOR_FULL_RESOLUTION_CIF_1 == 0x130000))\r
-#define PMEM_CAM_NECESSARY_CIF_1 0x800000 /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_1 0x400000\r
+#define PMEM_CAM_NECESSARY_CIF_1 0xa00000 /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_1 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_1 == 0x30000)\r
-#define PMEM_CAM_NECESSARY_CIF_1 0x400000 /* 640*480*1.5*4(preview) + 1M(capture raw) + 1M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY_CIF_1 0x400000\r
+#define PMEM_CAM_NECESSARY_CIF_1 0x600000 /* 640*480*1.5*4(preview) + 1M(capture raw) + 1M(jpeg encode output) */\r
+#define PMEM_CAMIPP_NECESSARY_CIF_1 0x600000\r
#elif (PMEM_SENSOR_FULL_RESOLUTION_CIF_1 == 0x00)\r
#define PMEM_CAM_NECESSARY_CIF_1 0x00\r
#define PMEM_CAMIPP_NECESSARY_CIF_1 0x00\r
#endif\r
\r
#else // #ifndef PMEM_CAM_SIZE\r
+/*\r
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int camio_version = KERNEL_VERSION(0,1,0);\r
+module_param(camio_version, int, S_IRUGO);\r
\r
-static int camera_debug;\r
+\r
+static int camera_debug=1;\r
module_param(camera_debug, int, S_IRUGO|S_IWUSR); \r
\r
+#undef CAMMODULE_NAME\r
+#define CAMMODULE_NAME "rk_cam_io"\r
+\r
#define ddprintk(level, fmt, arg...) do { \\r
if (camera_debug >= level) \\r
- printk(KERN_WARNING"rk_cam_io: " fmt , ## arg); } while (0)\r
+ printk(KERN_WARNING"%s(%d):" fmt , CAMMODULE_NAME,__LINE__,## arg); } while (0)\r
\r
-#define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__) \r
+#define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__) \r
+#define eprintk(format, ...) printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__) \r
\r
#define SENSOR_NAME_0 STR(CONFIG_SENSOR_0) /* back camera sensor 0 */\r
#define SENSOR_NAME_1 STR(CONFIG_SENSOR_1) /* front camera sensor 0 */\r
static int rk_sensor_io_deinit(int sensor);\r
static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on);\r
static int rk_sensor_power(struct device *dev, int on);\r
-#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) \\r
- || (CONFIG_SENSOR_RESET_PIN_01 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_02 != INVALID_GPIO) \\r
- || (CONFIG_SENSOR_RESET_PIN_11 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_12 != INVALID_GPIO)\r
+static int rk_sensor_register(void);\r
static int rk_sensor_reset(struct device *dev);\r
-#endif\r
+\r
static int rk_sensor_powerdown(struct device *dev, int on);\r
\r
static struct rk29camera_platform_data rk_camera_platform_data = {\r
.io_deinit = rk_sensor_io_deinit,\r
.iomux = rk_sensor_iomux,\r
.sensor_ioctrl = rk_sensor_ioctrl,\r
- \r
+ .sensor_register = rk_sensor_register,\r
.gpio_res = {\r
{\r
- #if CONFIG_SENSOR_IIC_ADDR_0 \r
+ #if defined CONFIG_SENSOR_IIC_ADDR_0 && CONFIG_SENSOR_IIC_ADDR_0 \r
.gpio_reset = CONFIG_SENSOR_RESET_PIN_0,\r
.gpio_power = CONFIG_SENSOR_POWER_PIN_0,\r
.gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_0,\r
.dev_name = NULL,\r
#endif\r
}, {\r
- #if CONFIG_SENSOR_IIC_ADDR_1 \r
+ #if defined CONFIG_SENSOR_IIC_ADDR_1 && CONFIG_SENSOR_IIC_ADDR_1 \r
.gpio_reset = CONFIG_SENSOR_RESET_PIN_1,\r
.gpio_power = CONFIG_SENSOR_POWER_PIN_1,\r
.gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_1,\r
\r
.info = {\r
{\r
+ #ifdef CONFIG_SENSOR_0 \r
.dev_name = SENSOR_DEVICE_NAME_0,\r
.orientation = CONFIG_SENSOR_ORIENTATION_0, \r
+ #else\r
+ .dev_name = NULL,\r
+ .orientation = 0x00, \r
+ #endif\r
},{\r
+ #ifdef CONFIG_SENSOR_1\r
.dev_name = SENSOR_DEVICE_NAME_1,\r
.orientation = CONFIG_SENSOR_ORIENTATION_1,\r
+ #else\r
+ .dev_name = NULL,\r
+ .orientation = 0x00, \r
+ #endif\r
#ifdef CONFIG_SENSOR_01\r
},{\r
.dev_name = SENSOR_DEVICE_NAME_01,\r
},\r
#endif\r
},\r
+ .register_dev_new = new_camera,\r
};\r
\r
\r
if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {\r
if (on) {\r
gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
- dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+ dprintk("%s PowerPin=%d ..PinLevel = %x \n",res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
msleep(10);\r
} else {\r
gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
- dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+ dprintk("%s PowerPin=%d ..PinLevel = %x \n",res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
}\r
} else {\r
ret = RK29_CAM_EIO_REQUESTFAIL;\r
- printk("%s..%s..PowerPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_power);\r
+ eprintk("%s PowerPin=%d request failed!\n", res->dev_name,camera_power);\r
} \r
} else {\r
ret = RK29_CAM_EIO_INVALID;\r
if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) {\r
if (on) {\r
gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
- dprintk("%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+ dprintk("%s ResetPin=%d ..PinLevel = %x \n",res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
} else {\r
gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
- dprintk("%s..%s..ResetPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+ dprintk("%s ResetPin= %d..PinLevel = %x \n",res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
}\r
} else {\r
ret = RK29_CAM_EIO_REQUESTFAIL;\r
- printk("%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_reset);\r
+ eprintk("%s ResetPin=%d request failed!\n", res->dev_name,camera_reset);\r
}\r
} else {\r
ret = RK29_CAM_EIO_INVALID;\r
if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
if (on) {\r
gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
- dprintk("%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+ dprintk("%s PowerDownPin=%d ..PinLevel = %x \n" ,res->dev_name,camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
} else {\r
gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
- dprintk("%s..%s..PowerDownPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+ dprintk("%s PowerDownPin= %d..PinLevel = %x \n" ,res->dev_name, camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
}\r
} else {\r
ret = RK29_CAM_EIO_REQUESTFAIL;\r
- dprintk("%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_powerdown);\r
+ dprintk("%s PowerDownPin=%d request failed!\n", res->dev_name,camera_powerdown);\r
}\r
} else {\r
ret = RK29_CAM_EIO_INVALID;\r
case Flash_Off:\r
{\r
gpio_set_value(camera_flash,(((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
- 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)); \r
+ dprintk("%s FlashPin= %d..PinLevel = %x \n", res->dev_name, camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); \r
break;\r
}\r
\r
case Flash_On:\r
{\r
gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
- dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+ dprintk("%s FlashPin=%d ..PinLevel = %x \n", res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
break;\r
}\r
\r
case Flash_Torch:\r
{\r
gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
- dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+ dprintk("%s FlashPin=%d ..PinLevel = %x \n", res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
break;\r
}\r
\r
default:\r
{\r
- printk("%s..%s..Flash command(%d) is invalidate \n",__FUNCTION__,res->dev_name,on);\r
+ eprintk("%s Flash command(%d) is invalidate \n", res->dev_name,on);\r
break;\r
}\r
}\r
} else {\r
ret = RK29_CAM_EIO_REQUESTFAIL;\r
- printk("%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_flash);\r
+ eprintk("%s FlashPin=%d request failed!\n", res->dev_name,camera_flash);\r
}\r
} else {\r
ret = RK29_CAM_EIO_INVALID;\r
{\r
switch (idx)\r
{\r
+ #ifdef CONFIG_SENSOR_0\r
case 0:\r
{\r
if ((w==176) && (h==144)) {\r
}\r
break;\r
}\r
+ #endif\r
+ #ifdef CONFIG_SENSOR_1\r
case 1:\r
{\r
if ((w==176) && (h==144)) {\r
}\r
break;\r
}\r
-\r
+ #endif\r
#ifdef CONFIG_SENSOR_01\r
case 2:\r
{\r
}\r
#endif\r
default:\r
- printk(KERN_ERR"rk_cam_io: sensor-%d have not been define in board file!",idx);\r
+ eprintk(" sensor-%d have not been define in board file!",idx);\r
}\r
}\r
-\r
-static int rk_sensor_io_init(void)\r
+static int _rk_sensor_io_init_(struct rk29camera_gpio_res *gpio_res)\r
{\r
- int ret = 0, i,j;\r
+ int ret = 0, i;\r
unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;\r
unsigned int camera_ioflag;\r
- static bool is_init = false;\r
- struct rk29camera_platform_data* plat_data = &rk_camera_platform_data;\r
-\r
- if(is_init) { \r
- return 0;\r
- } else {\r
- is_init = true;\r
- }\r
- \r
- if (sensor_ioctl_cb.sensor_power_cb == NULL)\r
- sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb;\r
- if (sensor_ioctl_cb.sensor_reset_cb == NULL)\r
- sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb;\r
- if (sensor_ioctl_cb.sensor_powerdown_cb == NULL)\r
- sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb;\r
- if (sensor_ioctl_cb.sensor_flash_cb == NULL)\r
- sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb;\r
- \r
- for(i = 0;i < RK_CAM_NUM; i++){\r
- if (plat_data->gpio_res[i].dev_name == NULL)\r
- continue;\r
- camera_reset = plat_data->gpio_res[i].gpio_reset;\r
- camera_power = plat_data->gpio_res[i].gpio_power;\r
- camera_powerdown = plat_data->gpio_res[i].gpio_powerdown;\r
- camera_flash = plat_data->gpio_res[i].gpio_flash;\r
- camera_ioflag = plat_data->gpio_res[i].gpio_flag;\r
- plat_data->gpio_res[i].gpio_init = 0;\r
-\r
- if (camera_power != INVALID_GPIO) {\r
- ret = gpio_request(camera_power, "camera power");\r
- if (ret) {\r
- for (j=0; j<i; j++) {\r
- if (camera_power == plat_data->gpio_res[j].gpio_power)\r
- break;\r
- }\r
- if (i==j) {\r
- printk(KERN_ERR"rk_cam_io: %s..%s..power pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power);\r
- goto sensor_io_init_erro;\r
+ struct rk29camera_gpio_res *io_res;\r
+ bool io_requested_in_camera;\r
+\r
+ camera_reset = gpio_res->gpio_reset;\r
+ camera_power = gpio_res->gpio_power;\r
+ camera_powerdown = gpio_res->gpio_powerdown;\r
+ camera_flash = gpio_res->gpio_flash;\r
+ camera_ioflag = gpio_res->gpio_flag;\r
+ gpio_res->gpio_init = 0;\r
+\r
+ if (camera_power != INVALID_GPIO) {\r
+ ret = gpio_request(camera_power, "camera power");\r
+ if (ret) {\r
+ io_requested_in_camera = false;\r
+ for (i=0; i<RK_CAM_NUM; i++) {\r
+ io_res = &rk_camera_platform_data.gpio_res[i];\r
+ if (io_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) {\r
+ if (io_res->gpio_power == camera_power)\r
+ io_requested_in_camera = true; \r
}\r
}\r
\r
- if (rk_camera_platform_data.iomux(camera_power) < 0) {\r
- 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);\r
- goto sensor_io_init_erro;\r
+ if (io_requested_in_camera==false) {\r
+ i=0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ io_res = &new_camera[i].io;\r
+ if (io_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) {\r
+ if (io_res->gpio_power == camera_power)\r
+ io_requested_in_camera = true; \r
+ }\r
+ i++;\r
+ }\r
}\r
\r
- plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK;\r
- gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
- gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
-\r
- dprintk("%s....power pin(%d) init success(0x%x) \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+ if (io_requested_in_camera==false) {\r
+ printk( "%s power pin(%d) init failed\n", gpio_res->dev_name,camera_power);\r
+ goto _rk_sensor_io_init_end_;\r
+ } else {\r
+ ret =0;\r
+ }\r
+ }\r
\r
+ if (rk_camera_platform_data.iomux(camera_power) < 0) {\r
+ ret = -1;\r
+ eprintk("%s power pin(%d) iomux init failed\n",gpio_res->dev_name,camera_power);\r
+ goto _rk_sensor_io_init_end_;\r
}\r
+ \r
+ gpio_res->gpio_init |= RK29_CAM_POWERACTIVE_MASK;\r
+ gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+ gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
\r
- if (camera_reset != INVALID_GPIO) {\r
- ret = gpio_request(camera_reset, "camera reset");\r
- if (ret) {\r
- for (j=0; j<i; j++) {\r
- if (camera_reset == plat_data->gpio_res[j].gpio_reset) { \r
- break;\r
- }\r
- }\r
- if (i==j) {\r
- printk(KERN_ERR"rk_cam_io: %s..%s..reset pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_reset);\r
- goto sensor_io_init_erro;\r
+ 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));\r
+\r
+ }\r
+\r
+ if (camera_reset != INVALID_GPIO) {\r
+ ret = gpio_request(camera_reset, "camera reset");\r
+ if (ret) {\r
+ io_requested_in_camera = false;\r
+ for (i=0; i<RK_CAM_NUM; i++) {\r
+ io_res = &rk_camera_platform_data.gpio_res[i];\r
+ if (io_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) {\r
+ if (io_res->gpio_reset == camera_reset)\r
+ io_requested_in_camera = true; \r
}\r
}\r
\r
- if (rk_camera_platform_data.iomux(camera_reset) < 0) {\r
- 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);\r
- goto sensor_io_init_erro;\r
+ if (io_requested_in_camera==false) {\r
+ i=0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ io_res = &new_camera[i].io;\r
+ if (io_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) {\r
+ if (io_res->gpio_reset == camera_reset)\r
+ io_requested_in_camera = true; \r
+ }\r
+ i++;\r
+ }\r
}\r
\r
- plat_data->gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK;\r
- gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
- gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-\r
- dprintk("%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+ if (io_requested_in_camera==false) {\r
+ eprintk("%s reset pin(%d) init failed\n" ,gpio_res->dev_name,camera_reset);\r
+ goto _rk_sensor_io_init_end_;\r
+ } else {\r
+ ret =0;\r
+ }\r
+ }\r
\r
+ if (rk_camera_platform_data.iomux(camera_reset) < 0) {\r
+ ret = -1;\r
+ eprintk("%s reset pin(%d) iomux init failed\n", gpio_res->dev_name,camera_reset);\r
+ goto _rk_sensor_io_init_end_;\r
}\r
+ \r
+ gpio_res->gpio_init |= RK29_CAM_RESETACTIVE_MASK;\r
+ gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+ gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
\r
- if (camera_powerdown != INVALID_GPIO) {\r
- ret = gpio_request(camera_powerdown, "camera powerdown");\r
- if (ret) {\r
- for (j=0; j<i; j++) {\r
- if (camera_powerdown == plat_data->gpio_res[j].gpio_powerdown) { \r
- break;\r
- }\r
- }\r
- if (i==j) {\r
- printk(KERN_ERR"rk_cam_io: %s..%s..powerdown pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_powerdown);\r
- goto sensor_io_init_erro;\r
+ 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));\r
+\r
+ }\r
+\r
+ if (camera_powerdown != INVALID_GPIO) {\r
+ ret = gpio_request(camera_powerdown, "camera powerdown");\r
+ if (ret) {\r
+ io_requested_in_camera = false;\r
+ for (i=0; i<RK_CAM_NUM; i++) {\r
+ io_res = &rk_camera_platform_data.gpio_res[i];\r
+ if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
+ if (io_res->gpio_powerdown == camera_powerdown)\r
+ io_requested_in_camera = true; \r
}\r
}\r
\r
- if (rk_camera_platform_data.iomux(camera_powerdown) < 0) {\r
- 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);\r
- goto sensor_io_init_erro;\r
+ if (io_requested_in_camera==false) {\r
+ i=0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ io_res = &new_camera[i].io;\r
+ if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
+ if (io_res->gpio_powerdown == camera_powerdown)\r
+ io_requested_in_camera = true; \r
+ }\r
+ i++;\r
+ }\r
}\r
\r
- plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK;\r
- gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
- gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
-\r
- dprintk("%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+ if (io_requested_in_camera==false) {\r
+ eprintk("%s powerdown pin(%d) init failed\n",gpio_res->dev_name,camera_powerdown);\r
+ goto _rk_sensor_io_init_end_;\r
+ } else {\r
+ ret =0;\r
+ }\r
+ }\r
\r
+ if (rk_camera_platform_data.iomux(camera_powerdown) < 0) {\r
+ ret = -1;\r
+ eprintk("%s powerdown pin(%d) iomux init failed\n",gpio_res->dev_name,camera_powerdown);\r
+ goto _rk_sensor_io_init_end_;\r
}\r
+ \r
+ gpio_res->gpio_init |= RK29_CAM_POWERDNACTIVE_MASK;\r
+ gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+ gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
\r
- if (camera_flash != INVALID_GPIO) {\r
- ret = gpio_request(camera_flash, "camera flash");\r
- if (ret) {\r
- for (j=0; j<i; j++) {\r
- if (camera_flash == plat_data->gpio_res[j].gpio_flash) { \r
- break;\r
- }\r
- }\r
- if (i==j) {\r
- printk(KERN_ERR"rk_cam_io: %s..%s..flash pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_flash);\r
- goto sensor_io_init_erro;\r
+ 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));\r
+\r
+ }\r
+\r
+ if (camera_flash != INVALID_GPIO) {\r
+ ret = gpio_request(camera_flash, "camera flash");\r
+ if (ret) {\r
+ io_requested_in_camera = false;\r
+ for (i=0; i<RK_CAM_NUM; i++) {\r
+ io_res = &rk_camera_platform_data.gpio_res[i];\r
+ if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
+ if (io_res->gpio_powerdown == camera_powerdown)\r
+ io_requested_in_camera = true; \r
}\r
}\r
\r
- if (rk_camera_platform_data.iomux(camera_flash) < 0) {\r
- 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); \r
+ if (io_requested_in_camera==false) {\r
+ i=0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ io_res = &new_camera[i].io;\r
+ if (io_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
+ if (io_res->gpio_powerdown == camera_powerdown)\r
+ io_requested_in_camera = true; \r
+ }\r
+ i++;\r
+ }\r
}\r
\r
- plat_data->gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK;\r
- gpio_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); /* falsh off */\r
- gpio_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+ ret = 0; //ddl@rock-chips.com : flash is only a function, sensor is also run;\r
+ if (io_requested_in_camera==false) {\r
+ eprintk("%s flash pin(%d) init failed\n",gpio_res->dev_name,camera_flash);\r
+ goto _rk_sensor_io_init_end_;\r
+ }\r
+ }\r
+\r
+ if (rk_camera_platform_data.iomux(camera_flash) < 0) {\r
+ printk("%s flash pin(%d) iomux init failed\n",gpio_res->dev_name,camera_flash); \r
+ }\r
+ \r
+ gpio_res->gpio_init |= RK29_CAM_FLASHACTIVE_MASK;\r
+ gpio_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); /* falsh off */\r
+ gpio_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+\r
+ 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));\r
+\r
+ } \r
+_rk_sensor_io_init_end_:\r
+ return ret;\r
+\r
+}\r
+\r
+static int _rk_sensor_io_deinit_(struct rk29camera_gpio_res *gpio_res)\r
+{\r
+ unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
+ unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;\r
+ \r
+ camera_reset = gpio_res->gpio_reset;\r
+ camera_power = gpio_res->gpio_power;\r
+ camera_powerdown = gpio_res->gpio_powerdown;\r
+ camera_flash = gpio_res->gpio_flash;\r
+\r
+ if (gpio_res->gpio_init & RK29_CAM_POWERACTIVE_MASK) {\r
+ if (camera_power != INVALID_GPIO) {\r
+ gpio_direction_input(camera_power);\r
+ gpio_free(camera_power);\r
+ }\r
+ }\r
\r
- dprintk("%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+ if (gpio_res->gpio_init & RK29_CAM_RESETACTIVE_MASK) {\r
+ if (camera_reset != INVALID_GPIO) {\r
+ gpio_direction_input(camera_reset);\r
+ gpio_free(camera_reset);\r
+ }\r
+ }\r
+\r
+ if (gpio_res->gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
+ if (camera_powerdown != INVALID_GPIO) {\r
+ gpio_direction_input(camera_powerdown);\r
+ gpio_free(camera_powerdown);\r
+ }\r
+ }\r
+\r
+ if (gpio_res->gpio_init & RK29_CAM_FLASHACTIVE_MASK) {\r
+ if (camera_flash != INVALID_GPIO) {\r
+ gpio_direction_input(camera_flash);\r
+ gpio_free(camera_flash);\r
+ }\r
+ }\r
+ gpio_res->gpio_init = 0;\r
+ \r
+ return 0;\r
+}\r
\r
- } \r
+static int rk_sensor_io_init(void)\r
+{\r
+ int i,j;\r
+ static bool is_init = false;\r
+ struct rk29camera_platform_data* plat_data = &rk_camera_platform_data;\r
\r
+ if(is_init) { \r
+ return 0;\r
+ } else {\r
+ is_init = true;\r
+ }\r
+ \r
+ if (sensor_ioctl_cb.sensor_power_cb == NULL)\r
+ sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb;\r
+ if (sensor_ioctl_cb.sensor_reset_cb == NULL)\r
+ sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb;\r
+ if (sensor_ioctl_cb.sensor_powerdown_cb == NULL)\r
+ sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb;\r
+ if (sensor_ioctl_cb.sensor_flash_cb == NULL)\r
+ sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb;\r
+ \r
+ for(i = 0;i < RK_CAM_NUM; i++) {\r
+ if (plat_data->gpio_res[i].dev_name == NULL)\r
+ continue;\r
+ \r
+ if (_rk_sensor_io_init_(&plat_data->gpio_res[i])<0)\r
+ goto sensor_io_init_erro;\r
\r
for (j=0; j<10; j++) {\r
memset(&plat_data->info[i].fival[j],0x00,sizeof(struct v4l2_frmivalenum));\r
\r
continue;\r
sensor_io_init_erro:\r
- rk_sensor_io_deinit(i);\r
+ _rk_sensor_io_deinit_(&plat_data->gpio_res[i]);\r
}\r
+ \r
+ i = 0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ if (_rk_sensor_io_init_(&new_camera[i].io)<0)\r
+ _rk_sensor_io_deinit_(&new_camera[i].io);\r
+\r
+ i++;\r
+ }\r
return 0;\r
}\r
\r
static int rk_sensor_io_deinit(int sensor)\r
{\r
- unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
- unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;\r
+ int i;\r
struct rk29camera_platform_data* plat_data = &rk_camera_platform_data;\r
\r
- camera_reset = plat_data->gpio_res[sensor].gpio_reset;\r
- camera_power = plat_data->gpio_res[sensor].gpio_power;\r
- camera_powerdown = plat_data->gpio_res[sensor].gpio_powerdown;\r
- camera_flash = plat_data->gpio_res[sensor].gpio_flash;\r
-\r
- if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) {\r
- if (camera_power != INVALID_GPIO) {\r
- gpio_direction_input(camera_power);\r
- gpio_free(camera_power);\r
- }\r
- }\r
-\r
- if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) {\r
- if (camera_reset != INVALID_GPIO) {\r
- gpio_direction_input(camera_reset);\r
- gpio_free(camera_reset);\r
- }\r
- }\r
+ for(i = 0;i < RK_CAM_NUM; i++) {\r
+ if (plat_data->gpio_res[i].dev_name == NULL)\r
+ continue;\r
+ \r
+ _rk_sensor_io_deinit_(&plat_data->gpio_res[i]);\r
+ }\r
\r
- if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {\r
- if (camera_powerdown != INVALID_GPIO) {\r
- gpio_direction_input(camera_powerdown);\r
- gpio_free(camera_powerdown);\r
- }\r
- }\r
+ i = 0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ _rk_sensor_io_deinit_(&new_camera[i].io);\r
\r
- if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) {\r
- if (camera_flash != INVALID_GPIO) {\r
- gpio_direction_input(camera_flash);\r
- gpio_free(camera_flash);\r
- }\r
- }\r
- plat_data->gpio_res[sensor].gpio_init = 0;\r
- \r
+ i++;\r
+ }\r
+ \r
return 0;\r
}\r
static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on)\r
{\r
- struct rk29camera_gpio_res *res = NULL; \r
- int ret = RK29_CAM_IO_SUCCESS,i = 0;\r
-\r
+ struct rk29camera_gpio_res *res = NULL;\r
+ struct rkcamera_platform_data *new_cam_dev = NULL;\r
struct rk29camera_platform_data* plat_data = &rk_camera_platform_data;\r
- //for test reg\r
+ int ret = RK29_CAM_IO_SUCCESS,i = 0;\r
+ struct soc_camera_link *dev_icl = NULL;\r
+\r
+ //for test reg\r
for(i = 0;i < RK_CAM_NUM;i++){\r
if(plat_data->gpio_res[i].dev_name && (strcmp(plat_data->gpio_res[i].dev_name, dev_name(dev)) == 0)) {\r
res = (struct rk29camera_gpio_res *)&plat_data->gpio_res[i];\r
+ dev_icl = &plat_data->register_dev[i].link_info;\r
break;\r
} \r
- } \r
+ }\r
+\r
+ if (res == NULL) {\r
+ i = 0;\r
+ while (strstr(new_camera[i].dev_name,"end")==NULL) {\r
+ if (strcmp(new_camera[i].dev_name, dev_name(dev)) == 0) {\r
+ res = (struct rk29camera_gpio_res *)&new_camera[i].io; \r
+ new_cam_dev = &new_camera[i];\r
+ dev_icl = &new_camera[i].dev.link_info;\r
+ break;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
\r
if (res == NULL) {\r
- printk(KERN_ERR "rk_cam_io: %s is not regisiterd in rk29_camera_platform_data!!\n",dev_name(dev));\r
+ eprintk("%s is not regisiterd in rk29_camera_platform_data!!\n",dev_name(dev));\r
ret = RK29_CAM_EIO_INVALID;\r
goto rk_sensor_ioctrl_end;\r
}\r
case Cam_Power:\r
{\r
if (sensor_ioctl_cb.sensor_power_cb) {\r
- ret = sensor_ioctl_cb.sensor_power_cb(res, on);\r
+ ret = sensor_ioctl_cb.sensor_power_cb(res, on); \r
} else {\r
- printk(KERN_ERR "sensor_ioctl_cb.sensor_power_cb is NULL");\r
+ eprintk("sensor_ioctl_cb.sensor_power_cb is NULL");\r
WARN_ON(1);\r
}\r
break;\r
{\r
if (sensor_ioctl_cb.sensor_reset_cb) {\r
ret = sensor_ioctl_cb.sensor_reset_cb(res, on);\r
+\r
+ ret = (ret != RK29_CAM_EIO_INVALID)?ret:0;\r
} else {\r
- printk(KERN_ERR "sensor_ioctl_cb.sensor_reset_cb is NULL");\r
+ eprintk( "sensor_ioctl_cb.sensor_reset_cb is NULL");\r
WARN_ON(1);\r
}\r
break;\r
if (sensor_ioctl_cb.sensor_powerdown_cb) {\r
ret = sensor_ioctl_cb.sensor_powerdown_cb(res, on);\r
} else {\r
- printk(KERN_ERR "sensor_ioctl_cb.sensor_powerdown_cb is NULL");\r
+ eprintk( "sensor_ioctl_cb.sensor_powerdown_cb is NULL");\r
WARN_ON(1);\r
}\r
break;\r
if (sensor_ioctl_cb.sensor_flash_cb) {\r
ret = sensor_ioctl_cb.sensor_flash_cb(res, on);\r
} else {\r
- printk(KERN_ERR "sensor_ioctl_cb.sensor_flash_cb is NULL!");\r
+ eprintk( "sensor_ioctl_cb.sensor_flash_cb is NULL!");\r
WARN_ON(1);\r
}\r
break;\r
}\r
+\r
+ case Cam_Mclk:\r
+ {\r
+ if (plat_data->sensor_mclk && dev_icl) {\r
+ plat_data->sensor_mclk(dev_icl->bus_id,(on!=0)?1:0,on);\r
+ } else { \r
+ eprintk( "%s(%d): sensor_mclk(%p) or dev_icl(%p) is NULL\n",\r
+ __FUNCTION__,__LINE__,plat_data->sensor_mclk,dev_icl);\r
+ }\r
+ break;\r
+ }\r
+ \r
default:\r
{\r
- printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);\r
+ eprintk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);\r
break;\r
}\r
}\r
rk_sensor_ioctrl_end:\r
return ret;\r
}\r
+\r
+static int rk_sensor_pwrseq(struct device *dev,int powerup_sequence, int on, int mclk_rate)\r
+{\r
+ int ret =0;\r
+ int i,powerup_type;\r
+ \r
+ for (i=0; i<8; i++) {\r
+\r
+ if (on == 1)\r
+ powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence,i);\r
+ else\r
+ powerup_type = SENSOR_PWRSEQ_GET(powerup_sequence,(7-i));\r
+ \r
+ switch (powerup_type)\r
+ {\r
+ case SENSOR_PWRSEQ_AVDD:\r
+ case SENSOR_PWRSEQ_DOVDD:\r
+ case SENSOR_PWRSEQ_DVDD:\r
+ case SENSOR_PWRSEQ_PWR:\r
+ { \r
+ ret = rk_sensor_ioctrl(dev,Cam_Power, on);\r
+ if (ret<0) {\r
+ eprintk("SENSOR_PWRSEQ_PWR failed\n");\r
+ } else { \r
+ msleep(10);\r
+ dprintk("SensorPwrSeq-power: %d\n",on);\r
+ }\r
+ break;\r
+ }\r
+\r
+ case SENSOR_PWRSEQ_HWRST:\r
+ {\r
+ ret = rk_sensor_ioctrl(dev,Cam_Reset, 1);\r
+ msleep(2);\r
+ ret |= rk_sensor_ioctrl(dev,Cam_Reset, 0); \r
+ if (ret<0) {\r
+ eprintk("SENSOR_PWRSEQ_HWRST failed\n");\r
+ } else {\r
+ dprintk("SensorPwrSeq-reset: %d\n",on);\r
+ }\r
+ break;\r
+ }\r
+\r
+ case SENSOR_PWRSEQ_PWRDN:\r
+ { \r
+ ret = rk_sensor_ioctrl(dev,Cam_PowerDown, !on);\r
+ if (ret<0) {\r
+ eprintk("SENSOR_PWRSEQ_PWRDN failed\n");\r
+ } else {\r
+ dprintk("SensorPwrSeq-power down: %d \n",!on);\r
+ }\r
+ break;\r
+ }\r
+\r
+ case SENSOR_PWRSEQ_CLKIN:\r
+ {\r
+ ret = rk_sensor_ioctrl(dev,Cam_Mclk, (on?mclk_rate:on));\r
+ if (ret<0) {\r
+ eprintk("SENSOR_PWRSEQ_CLKIN failed\n");\r
+ } else {\r
+ dprintk("SensorPwrSeq-clock: %d\n",on);\r
+ }\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ } \r
+\r
+ return ret;\r
+}\r
+\r
static int rk_sensor_power(struct device *dev, int on)\r
{\r
- if (!on) /* ddl@rock-chips.com : Ensure sensor enter standby or power off */\r
- rk_sensor_powerdown(dev,1);\r
- rk_sensor_ioctrl(dev,Cam_Power,on);\r
- return 0;\r
+ int i, powerup_sequence,mclk_rate;\r
+ \r
+ struct rk29camera_platform_data* plat_data = &rk_camera_platform_data;\r
+ struct rk29camera_gpio_res *dev_io = NULL;\r
+ struct rkcamera_platform_data *new_camera=NULL, *new_device=NULL;\r
+ bool real_pwroff = true;\r
+ int ret = 0;\r
+ \r
+ //ddl@rock-chips.com: other sensor must switch into standby before turn on power;\r
+ for(i = 0;i < RK_CAM_NUM; i++) {\r
+ if (plat_data->gpio_res[i].dev_name == NULL)\r
+ continue;\r
+\r
+ if (plat_data->gpio_res[i].gpio_powerdown != INVALID_GPIO) {\r
+ gpio_direction_output(plat_data->gpio_res[i].gpio_powerdown,\r
+ ((plat_data->gpio_res[i].gpio_flag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); \r
+ }\r
+ \r
+ if (strcmp(plat_data->gpio_res[i].dev_name,dev_name(dev))) {\r
+ if (sensor_ioctl_cb.sensor_powerdown_cb && on)\r
+ sensor_ioctl_cb.sensor_powerdown_cb(&plat_data->gpio_res[i],1);\r
+ } else { \r
+ dev_io = &plat_data->gpio_res[i];\r
+ real_pwroff = true;\r
+ }\r
+ }\r
+\r
+ new_camera = plat_data->register_dev_new;\r
+ while (strstr(new_camera->dev_name,"end")==NULL) {\r
+\r
+ if (new_camera->io.gpio_powerdown != INVALID_GPIO) {\r
+ gpio_direction_output(new_camera->io.gpio_powerdown,\r
+ ((new_camera->io.gpio_flag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); \r
+ }\r
+ \r
+ if (strcmp(new_camera->dev_name,dev_name(dev))) {\r
+ if (sensor_ioctl_cb.sensor_powerdown_cb && on)\r
+ sensor_ioctl_cb.sensor_powerdown_cb(&new_camera->io,1);\r
+ } else {\r
+ new_device = new_camera;\r
+ dev_io = &new_camera->io;\r
+ \r
+ if (!Sensor_Support_DirectResume(new_camera->pwdn_info))\r
+ real_pwroff = true;\r
+ else\r
+ real_pwroff = false;\r
+ }\r
+ new_camera++;\r
+ }\r
+\r
+ if (new_device != NULL) {\r
+ powerup_sequence = new_device->powerup_sequence;\r
+ if ((new_device->mclk_rate == 24) || (new_device->mclk_rate == 48))\r
+ mclk_rate = new_device->mclk_rate*1000000;\r
+ else \r
+ mclk_rate = 24000000;\r
+ } else {\r
+ powerup_sequence = sensor_PWRSEQ_DEFAULT;\r
+ mclk_rate = 24000000;\r
+ }\r
+ \r
+ if (on) {\r
+ rk_sensor_pwrseq(dev, powerup_sequence, on,mclk_rate); \r
+ } else {\r
+ if (real_pwroff) {\r
+ rk_sensor_pwrseq(dev, powerup_sequence, on,mclk_rate);\r
+ \r
+ /*ddl@rock-chips.com: all power down switch to Hi-Z after power off*/\r
+ for(i = 0;i < RK_CAM_NUM; i++) {\r
+ if (plat_data->gpio_res[i].dev_name == NULL)\r
+ continue;\r
+ if (plat_data->gpio_res[i].gpio_powerdown != INVALID_GPIO) {\r
+ gpio_direction_input(plat_data->gpio_res[i].gpio_powerdown); \r
+ }\r
+ }\r
+ \r
+ new_camera = plat_data->register_dev_new;\r
+ while (strstr(new_camera->dev_name,"end")==NULL) {\r
+ if (new_camera->io.gpio_powerdown != INVALID_GPIO) {\r
+ gpio_direction_input(new_camera->io.gpio_powerdown); \r
+ }\r
+ new_camera->pwdn_info |= 0x01;\r
+ new_camera++;\r
+ }\r
+ } else { \r
+ rk_sensor_ioctrl(dev,Cam_PowerDown, !on);\r
+\r
+ rk_sensor_ioctrl(dev,Cam_Mclk, 0);\r
+ }\r
+\r
+ msleep(500);\r
+ }\r
+ return ret;\r
}\r
-#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) \\r
- || (CONFIG_SENSOR_RESET_PIN_01 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_02 != INVALID_GPIO) \\r
- || (CONFIG_SENSOR_RESET_PIN_11 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_12 != INVALID_GPIO)\r
static int rk_sensor_reset(struct device *dev)\r
{\r
+#if 0\r
rk_sensor_ioctrl(dev,Cam_Reset,1);\r
msleep(2);\r
rk_sensor_ioctrl(dev,Cam_Reset,0);\r
+#else\r
+ /*\r
+ *ddl@rock-chips.com : the rest function invalidate, because this operate is put together in rk_sensor_power;\r
+ */\r
+#endif\r
return 0;\r
}\r
-#endif\r
static int rk_sensor_powerdown(struct device *dev, int on)\r
{\r
return rk_sensor_ioctrl(dev,Cam_PowerDown,on);\r
if(id < 0 || id >= 6)\r
return -EINVAL;\r
for(i = 0; i < 6; i++){\r
- if(i == id){\r
- printk("%s: id = %d, i2c = %d, gpio = %d\n", __func__, id, i2c, gpio);\r
- }\r
- if(rk_camera_platform_data.gpio_res[i].dev_name &&\r
- strcmp(rk_camera_platform_data.gpio_res[i].dev_name, dev_name[id]) == 0)\r
- rk_camera_platform_data.gpio_res[i].gpio_powerdown = gpio;\r
- if(rk_camera_platform_data.register_dev[i].link_info.module_name &&\r
- strcmp(rk_camera_platform_data.register_dev[i].link_info.module_name, module_name[id]) == 0)\r
- rk_camera_platform_data.register_dev[i].link_info.i2c_adapter_id = i2c;\r
+ if(i == id){\r
+ printk("%s: id = %d, i2c = %d, gpio = %d\n", __func__, id, i2c, gpio);\r
+ }\r
+ if(rk_camera_platform_data.gpio_res[i].dev_name &&\r
+ strcmp(rk_camera_platform_data.gpio_res[i].dev_name, dev_name[id]) == 0)\r
+ rk_camera_platform_data.gpio_res[i].gpio_powerdown = gpio;\r
+ if(rk_camera_platform_data.register_dev[i].link_info.module_name &&\r
+ strcmp(rk_camera_platform_data.register_dev[i].link_info.module_name, module_name[id]) == 0)\r
+ rk_camera_platform_data.register_dev[i].link_info.i2c_adapter_id = i2c;\r
}\r
\r
return 0;\r
}\r
#endif\r
\r
+int rk_sensor_register(void)\r
+{\r
+ int i;\r
+\r
+ i = 0;\r
+ while (strstr(new_camera[i].dev.device_info.dev.init_name,"end")==NULL) {\r
+\r
+ if (new_camera[i].dev.i2c_cam_info.addr == INVALID_VALUE) {\r
+ WARN(1, \r
+ KERN_ERR "%s(%d): new_camera[%d] i2c addr is invalidate!",\r
+ __FUNCTION__,__LINE__,i);\r
+ continue;\r
+ }\r
+ \r
+ sprintf(new_camera[i].dev_name,"%s_%d",new_camera[i].dev.device_info.dev.init_name,i+3);\r
+ new_camera[i].dev.device_info.dev.init_name =(const char*)&new_camera[i].dev_name[0];\r
+ new_camera[i].io.dev_name =(const char*)&new_camera[i].dev_name[0];\r
+ \r
+ if (new_camera[i].orientation == INVALID_VALUE) {\r
+ if (strstr(new_camera[i].dev_name,"back")) {\r
+ new_camera[i].orientation = 90;\r
+ } else {\r
+ new_camera[i].orientation = 270;\r
+ }\r
+ }\r
+\r
+ new_camera[i].dev.link_info.power = rk_sensor_power;\r
+ new_camera[i].dev.link_info.powerdown = rk_sensor_powerdown; \r
+\r
+ new_camera[i].dev.link_info.board_info =&new_camera[i].dev.i2c_cam_info;\r
+ new_camera[i].dev.device_info.id = i+6;\r
+ new_camera[i].dev.device_info.dev.platform_data = &new_camera[i].dev.link_info;\r
+\r
+ if (new_camera[i].flash == true) {\r
+ if (CONFIG_SENSOR_FLASH_IOCTL_USR == 0) {\r
+ eprintk("new_camera[%d] have been configed as attach flash, but CONFIG_SENSOR_FLASH_IOCTL_USR isn't turn on!",i);\r
+\r
+ new_camera[i].flash = false; \r
+ }\r
+ }\r
+\r
+ new_camera[i].dev.link_info.priv_usr = &rk_camera_platform_data;\r
+ platform_device_register(&new_camera[i].dev.device_info);\r
+ i++;\r
+ }\r
+ \r
+ sprintf(new_camera[i].dev_name,"%s",new_camera[i].dev.device_info.dev.init_name);\r
+\r
+ return 0;\r
+}\r
#endif\r
\r
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
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"
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"
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"
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
---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"
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"
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"
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"
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"
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
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
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
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"
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"
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"
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"
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"
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"
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
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
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
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
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/
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
-
+\r
+#include "generic_sensor.h"\r
+\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
- {
- 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);
- }
-
- }
-
-
- 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 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);;
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0307\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0307\r
+#define SENSOR_ID 0x99\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ //========= close output\r
+ {0x43 ,0x00}, \r
+ {0x44 ,0xa2}, \r
+ \r
+ //========= close some functions\r
+ // open them after configure their parmameters\r
+ {0x40 ,0x10}, \r
+ {0x41 ,0x00}, \r
+ {0x42 ,0x10}, \r
+ {0x47 ,0x00}, //mode1, \r
+ {0x48 ,0xc3}, //mode2, \r
+ {0x49 ,0x00}, //dither_mode \r
+ {0x4a ,0x00}, //clock_gating_en\r
+ {0x4b ,0x00}, //mode_reg3\r
+ {0x4E ,0x22},//0x23}, //sync mode yaowei\r
+ {0x4F ,0x01}, //AWB, AEC, every N frame \r
+ \r
+ //========= frame timing\r
+ {0x01 ,0x6a}, //HB\r
+ {0x02 ,0x70}, //VB\r
+ {0x1C ,0x00}, //Vs_st\r
+ {0x1D ,0x00}, //Vs_et\r
+ {0x10 ,0x00}, //high 4 bits of VB, HB\r
+ {0x11 ,0x05}, //row_tail, AD_pipe_number\r
+ \r
+ \r
+ \r
+ \r
+ \r
+ //========= windowing\r
+ {0x05 ,0x00}, //row_start\r
+ {0x06 ,0x00},\r
+ {0x07 ,0x00}, //col start\r
+ {0x08 ,0x00}, \r
+ {0x09 ,0x01}, //win height\r
+ {0x0A ,0xE8},\r
+ {0x0B ,0x02}, //win width, pixel array only 640\r
+ {0x0C ,0x80},\r
+ \r
+ //========= analog\r
+ {0x0D ,0x22}, //rsh_width\r
+ \r
+ {0x0E ,0x02}, //CISCTL mode2, \r
+ \r
+ \r
+ {0x12 ,0x70}, //7 hrst, 6_4 darsg,\r
+ {0x13 ,0x00}, //7 CISCTL_restart, 0 apwd\r
+ {0x14 ,0x00}, //NA\r
+ {0x15 ,0xba}, //7_4 vref\r
+ {0x16 ,0x13}, //5to4 _coln_r, __1to0__da18\r
+ {0x17 ,0x52}, //opa_r, ref_r, sRef_r\r
+ //{0x18 ,0xc0}, //analog_mode, best case for left band.\r
+ \r
+ {0x1E ,0x0d}, //tsp_width \r
+ {0x1F ,0x32}, //sh_delay\r
+ \r
+ //========= offset\r
+ {0x47 ,0x00}, //7__test_image, __6__fixed_pga, __5__auto_DN, __4__CbCr_fix, \r
+ //__3to2__dark_sequence, __1__allow_pclk_vcync, __0__LSC_test_image\r
+ {0x19 ,0x06}, //pga_o \r
+ {0x1a ,0x06}, //pga_e \r
+ \r
+ {0x31 ,0x00}, //4 //pga_oFFset , high 8bits of 11bits\r
+ {0x3B ,0x00}, //global_oFFset, low 8bits of 11bits\r
+ \r
+ {0x59 ,0x0f}, //offset_mode \r
+ {0x58 ,0x88}, //DARK_VALUE_RATIO_G, DARK_VALUE_RATIO_RB\r
+ {0x57 ,0x08}, //DARK_CURRENT_RATE\r
+ {0x56 ,0x77}, //PGA_OFFSET_EVEN_RATIO, PGA_OFFSET_ODD_RATIO\r
+ \r
+ //========= blk\r
+ {0x35 ,0xd8}, //blk_mode\r
+ \r
+ {0x36 ,0x40}, \r
+ \r
+ {0x3C ,0x00}, \r
+ {0x3D ,0x00}, \r
+ {0x3E ,0x00}, \r
+ {0x3F ,0x00}, \r
+ \r
+ {0xb5 ,0x70}, \r
+ {0xb6 ,0x40}, \r
+ {0xb7 ,0x00}, \r
+ {0xb8 ,0x38}, \r
+ {0xb9 ,0xc3}, \r
+ {0xba ,0x0f}, \r
+ \r
+ {0x7e ,0x50},//0x45 ylz++ \r
+ {0x7f ,0x76}, //0x66\r
+ \r
+ {0x5c ,0x48}, //78\r
+ {0x5d ,0x58}, //88\r
+ \r
+ \r
+ //========= manual_gain \r
+ {0x61 ,0x80}, //manual_gain_g1 \r
+ {0x63 ,0x80}, //manual_gain_r\r
+ {0x65 ,0x98}, //manual_gai_b, 0xa0=1.25, 0x98=1.1875\r
+ {0x67 ,0x80}, //manual_gain_g2\r
+ {0x68 ,0x18}, //global_manual_gain 2.4bits\r
+ \r
+ //=========CC _R\r
+ {0x69 ,0x58}, //54\r
+ {0x6A ,0xf6}, //ff\r
+ {0x6B ,0xfb}, //fe\r
+ {0x6C ,0xf4}, //ff\r
+ {0x6D ,0x5a}, //5f\r
+ {0x6E ,0xe6}, //e1\r
+ \r
+ {0x6f ,0x00}, \r
+ \r
+ //=========lsc \r
+ {0x70 ,0x14}, \r
+ {0x71 ,0x1c}, \r
+ {0x72 ,0x20}, \r
+ \r
+ {0x73 ,0x10}, \r
+ {0x74 ,0x3c}, \r
+ {0x75 ,0x52}, \r
+ \r
+ //=========dn \r
+ {0x7d ,0x2f}, //dn_mode \r
+ {0x80 ,0x0c}, //when auto_dn, check 7e,7f\r
+ {0x81 ,0x0c},\r
+ {0x82 ,0x44},\r
+ \r
+ //dd \r
+ {0x83 ,0x18}, //DD_TH1 \r
+ {0x84 ,0x18}, //DD_TH2 \r
+ {0x85 ,0x04}, //DD_TH3 \r
+ {0x87 ,0x34}, //32 b DNDD_low_range X16, DNDD_low_range_C_weight_center \r
+ \r
+ \r
+ //=========intp-ee \r
+ {0x88 ,0x04}, \r
+ {0x89 ,0x01}, \r
+ {0x8a ,0x50},//60 \r
+ {0x8b ,0x50},//60 \r
+ {0x8c ,0x07}, \r
+ \r
+ {0x50 ,0x0c}, \r
+ {0x5f ,0x3c}, \r
+ \r
+ {0x8e ,0x02}, \r
+ {0x86 ,0x02}, \r
+ \r
+ {0x51 ,0x20}, \r
+ {0x52 ,0x08}, \r
+ {0x53 ,0x00}, \r
+ \r
+ \r
+ //========= YCP \r
+ //contrast_center \r
+ {0x77 ,0x80}, //contrast_center \r
+ {0x78 ,0x00}, //fixed_Cb \r
+ {0x79 ,0x00}, //fixed_Cr \r
+ {0x7a ,0x00}, //luma_offset \r
+ {0x7b ,0x40}, //hue_cos \r
+ {0x7c ,0x00}, //hue_sin \r
+ \r
+ //saturation \r
+ {0xa0 ,0x40}, //global_saturation\r
+ {0xa1 ,0x42}, //luma_contrast \r
+ {0xa2 ,0x40}, //saturation_Cb //ylz 34 \r
+ {0xa3 ,0x34}, //saturation_Cr\r
+ \r
+ {0xa4 ,0xc8}, \r
+ {0xa5 ,0x02}, \r
+ {0xa6 ,0x28}, \r
+ {0xa7 ,0x02}, \r
+ \r
+ //skin \r
+ {0xa8 ,0xee}, \r
+ {0xa9 ,0x12}, \r
+ {0xaa ,0x01}, \r
+ {0xab ,0x20}, \r
+ {0xac ,0xf0}, \r
+ {0xad ,0x10}, \r
+ \r
+ //========= ABS\r
+ {0xae ,0x18}, \r
+ {0xaf ,0x74}, \r
+ {0xb0 ,0xe0}, \r
+ {0xb1 ,0x20}, \r
+ {0xb2 ,0x6c}, \r
+ {0xb3 ,0x40}, \r
+ {0xb4 ,0x04}, \r
+ \r
+ //========= AWB \r
+ {0xbb ,0x42}, \r
+ {0xbc ,0x60},\r
+ {0xbd ,0x50},\r
+ {0xbe ,0x50},\r
+ \r
+ {0xbf ,0x0c}, \r
+ {0xc0 ,0x06}, \r
+ {0xc1 ,0x60}, \r
+ {0xc2 ,0xf1}, //f1\r
+ {0xc3 ,0x40},\r
+ {0xc4 ,0x1c}, //18//20\r
+ {0xc5 ,0x56}, //33\r
+ {0xc6 ,0x1d}, \r
+ \r
+ {0xca ,0x70}, \r
+ {0xcb ,0x70}, \r
+ {0xcc ,0x78},\r
+ \r
+ {0xcd ,0x80}, //R_ratio \r
+ {0xce ,0x80}, //G_ratio , cold_white white \r
+ {0xcf ,0x80}, //B_ratio \r
+ \r
+ //========= aecT \r
+ {0x20 ,0x06},//0x02 \r
+ {0x21 ,0xc0}, \r
+ {0x22 ,0x40}, \r
+ {0x23 ,0x88}, \r
+ {0x24 ,0x96}, \r
+ {0x25 ,0x30}, \r
+ {0x26 ,0xd0}, \r
+ {0x27 ,0x00}, \r
+ \r
+ {0x28 ,0x02}, //AEC_exp_level_1bit11to8 \r
+ {0x29 ,0x58}, //AEC_exp_level_1bit7to0 \r
+ {0x2a ,0x03}, //AEC_exp_level_2bit11to8 \r
+ {0x2b ,0x84}, //AEC_exp_level_2bit7to0 \r
+ {0x2c ,0x09}, //AEC_exp_level_3bit11to8 659 - 8FPS, 8ca - 6FPS // \r
+ {0x2d ,0x60}, //AEC_exp_level_3bit7to0 \r
+ {0x2e ,0x0a}, //AEC_exp_level_4bit11to8 4FPS \r
+ {0x2f ,0x8c}, //AEC_exp_level_4bit7to0 \r
+ \r
+ {0x30 ,0x20}, \r
+ {0x31 ,0x00}, \r
+ {0x32 ,0x1c}, \r
+ {0x33 ,0x90}, \r
+ {0x34 ,0x10}, \r
+ \r
+ {0xd0 ,0x34}, \r
+ \r
+ {0xd1 ,0x40}, //AEC_target_Y \r
+ {0xd2 ,0x61},//0xf2 \r
+ {0xd4 ,0x96}, \r
+ {0xd5 ,0x01}, // william 0318\r
+ {0xd6 ,0x96}, //antiflicker_step \r
+ {0xd7 ,0x03}, //AEC_exp_time_min ,william 20090312 \r
+ {0xd8 ,0x02}, \r
+ \r
+ {0xdd ,0x12},//0x12 \r
+ \r
+ //========= measure window \r
+ {0xe0 ,0x03}, \r
+ {0xe1 ,0x02}, \r
+ {0xe2 ,0x27}, \r
+ {0xe3 ,0x1e}, \r
+ {0xe8 ,0x3b}, \r
+ {0xe9 ,0x6e}, \r
+ {0xea ,0x2c}, \r
+ {0xeb ,0x50}, \r
+ {0xec ,0x73}, \r
+ \r
+ //========= close_frame \r
+ {0xed ,0x00}, //close_frame_num1 ,can be use to reduce FPS \r
+ {0xee ,0x00}, //close_frame_num2 \r
+ {0xef ,0x00}, //close_frame_num\r
+ \r
+ // page1\r
+ {0xf0 ,0x01}, //select page1 \r
+ \r
+ {0x00 ,0x20}, \r
+ {0x01 ,0x20}, \r
+ {0x02 ,0x20}, \r
+ {0x03 ,0x20}, \r
+ {0x04 ,0x78}, \r
+ {0x05 ,0x78}, \r
+ {0x06 ,0x78}, \r
+ {0x07 ,0x78}, \r
+ \r
+ \r
+ \r
+ {0x10 ,0x04}, \r
+ {0x11 ,0x04}, \r
+ {0x12 ,0x04}, \r
+ {0x13 ,0x04}, \r
+ {0x14 ,0x01}, \r
+ {0x15 ,0x01}, \r
+ {0x16 ,0x01}, \r
+ {0x17 ,0x01}, \r
+ \r
+ \r
+ {0x20 ,0x00}, \r
+ {0x21 ,0x00}, \r
+ {0x22 ,0x00}, \r
+ {0x23 ,0x00}, \r
+ {0x24 ,0x00}, \r
+ {0x25 ,0x00}, \r
+ {0x26 ,0x00}, \r
+ {0x27 ,0x00}, \r
+ \r
+ {0x40 ,0x11}, \r
+ \r
+ //=============================lscP \r
+ {0x45 ,0x06}, \r
+ {0x46 ,0x06}, \r
+ {0x47 ,0x05}, \r
+ \r
+ {0x48 ,0x04}, \r
+ {0x49 ,0x03}, \r
+ {0x4a ,0x03}, \r
+ \r
+ \r
+ {0x62 ,0xd8}, \r
+ {0x63 ,0x24}, \r
+ {0x64 ,0x24},\r
+ {0x65 ,0x24}, \r
+ {0x66 ,0xd8}, \r
+ {0x67 ,0x24},\r
+ \r
+ {0x5a ,0x00}, \r
+ {0x5b ,0x00}, \r
+ {0x5c ,0x00}, \r
+ {0x5d ,0x00}, \r
+ {0x5e ,0x00}, \r
+ {0x5f ,0x00}, \r
+ \r
+ \r
+ //============================= ccP \r
+ \r
+ {0x69 ,0x03}, //cc_mode\r
+ \r
+ //CC_G\r
+ {0x70 ,0x5d}, \r
+ {0x71 ,0xed}, \r
+ {0x72 ,0xff}, \r
+ {0x73 ,0xe5}, \r
+ {0x74 ,0x5f}, \r
+ {0x75 ,0xe6}, \r
+ \r
+ //CC_B\r
+ {0x76 ,0x41}, \r
+ {0x77 ,0xef}, \r
+ {0x78 ,0xff}, \r
+ {0x79 ,0xff}, \r
+ {0x7a ,0x5f}, \r
+ {0x7b ,0xfa}, \r
+ \r
+ \r
+ //============================= AGP\r
+ \r
+ {0x7e ,0x00}, \r
+ {0x7f ,0x20}, //x040\r
+ {0x80 ,0x48}, \r
+ {0x81 ,0x06}, \r
+ {0x82 ,0x08}, \r
+ \r
+ {0x83 ,0x23}, \r
+ {0x84 ,0x38}, \r
+ {0x85 ,0x4F}, \r
+ {0x86 ,0x61}, \r
+ {0x87 ,0x72}, \r
+ {0x88 ,0x80}, \r
+ {0x89 ,0x8D}, \r
+ {0x8a ,0xA2}, \r
+ {0x8b ,0xB2}, \r
+ {0x8c ,0xC0}, \r
+ {0x8d ,0xCA}, \r
+ {0x8e ,0xD3}, \r
+ {0x8f ,0xDB}, \r
+ {0x90 ,0xE2}, \r
+ {0x91 ,0xED}, \r
+ {0x92 ,0xF6}, \r
+ {0x93 ,0xFD}, \r
+ \r
+ //about gamma1 is hex r oct\r
+ {0x94 ,0x04}, \r
+ {0x95 ,0x0E}, \r
+ {0x96 ,0x1B}, \r
+ {0x97 ,0x28}, \r
+ {0x98 ,0x35}, \r
+ {0x99 ,0x41}, \r
+ {0x9a ,0x4E}, \r
+ {0x9b ,0x67}, \r
+ {0x9c ,0x7E}, \r
+ {0x9d ,0x94}, \r
+ {0x9e ,0xA7}, \r
+ {0x9f ,0xBA}, \r
+ {0xa0 ,0xC8}, \r
+ {0xa1 ,0xD4}, \r
+ {0xa2 ,0xE7}, \r
+ {0xa3 ,0xF4}, \r
+ {0xa4 ,0xFA}, \r
+ \r
+ //========= open functions \r
+ {0xf0 ,0x00}, //set back to page0 \r
+ {0x40 ,0x7e}, \r
+ {0x41 ,0x2F},\r
+ \r
+ ///// Çë×¢Ò⣬µ÷ÕûGC0307µÄ¾µÏñºÍ·×ª£¬ÐèҪͬʱÐÞ¸ÄÈý¸ö¼Ä´æÆ÷£¬ÈçÏÂ:\r
+ \r
+ {0x0f, 0xb2},\r
+ {0x45, 0x27},\r
+ {0x47, 0x2c}, \r
+ ///banding setting \r
+ { 0x01 ,0xfa}, // 24M \r
+ { 0x02 ,0x70}, \r
+ { 0x10 ,0x01}, \r
+ { 0xd6 ,0x64}, \r
+ { 0x28 ,0x02}, \r
+ { 0x29 ,0x58}, \r
+ { 0x2a ,0x02}, \r
+ { 0x2b ,0x58}, \r
+ { 0x2c ,0x02}, \r
+ { 0x2d ,0x58}, \r
+ { 0x2e ,0x06}, \r
+ { 0x2f ,0x40}, \r
+ \r
+ /************\r
+ {0x0f, 0x02},//82\r
+ {0x45, 0x24},\r
+ {0x47, 0x20}, \r
+ **************/\r
+ ///// ËÄÖÖ²»Í¬µÄ·×ªºÍ¾µÏñÉ趨£¬¿Í»§¿ÉÖ±½Ó¸´ÖÆ!!!!!!\r
+ \r
+ \r
+#if 0\r
+ // IMAGE_NORMAL:\r
+ {0x0f, 0xb2},\r
+ {0x45, 0x27},\r
+ {0x47, 0x2c}, \r
+ \r
+ // IMAGE_H_MIRROR:\r
+ {0x0f, 0xa2},\r
+ {0x45, 0x26},\r
+ {0x47, 0x28}, \r
+ \r
+ // IMAGE_V_MIRROR: \r
+ {0x0f, 0x92},\r
+ {0x45, 0x25},\r
+ {0x47, 0x24}, \r
+ \r
+ // IMAGE_HV_MIRROR: // 180\r
+ {0x0f, 0x82},\r
+ {0x45, 0x24},\r
+ {0x47, 0x20}, \r
+#endif\r
+ {0x43, 0x40},\r
+ {0x44, 0xe2}, \r
+\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ SensorEnd\r
+\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+#if 1\r
+ { 0x05 , 0x00},\r
+ { 0x06 , 0x00},\r
+ { 0x07 , 0x00},\r
+ { 0x08 , 0x00},//0x10 james 20100715\r
+ { 0x09 , 0x01},\r
+ { 0x0a , 0xe8},\r
+ { 0x0b , 0x02},\r
+ { 0x0c , 0x88},//0x80 james 20100715\r
+ { 0x45 , 0x24}, // bit[7:2]=001001\r
+ { 0x48 , 0x84}, // bit[7]=1\r
+ { 0xe0 , 0x03},\r
+ { 0xe1 , 0x02},\r
+ { 0xe2 , 0x27},\r
+ { 0xe3 , 0x1e},\r
+ { 0xe8 , 0x3b},\r
+ { 0xe9 , 0x6e},\r
+ { 0xea , 0x2c},\r
+ { 0xeb , 0x50},\r
+ { 0xec , 0x73},\r
+#else\r
+ {0x17, 0x13},\r
+ {0x18, 0x01},\r
+ {0x32, 0xbf},\r
+ {0x19, 0x03},\r
+ {0x1a, 0x7b},\r
+ {0x03, 0x0a},\r
+ \r
+#endif\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x00,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0xc7,0x4c}, //for AWB can adjust back\r
+ {0xc8,0x40},\r
+ {0xc9,0x4a}, \r
+ {0x41,0x2f},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x41,0x2b}, // Enable AWB \r
+ {0xc7,0x5a}, //WB_manual_gain\r
+ {0xc8,0x42},\r
+ {0xc9,0x40},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x41,0x2b}, // Enable AWB \r
+ {0xc7,0x50},\r
+ {0xc8,0x45},\r
+ {0xc9,0x40},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x41,0x2b}, // Enable AWB \r
+ {0xc7,0x48},\r
+ {0xc8,0x40},\r
+ {0xc9,0x5c},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x41,0x2b}, // Enable AWB \r
+ {0xc7,0x40},\r
+ {0xc8,0x42},\r
+ {0xc9,0x50},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ {0x7a, 0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ {0x7a, 0xf0},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ {0x7a, 0x00},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0x7a, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0x7a, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0x7a, 0x30},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x41,0x2f}, // 1\r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x24},//20\r
+ {0x48,0xc3},\r
+ {0x8a,0x50},//60\r
+ {0x8b,0x50},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0x00},\r
+ {0x79,0x00},\r
+ {0x7b,0x40},\r
+ {0x7c,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x41,0x2f}, // danse \r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x3c},\r
+ {0x48,0xc3},\r
+ {0x8a,0x60},\r
+ {0x8b,0x60},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0x00},\r
+ {0x79,0x00},\r
+ {0x7b,0x40},\r
+ {0x7c,0x00}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x41,0x2f}, \r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x3c},\r
+ {0x48,0xc3},\r
+ {0x8a,0x60},\r
+ {0x8b,0x60},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0xc0},\r
+ {0x79,0x20},\r
+ {0x7b,0x40},\r
+ {0x7c,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x41,0x6f}, // 4\r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x20},\r
+ {0x48,0xc3},\r
+ {0x8a,0x60},\r
+ {0x8b,0x60},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0x00},\r
+ {0x79,0x00},\r
+ {0x7b,0x40},\r
+ {0x7c,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x41,0x2f}, // 5\r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x2c},\r
+ {0x48,0xc3},\r
+ {0x8a,0x60},\r
+ {0x8b,0x60},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0x70},\r
+ {0x79,0x00},\r
+ {0x7b,0x3f},\r
+ {0x7c,0xf5},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish 6\r
+ {0x41,0x2f}, \r
+ {0x40,0x7e},\r
+ {0x42,0x10},\r
+ {0x47,0x3c},\r
+ {0x48,0xc3},\r
+ {0x8a,0x60},\r
+ {0x8b,0x60},\r
+ {0x8c,0x07},\r
+ {0x50,0x0c},\r
+ {0x77,0x80},\r
+ {0xa1,0x40},\r
+ {0x7a,0x00},\r
+ {0x78,0xc0},\r
+ {0x79,0xc0},\r
+ {0x7b,0x40},\r
+ {0x7c,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Grayscale[]=\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ {0x00,0x00}\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ //-3\r
+ {0xd1, 0x38},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ //-2\r
+ {0xd1, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ //-1\r
+ {0xd1, 0x48},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ //default\r
+ {0xd1, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ // 1\r
+ {0xd1, 0x58},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ // 2\r
+ {0xd1, 0x60},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ // 3\r
+ {0xd1, 0x68},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ { 0xdd ,0x22}, //0x12\r
+ { 0x41 ,0x2f}, \r
+ { 0x21 ,0xc0},\r
+ { 0xd2 ,0x02},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ { 0xdd ,0x32},\r
+ { 0x41 ,0x0f},\r
+ { 0xb0 ,0x10},\r
+ { 0x21 ,0xf0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val1,val2,val3;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xf0, 0);\r
+ err = sensor_read(client,0x0f,&val1);\r
+ err = sensor_read(client,0x45,&val2);\r
+ err = sensor_read(client,0x47,&val3);\r
+ if(err ==0){\r
+ if((val1 == 0xb2) && (val2 == 0x27) && (val3 == 0x2c)){//normal\r
+ err = sensor_write(client, 0x0f, 0xa2);\r
+ err = sensor_write(client, 0x45, 0x26);\r
+ err = sensor_write(client, 0x47, 0x28);\r
+ }else if((val1 == 0xa2) && (val2 == 0x26) && (val3 == 0x28)){//h_mir\r
+ err = sensor_write(client, 0x0f, 0xb2);\r
+ err = sensor_write(client, 0x45, 0x27);\r
+ err = sensor_write(client, 0x47, 0x2c);\r
+ }else if((val1 == 0x92) && (val2 == 0x25) && (val3 == 0x24)){//v_flip\r
+ err = sensor_write(client, 0x0f, 0x82);\r
+ err = sensor_write(client, 0x45, 0x24);\r
+ err = sensor_write(client, 0x47, 0x20);\r
+ }else if((val1 == 0x82) && (val2 == 0x24) && (val3 == 0x20)){//h_v_mir\r
+ err = sensor_write(client, 0x0f, 0x92);\r
+ err = sensor_write(client, 0x45, 0x25);\r
+ err = sensor_write(client, 0x47, 0x24);\r
+ }\r
+\r
+ }\r
+ \r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val1,val2,val3;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ sensor_write(client, 0xf0, 0);\r
+ err = sensor_read(client,0x0f,&val1);\r
+ err = sensor_read(client,0x45,&val2);\r
+ err = sensor_read(client,0x47,&val3);\r
+ if(err ==0){\r
+ if((val1 == 0xb2) && (val2 == 0x27) && (val3 == 0x2c)){//normal\r
+ err = sensor_write(client, 0x0f, 0x92);\r
+ err = sensor_write(client, 0x45, 0x25);\r
+ err = sensor_write(client, 0x47, 0x24);\r
+ }else if((val1 == 0xa2) && (val2 == 0x26) && (val3 == 0x28)){//h_mir\r
+ err = sensor_write(client, 0x0f, 0x82);\r
+ err = sensor_write(client, 0x45, 0x24);\r
+ err = sensor_write(client, 0x47, 0x20);\r
+ }else if((val1 == 0x92) && (val2 == 0x25) && (val3 == 0x24)){//v_flip\r
+ err = sensor_write(client, 0x0f, 0xb2);\r
+ err = sensor_write(client, 0x45, 0x27);\r
+ err = sensor_write(client, 0x47, 0x2c);\r
+ }else if((val1 == 0x82) && (val2 == 0x24) && (val3 == 0x20)){//h_v_mir\r
+ err = sensor_write(client, 0x0f, 0xa2);\r
+ err = sensor_write(client, 0x45, 0x26);\r
+ err = sensor_write(client, 0x47, 0x28);\r
+ }\r
+ \r
+ }\r
+ \r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
+ {
+ 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);
+ }
+
+ }
+
+
+ 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 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);;
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
-
+\r
+#include "generic_sensor.h"\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
- {
- 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);
- }
-
- }
-
-
- 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;
- 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0308\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0308\r
+#define SENSOR_ID 0x9b\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0xfe , 0x80}, \r
+ \r
+ {0xfe , 0x00}, // set page0\r
+ \r
+ {0xd2 , 0x10}, // close AEC\r
+ {0x22 , 0x55}, // close AWB\r
+ \r
+ {0x03 , 0x01}, \r
+ {0x04 , 0x2c}, \r
+ {0x5a , 0x56},\r
+ {0x5b , 0x40},\r
+ {0x5c , 0x4a}, \r
+ \r
+ {0x22 , 0x57}, // Open AWB\r
+ \r
+ {0x01 , 0xfa}, \r
+ {0x02 , 0x70}, \r
+ {0x0f , 0x01}, \r
+ \r
+ \r
+ {0xe2 , 0x00}, //anti-flicker step [11:8] \r
+ {0xe3 , 0x64}, //anti-flicker step [7:0] \r
+ \r
+ {0xe4 , 0x02}, //exp level 1 16.67fps \r
+ {0xe5 , 0x58}, \r
+ {0xe6 , 0x03}, //exp level 2 12.5fps \r
+ {0xe7 , 0x20}, \r
+ {0xe8 , 0x04}, //exp level 3 8.33fps \r
+ {0xe9 , 0xb0}, \r
+ {0xea , 0x09}, //exp level 4 4.00fps \r
+ {0xeb , 0xc4}, \r
+ \r
+ //{0xec , 0x20},\r
+ \r
+ {0x05 , 0x00}, \r
+ {0x06 , 0x00}, \r
+ {0x07 , 0x00}, \r
+ {0x08 , 0x00}, \r
+ {0x09 , 0x01}, \r
+ {0x0a , 0xe8}, \r
+ {0x0b , 0x02}, \r
+ {0x0c , 0x88}, \r
+ {0x0d , 0x02}, \r
+ {0x0e , 0x02}, \r
+ {0x10 , 0x22}, \r
+ {0x11 , 0xfd}, \r
+ {0x12 , 0x2a}, \r
+ {0x13 , 0x00}, \r
+ {0x14 , 0x10}, //0x10\r
+ //-------------H_V_Switch(4)---------------//\r
+ /* 1: // normal\r
+ {0x14 , 0x10}, \r
+ 2: // IMAGE_H_MIRROR\r
+ {0x14 , 0x11},\r
+ \r
+ 3: // IMAGE_V_MIRROR\r
+ {0x14 , 0x12},\r
+ \r
+ 4: // IMAGE_HV_MIRROR\r
+ {0x14 , 0x13},*/ \r
+ {0x15 , 0x0a}, \r
+ {0x16 , 0x05}, \r
+ {0x17 , 0x01}, \r
+ {0x18 , 0x44}, \r
+ {0x19 , 0x44}, \r
+ {0x1a , 0x1e}, \r
+ {0x1b , 0x00}, \r
+ {0x1c , 0xc1}, \r
+ {0x1d , 0x08}, \r
+ {0x1e , 0x60}, \r
+ {0x1f , 0x17}, \r
+ \r
+ \r
+ {0x20 , 0xff}, \r
+ {0x21 , 0xf8}, \r
+ {0x22 , 0x57}, \r
+ {0x24 , 0xa2}, \r
+ {0x25 , 0x0f}, \r
+ \r
+ //output sync_mode \r
+ {0x26 , 0x02}, //0x03 20101016 zhj \r
+ {0x2f , 0x01}, \r
+ {0x30 , 0xf7}, \r
+ {0x31 , 0x50},\r
+ {0x32 , 0x00},\r
+ {0x39 , 0x04},\r
+ {0x3a , 0x18},\r
+ {0x3b , 0x20}, \r
+ {0x3c , 0x00}, \r
+ {0x3d , 0x00}, \r
+ {0x3e , 0x00}, \r
+ {0x3f , 0x00}, \r
+ {0x50 , 0x10}, \r
+ {0x53 , 0x82}, \r
+ {0x54 , 0x80}, \r
+ {0x55 , 0x80}, \r
+ {0x56 , 0x82}, \r
+ {0x8b , 0x40}, \r
+ {0x8c , 0x40}, \r
+ {0x8d , 0x40}, \r
+ {0x8e , 0x2e}, \r
+ {0x8f , 0x2e}, \r
+ {0x90 , 0x2e}, \r
+ {0x91 , 0x3c}, \r
+ {0x92 , 0x50}, \r
+ {0x5d , 0x12}, \r
+ {0x5e , 0x1a}, \r
+ {0x5f , 0x24}, \r
+ {0x60 , 0x07}, \r
+ {0x61 , 0x15}, \r
+ {0x62 , 0x08}, \r
+ {0x64 , 0x03}, \r
+ {0x66 , 0xe8}, \r
+ {0x67 , 0x86}, \r
+ {0x68 , 0xa2}, \r
+ {0x69 , 0x18}, \r
+ {0x6a , 0x0f}, \r
+ {0x6b , 0x00}, \r
+ {0x6c , 0x5f}, \r
+ {0x6d , 0x8f}, \r
+ {0x6e , 0x55}, \r
+ {0x6f , 0x38}, \r
+ {0x70 , 0x15}, \r
+ {0x71 , 0x33}, \r
+ {0x72 , 0xdc}, \r
+ {0x73 , 0x80}, \r
+ {0x74 , 0x02}, \r
+ {0x75 , 0x3f}, \r
+ {0x76 , 0x02}, \r
+ {0x77 , 0x36}, \r
+ {0x78 , 0x88}, \r
+ {0x79 , 0x81}, \r
+ {0x7a , 0x81}, \r
+ {0x7b , 0x22}, \r
+ {0x7c , 0xff}, \r
+ {0x93 , 0x48}, \r
+ {0x94 , 0x00}, \r
+ {0x95 , 0x05}, \r
+ {0x96 , 0xe8}, \r
+ {0x97 , 0x40}, \r
+ {0x98 , 0xf0}, \r
+ {0xb1 , 0x38}, \r
+ {0xb2 , 0x38}, \r
+ {0xbd , 0x38}, \r
+ {0xbe , 0x36}, \r
+ {0xd0 , 0xc9}, \r
+ {0xd1 , 0x10}, \r
+ //{0xd2 , 0x90}, \r
+ {0xd3 , 0x80}, \r
+ {0xd5 , 0xf2}, \r
+ {0xd6 , 0x16}, \r
+ {0xdb , 0x92}, \r
+ {0xdc , 0xa5}, \r
+ {0xdf , 0x23}, \r
+ {0xd9 , 0x00}, \r
+ {0xda , 0x00}, \r
+ {0xe0 , 0x09}, \r
+ \r
+ {0xed , 0x04}, \r
+ {0xee , 0xa0}, \r
+ {0xef , 0x40}, \r
+ {0x80 , 0x03}, \r
+ {0x80 , 0x03}, \r
+ {0x9F , 0x10}, \r
+ {0xA0 , 0x20}, \r
+ {0xA1 , 0x38}, \r
+ {0xA2 , 0x4E}, \r
+ {0xA3 , 0x63}, \r
+ {0xA4 , 0x76}, \r
+ {0xA5 , 0x87}, \r
+ {0xA6 , 0xA2}, \r
+ {0xA7 , 0xB8}, \r
+ {0xA8 , 0xCA}, \r
+ {0xA9 , 0xD8}, \r
+ {0xAA , 0xE3}, \r
+ {0xAB , 0xEB}, \r
+ {0xAC , 0xF0}, \r
+ {0xAD , 0xF8}, \r
+ {0xAE , 0xFD}, \r
+ {0xAF , 0xFF}, \r
+ /*GC0308_GAMMA_Select,\r
+ 1: //smallest gamma curve\r
+ {0x9F , 0x0B},\r
+ {0xA0 , 0x16},\r
+ {0xA1 , 0x29},\r
+ {0xA2 , 0x3C},\r
+ {0xA3 , 0x4F},\r
+ {0xA4 , 0x5F},\r
+ {0xA5 , 0x6F},\r
+ {0xA6 , 0x8A},\r
+ {0xA7 , 0x9F},\r
+ {0xA8 , 0xB4}, \r
+ {0xA9 , 0xC6},\r
+ {0xAA , 0xD3},\r
+ {0xAB , 0xDD},\r
+ {0xAC , 0xE5},\r
+ {0xAD , 0xF1},\r
+ {0xAE , 0xFA},\r
+ {0xAF , 0xFF}, \r
+ \r
+ 2: \r
+ {0x9F , 0x0E},\r
+ {0xA0 , 0x1C},\r
+ {0xA1 , 0x34},\r
+ {0xA2 , 0x48},\r
+ {0xA3 , 0x5A},\r
+ {0xA4 , 0x6B},\r
+ {0xA5 , 0x7B},\r
+ {0xA6 , 0x95},\r
+ {0xA7 , 0xAB},\r
+ {0xA8 , 0xBF},\r
+ {0xA9 , 0xCE},\r
+ {0xAA , 0xD9},\r
+ {0xAB , 0xE4},\r
+ {0xAC , 0xEC},\r
+ {0xAD , 0xF7},\r
+ {0xAE , 0xFD},\r
+ {0xAF , 0xFF},\r
+ \r
+ 3:\r
+ {0x9F , 0x10},\r
+ {0xA0 , 0x20},\r
+ {0xA1 , 0x38},\r
+ {0xA2 , 0x4E},\r
+ {0xA3 , 0x63},\r
+ {0xA4 , 0x76},\r
+ {0xA5 , 0x87},\r
+ {0xA6 , 0xA2},\r
+ {0xA7 , 0xB8},\r
+ {0xA8 , 0xCA},\r
+ {0xA9 , 0xD8},\r
+ {0xAA , 0xE3},\r
+ {0xAB , 0xEB},\r
+ {0xAC , 0xF0},\r
+ {0xAD , 0xF8},\r
+ {0xAE , 0xFD},\r
+ {0xAF , 0xFF},\r
+ \r
+ 4:\r
+ {0x9F , 0x14},\r
+ {0xA0 , 0x28},\r
+ {0xA1 , 0x44},\r
+ {0xA2 , 0x5D},\r
+ {0xA3 , 0x72},\r
+ {0xA4 , 0x86},\r
+ {0xA5 , 0x95},\r
+ {0xA6 , 0xB1},\r
+ {0xA7 , 0xC6},\r
+ {0xA8 , 0xD5},\r
+ {0xA9 , 0xE1},\r
+ {0xAA , 0xEA},\r
+ {0xAB , 0xF1},\r
+ {0xAC , 0xF5},\r
+ {0xAD , 0xFB},\r
+ {0xAE , 0xFE},\r
+ {0xAF , 0xFF},\r
+ \r
+ 5: //largest gamma curve\r
+ {0x9F , 0x15},\r
+ {0xA0 , 0x2A},\r
+ {0xA1 , 0x4A},\r
+ {0xA2 , 0x67},\r
+ {0xA3 , 0x79},\r
+ {0xA4 , 0x8C},\r
+ {0xA5 , 0x9A},\r
+ {0xA6 , 0xB3},\r
+ {0xA7 , 0xC5},\r
+ {0xA8 , 0xD5},\r
+ {0xA9 , 0xDF},\r
+ {0xAA , 0xE8},\r
+ {0xAB , 0xEE},\r
+ {0xAC , 0xF3},\r
+ {0xAD , 0xFA},\r
+ {0xAE , 0xFD},\r
+ {0xAF , 0xFF}, */\r
+ //-----------GAMMA Select End--------------//\r
+ \r
+ {0xc0 , 0x00}, \r
+ {0xc1 , 0x10}, \r
+ {0xc2 , 0x1C}, \r
+ {0xc3 , 0x30}, \r
+ {0xc4 , 0x43}, \r
+ {0xc5 , 0x54}, \r
+ {0xc6 , 0x65}, \r
+ {0xc7 , 0x75}, \r
+ {0xc8 , 0x93}, \r
+ {0xc9 , 0xB0}, \r
+ {0xca , 0xCB}, \r
+ {0xcb , 0xE6}, \r
+ {0xcc , 0xFF}, \r
+ {0xf0 , 0x02}, \r
+ {0xf1 , 0x01}, \r
+ {0xf2 , 0x01}, \r
+ {0xf3 , 0x30}, \r
+ {0xf9 , 0x9f}, \r
+ {0xfa , 0x78}, \r
+ \r
+ //---------------------------------------------------------------\r
+ {0xfe , 0x01},// set page1 \r
+ \r
+ {0x00 , 0xf5}, \r
+ {0x02 , 0x1a}, \r
+ {0x0a , 0xa0}, \r
+ {0x0b , 0x60}, \r
+ {0x0c , 0x08}, \r
+ {0x0e , 0x4c}, \r
+ {0x0f , 0x39}, \r
+ {0x11 , 0x3f}, \r
+ {0x12 , 0x72}, \r
+ {0x13 , 0x13}, \r
+ {0x14 , 0x42}, \r
+ {0x15 , 0x43}, \r
+ {0x16 , 0xc2}, \r
+ {0x17 , 0xa8}, \r
+ {0x18 , 0x18}, \r
+ {0x19 , 0x40}, \r
+ {0x1a , 0xd0}, \r
+ {0x1b , 0xf5}, \r
+ {0x70 , 0x40}, \r
+ {0x71 , 0x58}, \r
+ {0x72 , 0x30}, \r
+ {0x73 , 0x48}, \r
+ {0x74 , 0x20}, \r
+ {0x75 , 0x60}, \r
+ {0x77 , 0x20}, \r
+ {0x78 , 0x32}, \r
+ {0x30 , 0x03}, \r
+ {0x31 , 0x40}, \r
+ {0x32 , 0xe0}, \r
+ {0x33 , 0xe0}, \r
+ {0x34 , 0xe0}, \r
+ {0x35 , 0xb0}, \r
+ {0x36 , 0xc0}, \r
+ {0x37 , 0xc0}, \r
+ {0x38 , 0x04}, \r
+ {0x39 , 0x09}, \r
+ {0x3a , 0x12}, \r
+ {0x3b , 0x1C}, \r
+ {0x3c , 0x28}, \r
+ {0x3d , 0x31}, \r
+ {0x3e , 0x44}, \r
+ {0x3f , 0x57}, \r
+ {0x40 , 0x6C}, \r
+ {0x41 , 0x81}, \r
+ {0x42 , 0x94}, \r
+ {0x43 , 0xA7}, \r
+ {0x44 , 0xB8}, \r
+ {0x45 , 0xD6}, \r
+ {0x46 , 0xEE}, \r
+ {0x47 , 0x0d}, \r
+ {0xfe , 0x00}, // set page0\r
+ \r
+ //-----------Update the registers 2010/07/06-------------//\r
+ //Registers of Page0\r
+ {0xfe , 0x00}, // set page0\r
+ {0x10 , 0x26}, \r
+ {0x11 , 0x0d}, // fd,modified by mormo 2010/07/06 \r
+ {0x1a , 0x2a}, // 1e,modified by mormo 2010/07/06 \r
+ \r
+ {0x1c , 0x49}, // c1,modified by mormo 2010/07/06 \r
+ {0x1d , 0x9a}, // 08,modified by mormo 2010/07/06 \r
+ {0x1e , 0x61}, // 60,modified by mormo 2010/07/06 \r
+ \r
+ {0x3a , 0x20},\r
+ \r
+ {0x50 , 0x14}, // 10,modified by mormo 2010/07/06 \r
+ {0x53 , 0x80}, \r
+ {0x56 , 0x80},\r
+ \r
+ {0x8b , 0x20}, //LSC \r
+ {0x8c , 0x20}, \r
+ {0x8d , 0x20}, \r
+ {0x8e , 0x14}, \r
+ {0x8f , 0x10}, \r
+ {0x90 , 0x14}, \r
+ \r
+ {0x94 , 0x02}, \r
+ {0x95 , 0x07}, \r
+ {0x96 , 0xe0}, \r
+ \r
+ {0xb1 , 0x40}, // YCPT \r
+ {0xb2 , 0x40}, \r
+ {0xb3 , 0x40},\r
+ {0xb6 , 0xe0},\r
+ \r
+ {0xd0 , 0xcb}, // AECT c9,modifed by mormo 2010/07/06 \r
+ {0xd3 , 0x48}, // 80,modified by mormor 2010/07/06 \r
+ \r
+ {0xf2 , 0x02}, \r
+ {0xf7 , 0x12},\r
+ {0xf8 , 0x0a},\r
+ \r
+ //Registers of Page1\r
+ {0xfe , 0x01},// set page1 \r
+ {0x02 , 0x20},\r
+ {0x04 , 0x10},\r
+ {0x05 , 0x08},\r
+ {0x06 , 0x20},\r
+ {0x08 , 0x0a},\r
+ \r
+ {0x0e , 0x44}, \r
+ {0x0f , 0x32},\r
+ {0x10 , 0x41}, \r
+ {0x11 , 0x37}, \r
+ {0x12 , 0x22}, \r
+ {0x13 , 0x19}, \r
+ {0x14 , 0x44}, \r
+ {0x15 , 0x44}, \r
+ \r
+ {0x19 , 0x50}, \r
+ {0x1a , 0xd8}, \r
+ \r
+ {0x32 , 0x10}, \r
+ \r
+ {0x35 , 0x00}, \r
+ {0x36 , 0x80}, \r
+ {0x37 , 0x00}, \r
+ //-----------Update the registers end---------//\r
+ \r
+ \r
+ {0xfe , 0x00}, // set page0\r
+ {0xd2 , 0x90}, \r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ SensorEnd\r
+\r
+};\r
+\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x00,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x5a, 0x4c}, \r
+ {0x5b, 0x40},\r
+ {0x5c, 0x4a},\r
+ {0x22, 0x57},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x22, 0x55}, // Disable AWB \r
+ {0x5a, 0x5a},\r
+ {0x5b, 0x42},\r
+ {0x5c, 0x40},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x22, 0x55}, // Disable AWB \r
+ {0x5a, 0x50},\r
+ {0x5b, 0x45},\r
+ {0x5c, 0x40},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x22, 0x55}, // Disable AWB \r
+ {0x5a, 0x48},\r
+ {0x5b, 0x40},\r
+ {0x5c, 0x5c},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x22, 0x55}, // Disable AWB \r
+ {0x5a, 0x40},\r
+ {0x5b, 0x42}, \r
+ {0x5c, 0x50},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ {0xb5, 0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ {0xb5, 0xf0},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ {0xb5, 0x00},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0xb5, 0x20},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0xb5, 0x30},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0xb5, 0x40},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x23,0x00}, \r
+ {0x2d,0x0a}, \r
+ {0x20,0x7f}, \r
+ {0xd2,0x90}, \r
+ {0x73,0x00}, \r
+ {0x77,0x38},\r
+ {0xb3,0x40}, \r
+ {0xb4,0x80}, \r
+ {0xba,0x00}, \r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a}, \r
+ {0x20,0x7f}, \r
+ {0xd2,0x90}, \r
+ {0x73,0x00}, \r
+ {0xb3,0x40},\r
+ {0xb4,0x80}, \r
+ {0xba,0x00}, \r
+ {0xbb,0x00}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x23,0x02},\r
+ {0x2d,0x0a},\r
+ {0x20,0x7f},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0xd2},\r
+ {0xbb,0x28},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x23,0x01},\r
+ {0x2d,0x0a},\r
+ {0x20,0x7f},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x23,0x02},\r
+ {0x2d,0x0a},\r
+ {0x20,0x7f},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x50},\r
+ {0xbb,0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x23,0x02},\r
+ {0x2d,0x0a},\r
+ {0x20,0x7f},\r
+ {0xd2,0x90},\r
+ {0x77,0x88},\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0xc0},\r
+ {0xbb,0xc0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ {0xd3, 0x30},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ {0xd3, 0x38},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ {0xd3, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ {0xd3, 0x48},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ {0xd3, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ {0xd3, 0x58},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ {0xd3, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ {0xb3,0x34},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ {0xb3,0x38},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ {0xb3,0x3d},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ {0xb3,0x40},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ {0xb3,0x44},\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ {0xb3,0x48},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ {0xb3,0x50},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xec, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ {0xec, 0x30},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ \r
+ //{0xfe , 0x00}, // set page0\r
+ \r
+ //{0x14 , 0x13}, //0x10\r
+ //-------------H_V_Switch(4)---------------//\r
+ /* 1: // normal\r
+ {0x14 , 0x10}, \r
+ 2: // IMAGE_H_MIRROR\r
+ {0x14 , 0x11},\r
+ \r
+ 3: // IMAGE_V_MIRROR\r
+ {0x14 , 0x12},\r
+ \r
+ 4: // IMAGE_HV_MIRROR\r
+ {0x14 , 0x13},*/ \r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x14, &val);\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0)\r
+ err = sensor_write(client, 0x14, (val |0x1));\r
+ else \r
+ err = sensor_write(client, 0x14, (val & 0xfe));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ \r
+ //{0xfe , 0x00}, // set page0\r
+ \r
+ //{0x14 , 0x13}, //0x10\r
+ //-------------H_V_Switch(4)---------------//\r
+ /* 1: // normal\r
+ {0x14 , 0x10}, \r
+ 2: // IMAGE_H_MIRROR\r
+ {0x14 , 0x11},\r
+ \r
+ 3: // IMAGE_V_MIRROR\r
+ {0x14 , 0x12},\r
+ \r
+ 4: // IMAGE_HV_MIRROR\r
+ {0x14 , 0x13},*/ \r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x14, &val);\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0)\r
+ err = sensor_write(client, 0x14, (val |0x2));\r
+ else \r
+ err = sensor_write(client, 0x14, (val & 0xfc));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
--- /dev/null
+
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
+ {
+ 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);
+ }
+
+ }
+
+
+ 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;
+ 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
+\r
+#include "generic_sensor.h"\r
+\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? x: y)
-
-/* Sensor Driver Configuration */
-#define SENSOR_NAME RK29_CAM_SENSOR_GC0309
-#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309
-#define SENSOR_ID 0xa0
-#define SENSOR_MIN_WIDTH 176
-#define SENSOR_MIN_HEIGHT 144
-#define SENSOR_MAX_WIDTH 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char value;
- int ret;
- struct sensor *sensor = to_sensor(client);
-
- /* We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant. */
- if (!icd->dev.parent ||
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
- return -ENODEV;
-
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- /* soft reset */
- ret = sensor_write(client, 0xfe, 0x80);
- if (ret != 0)
- {
- SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
- return -ENODEV;
- }
- mdelay(5); //delay 5 microseconds
-
- /* check if it is an sensor sensor */
- ret = sensor_read(client, 0x00, &value);
- if (ret != 0) {
- SENSOR_TR("read chip id high byte failed\n");
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- if (value == SENSOR_ID) {
- sensor->model = SENSOR_V4L2_IDENT;
- SENSOR_TR("chip id:0x%x\n",value);
- } else {
- SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value);
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0309\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309\r
+#define SENSOR_ID 0xa0\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); \r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ /*init registers code.*/\r
+#if 1\r
+ {0xfe,0x80}, // soft reset \r
+ {0x1a,0x16}, \r
+ {0xd2,0x10}, // close AEC\r
+ {0x22,0x55}, // close AWB\r
+ \r
+ {0x5a,0x56}, \r
+ {0x5b,0x40},\r
+ {0x5c,0x4a}, \r
+ \r
+ {0x22,0x57}, \r
+ \r
+ {0x01,0xfa}, \r
+ {0x02,0x70}, \r
+ {0x0f,0x01}, \r
+ \r
+ {0xe2,0x00}, \r
+ {0xe3,0x64}, \r
+ \r
+ {0x03,0x01}, \r
+ {0x04,0x2c}, \r
+ \r
+ {0x05,0x00},\r
+ {0x06,0x00},\r
+ {0x07,0x00}, \r
+ {0x08,0x00}, \r
+ {0x09,0x01}, \r
+ {0x0a,0xe8}, \r
+ {0x0b,0x02}, \r
+ {0x0c,0x88}, \r
+ {0x0d,0x02}, \r
+ {0x0e,0x02}, \r
+ {0x10,0x22}, \r
+ {0x11,0x0d}, \r
+ {0x12,0x2a}, \r
+ {0x13,0x00}, \r
+ {0x14,0x13},\r
+ {0x15,0x0a}, \r
+ {0x16,0x05}, \r
+ {0x17,0x01}, \r
+ \r
+ {0x1b,0x03}, \r
+ {0x1c,0xc1}, \r
+ {0x1d,0x08}, \r
+ {0x1e,0x20},\r
+ {0x1f,0x16}, \r
+ \r
+ {0x20,0xff}, \r
+ {0x21,0xf8}, \r
+ {0x24,0xa2}, \r
+ {0x25,0x0f},\r
+ //output sync_mode\r
+ {0x26,0x03}, \r
+ {0x2f,0x01}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// grab_t ////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x30,0xf7}, \r
+ {0x31,0x40},\r
+ {0x32,0x00}, \r
+ {0x39,0x04}, \r
+ {0x3a,0x20}, \r
+ {0x3b,0x20}, \r
+ {0x3c,0x02}, \r
+ {0x3d,0x02}, \r
+ {0x3e,0x02},\r
+ {0x3f,0x02}, \r
+ \r
+ //gain\r
+ {0x50,0x24}, \r
+ \r
+ {0x53,0x82}, \r
+ {0x54,0x80}, \r
+ {0x55,0x80}, \r
+ {0x56,0x82}, \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// LSC_t ////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x8b,0x20}, \r
+ {0x8c,0x20}, \r
+ {0x8d,0x20}, \r
+ {0x8e,0x10}, \r
+ {0x8f,0x10}, \r
+ {0x90,0x10}, \r
+ {0x91,0x3c}, \r
+ {0x92,0x50}, \r
+ {0x5d,0x12}, \r
+ {0x5e,0x1a}, \r
+ {0x5f,0x24}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// DNDD_t ///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x60,0x07}, \r
+ {0x61,0x0e}, \r
+ {0x62,0x0c}, \r
+ {0x64,0x03}, \r
+ {0x66,0xe8}, \r
+ {0x67,0x86}, \r
+ {0x68,0xa2}, \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// asde_t ///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x69,0x20}, \r
+ {0x6a,0x0f}, \r
+ {0x6b,0x00}, \r
+ {0x6c,0x53}, \r
+ {0x6d,0x83}, \r
+ {0x6e,0xac}, \r
+ {0x6f,0xac}, \r
+ {0x70,0x15}, \r
+ {0x71,0x33}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// eeintp_t///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x72,0xdc}, \r
+ {0x73,0x80}, \r
+ //for high resolution in light scene\r
+ {0x74,0x02}, \r
+ {0x75,0x3f}, \r
+ {0x76,0x02}, \r
+ {0x77,0x54}, \r
+ {0x78,0x88}, \r
+ {0x79,0x81}, \r
+ {0x7a,0x81}, \r
+ {0x7b,0x22}, \r
+ {0x7c,0xff},\r
+ \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ ///////////////////////////CC_t///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x93,0x45}, \r
+ {0x94,0x00}, \r
+ {0x95,0x00}, \r
+ {0x96,0x00}, \r
+ {0x97,0x45}, \r
+ {0x98,0xf0}, \r
+ {0x9c,0x00}, \r
+ {0x9d,0x03}, \r
+ {0x9e,0x00}, \r
+ \r
+ \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ ///////////////////////////YCP_t///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0xb1,0x40}, \r
+ {0xb2,0x40}, \r
+ {0xb8,0x20}, \r
+ {0xbe,0x36}, \r
+ {0xbf,0x00}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ ///////////////////////////AEC_t///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0xd0,0xc9}, \r
+ {0xd1,0x10}, \r
+ // {0xd2,0x90}, \r
+ {0xd3,0x80}, \r
+ {0xd5,0xf2}, \r
+ {0xd6,0x16}, \r
+ {0xdb,0x92}, \r
+ {0xdc,0xa5}, \r
+ {0xdf,0x23}, \r
+ {0xd9,0x00}, \r
+ {0xda,0x00}, \r
+ {0xe0,0x09},\r
+ \r
+ {0xec,0x20}, \r
+ {0xed,0x04}, \r
+ {0xee,0xa0}, \r
+ {0xef,0x40}, \r
+ \r
+ //Y_gamma\r
+ {0xc0,0x00},\r
+ {0xc1,0x0B},\r
+ {0xc2,0x15},\r
+ {0xc3,0x27},\r
+ {0xc4,0x39},\r
+ {0xc5,0x49},\r
+ {0xc6,0x5A},\r
+ {0xc7,0x6A},\r
+ {0xc8,0x89},\r
+ {0xc9,0xA8},\r
+ {0xca,0xC6},\r
+ {0xcb,0xE3},\r
+ {0xcc,0xFF},\r
+ \r
+ /////////////////////////////////////////////////////////////////\r
+ /////////////////////////// ABS_t ///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////\r
+ {0xf0,0x02},\r
+ {0xf1,0x01},\r
+ {0xf2,0x00}, \r
+ {0xf3,0x30}, \r
+ \r
+ /////////////////////////////////////////////////////////////////\r
+ /////////////////////////// Measure Window ///////////////////////\r
+ /////////////////////////////////////////////////////////////////\r
+ {0xf7,0x04}, \r
+ {0xf8,0x02}, \r
+ {0xf9,0x9f},\r
+ {0xfa,0x78},\r
+ \r
+#else\r
+ {0xfe,0x80}, // soft reset \r
+ \r
+ {0x1a,0x16}, \r
+ {0xd2,0x10}, // close AEC\r
+ {0x22,0x55}, // close AWB\r
+ \r
+ {0x5a,0x56}, \r
+ {0x5b,0x40},\r
+ {0x5c,0x4a}, \r
+ \r
+ {0x22,0x57}, \r
+ \r
+ {0x01,0xfa}, \r
+ {0x02,0x70}, \r
+ {0x0f,0x01}, \r
+ \r
+ {0xe2,0x00}, \r
+ {0xe3,0x64}, \r
+ \r
+ {0x03,0x01}, \r
+ {0x04,0x2c}, \r
+ \r
+ \r
+ {0x05,0x00},\r
+ {0x06,0x00},\r
+ {0x07,0x00}, \r
+ {0x08,0x00}, \r
+ {0x09,0x01}, \r
+ {0x0a,0xe8}, \r
+ {0x0b,0x02}, \r
+ {0x0c,0x88}, \r
+ {0x0d,0x02}, \r
+ {0x0e,0x02}, \r
+ {0x10,0x22}, \r
+ {0x11,0x0d}, \r
+ {0x12,0x2a}, \r
+ {0x13,0x00}, \r
+ \r
+ {0x15,0x0a}, \r
+ {0x16,0x05}, \r
+ {0x17,0x01}, \r
+ \r
+ {0x1b,0x03}, \r
+ {0x1c,0xc1}, \r
+ {0x1d,0x08}, \r
+ {0x1e,0x20},\r
+ {0x1f,0x16}, \r
+ \r
+ {0x20,0xff}, \r
+ {0x21,0xf8}, \r
+ {0x24,0xa2}, \r
+ {0x25,0x0f},\r
+ //output sync_mode\r
+ {0x26,0x03}, \r
+ {0x2f,0x01}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// grab_t ////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x30,0xf7}, \r
+ {0x31,0x40},\r
+ {0x32,0x00}, \r
+ {0x39,0x04}, \r
+ {0x3a,0x20}, \r
+ {0x3b,0x20}, \r
+ {0x3c,0x02}, \r
+ {0x3d,0x02}, \r
+ {0x3e,0x02},\r
+ {0x3f,0x02}, \r
+ \r
+ //gain\r
+ {0x50,0x24}, \r
+ \r
+ {0x53,0x82}, \r
+ {0x54,0x80}, \r
+ {0x55,0x80}, \r
+ {0x56,0x82}, \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// LSC_t ////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x8b,0x20}, \r
+ {0x8c,0x20}, \r
+ {0x8d,0x20}, \r
+ {0x8e,0x10}, \r
+ {0x8f,0x10}, \r
+ {0x90,0x10}, \r
+ {0x91,0x3c}, \r
+ {0x92,0x50}, \r
+ {0x5d,0x12}, \r
+ {0x5e,0x1a}, \r
+ {0x5f,0x24}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// DNDD_t ///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x60,0x07}, \r
+ {0x61,0x0e}, \r
+ {0x62,0x0c}, \r
+ {0x64,0x03}, \r
+ {0x66,0xe8}, \r
+ {0x67,0x86}, \r
+ {0x68,0xa2}, \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// asde_t ///////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x69,0x20}, \r
+ {0x6a,0x0f}, \r
+ {0x6b,0x00}, \r
+ {0x6c,0x53}, \r
+ {0x6d,0x83}, \r
+ {0x6e,0xac}, \r
+ {0x6f,0xac}, \r
+ {0x70,0x15}, \r
+ {0x71,0x33}, \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// eeintp_t///////////////////////////////\r
+#endif\r
+ {0x23,0x00},\r
+ {0x2d,0x0a}, // 0x08\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ {0x77,0x54},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ SensorEnd\r
+\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0xfe,80),\r
+ SensorWaitMs(5),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x00,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x5a,0x56}, //for AWB can adjust back\r
+ {0x5b,0x40},\r
+ {0x5c,0x4a}, \r
+ {0x22,0x57}, // Enable AWB\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x22,0x55}, // Disable AWB \r
+ {0x5a,0x8c}, //WB_manual_gain \r
+ {0x5b,0x50},\r
+ {0x5c,0x40},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x22,0x55}, \r
+ {0x5a,0x74}, \r
+ {0x5b,0x52},\r
+ {0x5c,0x40}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Incandescent\r
+ {0x22,0x55}, \r
+ {0x5a,0x48},\r
+ {0x5b,0x40},\r
+ {0x5c,0x5c},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //fluorescent\r
+ {0x22,0x55}, \r
+ {0x5a,0x40},\r
+ {0x5b,0x42},\r
+ {0x5c,0x50},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x23,0x00},\r
+ {0x2d,0x0a}, // 0x08\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ {0x77,0x54},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xbf},\r
+ {0xd2,0x10},\r
+ {0x73,0x01},\r
+ \r
+ {0x51,0x40},\r
+ {0x52,0x40},\r
+ {0xb3,0x60},\r
+ {0xb4,0x40},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0xd0},\r
+ {0xbb,0x28}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x23,0x03}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ //Bluish\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x50},\r
+ {0xbb,0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ //Greenish\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x77,0x88},\r
+ \r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0xc0},\r
+ {0xbb,0xc0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Grayscale[]=\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ {0x00,0x00}\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ //-3\r
+ {0xb5, 0xe8},\r
+ {0xd3, 0x38},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ //-2\r
+ {0xb5, 0xf0},\r
+ {0xd3, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ //-1\r
+ {0xb5, 0xf8},\r
+ {0xd3, 0x48},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ //default\r
+ {0xb5, 0x00},\r
+ {0xd3, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ // 1\r
+ {0xb5, 0x08},\r
+ {0xd3, 0x58},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ // 2\r
+ {0xb5, 0x10},\r
+ {0xd3, 0x60},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ // 3\r
+ {0xb5, 0x18},\r
+ {0xd3, 0x68},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xec, 0x20},\r
+ {0x20, 0x7f}, // close cc\r
+ {0x3c, 0x02},\r
+ {0x3d, 0x02},\r
+ {0x3e, 0x02},\r
+ {0x3f, 0x02},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk\r
+ {0xec, 0x30},\r
+ {0x20, 0x5f}, // close cc\r
+ {0x3c, 0x08},\r
+ {0x3d, 0x08},\r
+ {0x3e, 0x08},\r
+ {0x3f, 0x08},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x14, &val);\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0)\r
+ err = sensor_write(client, 0x14, (val |0x1));\r
+ else \r
+ err = sensor_write(client, 0x14, (val & 0xfe));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x14, &val);\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0)\r
+ err = sensor_write(client, 0x14, (val |0x2));\r
+ else \r
+ err = sensor_write(client, 0x14, (val & 0xfc));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0309
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0309
+#define SENSOR_ID 0xa0
+#define SENSOR_MIN_WIDTH 176
+#define SENSOR_MIN_HEIGHT 144
+#define SENSOR_MAX_WIDTH 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char value;
+ int ret;
+ struct sensor *sensor = to_sensor(client);
+
+ /* We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant. */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+ return -ENODEV;
+
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ /* soft reset */
+ ret = sensor_write(client, 0xfe, 0x80);
+ if (ret != 0)
+ {
+ SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+ return -ENODEV;
+ }
+ mdelay(5); //delay 5 microseconds
+
+ /* check if it is an sensor sensor */
+ ret = sensor_read(client, 0x00, &value);
+ if (ret != 0) {
+ SENSOR_TR("read chip id high byte failed\n");
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ if (value == SENSOR_ID) {
+ sensor->model = SENSOR_V4L2_IDENT;
+ SENSOR_TR("chip id:0x%x\n",value);
+ } else {
+ SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), value);
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
+
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+\r
+static int debug =1;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0328\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0328\r
+#define SENSOR_ID 0x9d\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); \r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0xfe , 0x80},\r
+ {0xfe , 0x80},\r
+ {0xfc , 0x16}, //clock enable\r
+ {0xfc , 0x16}, //clock enable\r
+ {0xfc , 0x16}, //clock enable\r
+ {0xfc , 0x16}, //clock enable\r
+ \r
+ {0x42 , 0x02},\r
+ \r
+ {0xfe , 0x01},\r
+ {0x4c , 0x01}, //AWB Buffer reset\r
+ {0xfe , 0x00},\r
+ \r
+ {0xfe , 0x00},\r
+ {0x0d , 0x01}, //{8}cis_win_height 486 1e6\r
+ {0x0e , 0xe8}, //{7:0}cis_win_height\r
+ {0x0f , 0x02}, //{9:8}cis_win_width 646 286\r
+ {0x10 , 0x88}, //{7:0}cis_win_width\r
+ {0x09 , 0x00}, //row_start\r
+ {0x0a , 0x00},\r
+ {0x0b , 0x00}, //col_start\r
+ {0x0c , 0x00},\r
+ {0x16 , 0x80},\r
+ {0x17 , 0x14}, //[7]hsync_always, [6]close_2_frame_dbrow, [5:4]CFA_seqence, [3:2]dark_CFA_seqence, [1]updown, [0]mirror\r
+ {0x19 , 0x06}, //AD Pipe line number\r
+ {0x1f , 0xC8}, //txlow\r
+ {0x20 , 0x01},\r
+ {0x21 , 0x78}, //68 \r
+ {0x22 , 0xb0},\r
+ {0x24 , 0x16},\r
+ {0x26 , 0x01},\r
+ \r
+ {0x50 , 0x01}, //crop mode\r
+ \r
+ //global gain for range\r
+ {0x70 , 0x45},\r
+ \r
+ ////////////////////////////////////////////////\r
+ //////////// BLK //////////////////////\r
+ ////////////////////////////////////////////////\r
+ {0x27 , 0x27},\r
+ {0x28 , 0x7F}, //BLK LIMIT\r
+ {0x29 , 0x20}, //global offset\r
+ {0x33 , 0x1A},//offset_ratio_G1\r
+ {0x34 , 0x1A}, //offset_ratio_R\r
+ {0x35 , 0x1A},\r
+ {0x36 , 0x1A},\r
+ {0x37 , 0x20}, \r
+ {0x38 , 0x20},\r
+ {0x39 , 0x20},\r
+ {0x3a , 0x20},\r
+ {0x47 , 0x00},\r
+ {0x48 , 0x75},//00\r
+ \r
+ \r
+ \r
+ ////////////////////////////////////////////////\r
+ //////////// block enable /////////////\r
+ ////////////////////////////////////////////////\r
+ {0x40 , 0x7f}, //\r
+ {0x41 , 0x22},//\r
+ \r
+ \r
+ {0x42 , 0xff},//\r
+ {0x45 , 0x00},\r
+ {0x44 , 0x02},\r
+ {0x46 , 0x02},\r
+ {0x4b , 0x01},\r
+ {0x50 , 0x01}, //crop mode\r
+ \r
+ //DN & EEINTP\r
+ {0x7e , 0x0a}, //\r
+ {0x7f , 0x03}, //c3 //1D DN\r
+ {0x81 , 0x15},\r
+ {0x82 , 0x85}, //8f//bilt_base_b\r
+ {0x83 , 0x02}, //02 //DN C weight\r
+ {0x84 , 0xe5},\r
+ {0x90 , 0xac},\r
+ {0x92 , 0x02}, //5\r
+ {0x94 , 0x05},\r
+ {0x95 , 0x63}, \r
+ \r
+ \r
+ ///////YCP\r
+ {0xd1 , 0x38},\r
+ {0xd2 , 0x38}, // cb,cr saturation\r
+ {0xdd , 0x54},\r
+ {0xde , 0x38}, //autogray_mode\r
+ {0xe4 , 0x88},\r
+ {0xe5 , 0x40},\r
+ {0xd7 , 0x0e},\r
+ //rgb gamma\r
+ {0xBF , 0x0E}, \r
+ {0xc0 , 0x1C}, \r
+ {0xc1 , 0x34},\r
+ {0xc2 , 0x48},\r
+ {0xc3 , 0x5A},\r
+ {0xc4 , 0x6B},\r
+ {0xc5 , 0x7B},\r
+ {0xc6 , 0x95},\r
+ {0xc7 , 0xAB},\r
+ {0xc8 , 0xBF},\r
+ {0xc9 , 0xCE},\r
+ {0xcA , 0xD9},\r
+ {0xcB , 0xE4},\r
+ {0xcC , 0xEC},\r
+ {0xcD , 0xF7},\r
+ {0xcE , 0xFD},\r
+ {0xcF , 0xFF},\r
+ \r
+ ///Y gamma\r
+ {0xfe , 0x00},\r
+ {0x63 , 0x00},\r
+ {0x64 , 0x05},\r
+ {0x65 , 0x0b},\r
+ {0x66 , 0x19},\r
+ {0x67 , 0x2e},\r
+ {0x68 , 0x40},\r
+ {0x69 , 0x54},\r
+ {0x6a , 0x66},\r
+ {0x6b , 0x86},\r
+ {0x6c , 0xa7},\r
+ {0x6d , 0xc6},\r
+ {0x6e , 0xe4},\r
+ {0x6f , 0xff},\r
+ \r
+ //ASDE\r
+ {0xfe , 0x01},\r
+ {0x18 , 0x02},\r
+ {0xfe , 0x00},\r
+ {0x97 , 0x30}, //Y offset TH\r
+ {0xa4 , 0x10}, //ASDE auto sa slope\r
+ {0xa8 , 0x80}, //ASDE LSC SLOPE\r
+ {0x9c , 0x60}, //auto Y offset Slope\r
+ {0xa2 , 0x23},\r
+ {0xad , 0x01}, //ASDE ee,ddMODE\r
+ {0x9c , 0x01}, //ABS manual K\r
+ \r
+ {0xfe , 0x01},\r
+ {0x9c , 0x00}, //ABS manual K\r
+ {0x08 , 0xa0},\r
+ {0x09 , 0xe8},\r
+ \r
+ {0x10 , 0x08},//[7]win_mode,[6]show_mode [3]measure_point\r
+ \r
+ {0x11 , 0x21}, //[7]fix target\r
+ {0x12 , 0x10}, \r
+ {0x13 , 0x45}, //AEC Y target\r
+ {0x15 , 0xfc}, //high range for count\r
+ {0x21 , 0xf0}, //c0 //post_gain limit\r
+ {0x22 , 0x60},\r
+ {0x23 , 0x30},//20 //dggain max\r
+ {0x25 , 0x00},\r
+ {0x24 , 0x14}, //Max index\r
+ \r
+ \r
+ {0xfe , 0x01},\r
+ {0x51 , 0x20},\r
+ {0x52 , 0x4f},\r
+ {0x53 , 0x40},\r
+ {0x54 , 0x9f},\r
+ {0x55 , 0x01},\r
+ {0x56 , 0x18}, //18\r
+ {0x5b , 0x02},\r
+ {0xb1 , 0xdc},\r
+ {0xb2 , 0xdc}, //R2G STAND\r
+ {0x7c , 0x71}, //AWB speed,AWB margin\r
+ {0x7d , 0x10}, //AWB every N\r
+ {0x76 , 0x8f}, //move mode en,Move mode TH\r
+ \r
+ \r
+ {0x50 , 0x80},\r
+ {0x4f , 0x00},\r
+ {0x4d , 0x01},\r
+ {0x4e , 0x02},\r
+ {0x4d , 0x35},\r
+ {0x4e , 0x01},\r
+ {0x4e , 0x01},\r
+ {0x4e , 0x01},\r
+ {0x4d , 0x44},\r
+ {0x4e , 0x04},\r
+ {0x4e , 0x04},\r
+ {0x4e , 0x02}, \r
+ {0x4d , 0x53},\r
+ {0x4e , 0x08},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x04},\r
+ {0x4d , 0x03},\r
+ {0x4e , 0x08},\r
+ {0x4d , 0x72},\r
+ {0x4e , 0x20}, \r
+ {0x4e , 0x20},\r
+ {0x4d , 0x83}, \r
+ {0x4e , 0x20},\r
+ {0x4d , 0x92},\r
+ {0x4e , 0x40},\r
+ {0x4e , 0x40},\r
+ {0x4f , 0x01}, \r
+ {0xfe , 0x00}, //page0\r
+ \r
+ {0xad , 0x00},\r
+ \r
+ {0xfe , 0x01},\r
+ {0xc0 , 0x11},\r
+ {0xc1 , 0x0b},\r
+ {0xc2 , 0x09},\r
+ {0xc6 , 0x0f},\r
+ {0xc7 , 0x0a},\r
+ {0xc8 , 0x07},\r
+ {0xba , 0x2d},\r
+ {0xbb , 0x1e},\r
+ {0xbc , 0x1e},\r
+ {0xb4 , 0x38},\r
+ {0xb5 , 0x26},\r
+ {0xb6 , 0x23},\r
+ {0xc3 , 0x00},\r
+ {0xc4 , 0x00},\r
+ {0xc5 , 0x00},\r
+ {0xc9 , 0x00},\r
+ {0xca , 0x00},\r
+ {0xcb , 0x00},\r
+ {0xbd , 0x0a},\r
+ {0xbe , 0x00},\r
+ {0xbf , 0x00},\r
+ {0xb7 , 0x04},\r
+ {0xb8 , 0x00},\r
+ {0xb9 , 0x00},\r
+ {0xa8 , 0x08},\r
+ {0xa9 , 0x00},\r
+ {0xaa , 0x00},\r
+ {0xab , 0x07},\r
+ {0xac , 0x00},\r
+ {0xad , 0x07},\r
+ {0xae , 0x0e},\r
+ {0xaf , 0x03},\r
+ {0xb0 , 0x03},\r
+ {0xb1 , 0x0d},\r
+ {0xb2 , 0x00},\r
+ {0xb3 , 0x08},\r
+ {0xa4 , 0x00},\r
+ {0xa5 , 0x00},\r
+ {0xa6 , 0x00},\r
+ {0xa7 , 0x00},\r
+ {0xa1 , 0x3c},\r
+ {0xa2 , 0x50},\r
+ {0xfe , 0x00},\r
+ \r
+ {0xB1 , 0x08},// 40\r
+ {0xB2 , 0x02},\r
+ {0xB3 , 0x07},\r
+ {0xB4 , 0xe0},\r
+ {0xB5 , 0x00},//\r
+ {0xB6 , 0xf0},\r
+ \r
+ {0xf1 , 0x07},\r
+ {0xf1 , 0x07},\r
+ {0xf2 , 0x01},\r
+ \r
+ {0x4f , 0x01},\r
+ \r
+ \r
+ \r
+ {0x05, 0x02}, \r
+ {0x06, 0x2c}, \r
+ {0x07, 0x00},\r
+ {0x08, 0xb8},\r
+ {0xfe, 0x01},\r
+ //GC0328_SET_PAGE1,\r
+ {0x29, 0x00}, //anti-flicker step [11:8]\r
+ {0x2a, 0x60}, //anti-flicker step [7:0]\r
+ \r
+ {0x2b, 0x02}, //exp level 0 14.28fps\r
+ {0x2c, 0xa0}, \r
+ {0x2d, 0x03}, //exp level 1 12.50fps\r
+ {0x2e, 0x00}, \r
+ {0x2f, 0x03}, //exp level 2 10.00fps\r
+ {0x30, 0xc0}, \r
+ {0x31, 0x05}, //exp level 3 7.14fps\r
+ {0x32, 0x40}, \r
+ \r
+ {0xfe, 0x00},\r
+ \r
+ \r
+ //-------------H_V_Switch(4)---------------//\r
+ {0x17 , 0x14}, //\r
+ \r
+ \r
+ /*GC0328_H_V_Switch,\r
+ \r
+ 1: // normal\r
+ {0x17 , 0x14},\r
+ \r
+ 2: // IMAGE_H_MIRROR\r
+ {0x17 , 0x15},\r
+ \r
+ 3: // IMAGE_V_MIRROR\r
+ {0x17 , 0x16},\r
+ \r
+ 4: // IMAGE_HV_MIRROR\r
+ {0x17 , 0x17},\r
+ */ \r
+ //-------------H_V_Select End--------------//\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ SensorEnd\r
+\r
+};\r
+\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0xf0,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0xfe, 0x00},\r
+ {0x77, 0x57}, \r
+ {0x78, 0x4d},\r
+ {0x79, 0x45},\r
+ {0x42, 0x57},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0xfe, 0x00},\r
+ {0x42, 0x55}, // Disable AWB \r
+ {0x77, 0x8c},\r
+ {0x78, 0x50},\r
+ {0x79, 0x40},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0xfe, 0x00},\r
+ {0x42, 0x55}, // Disable AWB \r
+ {0x77, 0x74},\r
+ {0x78, 0x52},\r
+ {0x79, 0x40},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0xfe, 0x00},\r
+ {0x42, 0x55}, // Disable AWB \r
+ {0x77, 0x48},\r
+ {0x78, 0x40},\r
+ {0x79, 0x5c},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0xfe, 0x00},\r
+ {0x42, 0x55}, // Disable AWB \r
+ {0x77, 0x40},\r
+ {0x78, 0x42}, \r
+ {0x79, 0x50},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ {0xfe, 0x00},\r
+ {0xd5, 0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ {0xfe, 0x00},\r
+ {0xd5, 0xf0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ {0xfe, 0x00},\r
+ {0xd5, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0xfe, 0x00},\r
+ {0xd5, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0xfe, 0x00},\r
+ {0xd5, 0x30},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0xfe, 0x00},\r
+ {0xd5, 0x40},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x43,0x00}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x43,0x02}, \r
+ {0xda,0x00}, \r
+ {0xdb,0x00}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x43,0x02},\r
+ {0xda,0xd0},\r
+ {0xdb,0x28},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x43,0x01},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x423,0x02},\r
+ {0xda,0x50},\r
+ {0xdb,0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x43,0x02},\r
+ \r
+ {0xda,0xc0},\r
+ {0xdb,0xc0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x30},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x38},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x40},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x45},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x50},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x58},\r
+ {0xfe, 0x00},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ {0xfe, 0x01},\r
+ {0x13, 0x60},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ {0xb3,0x34},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ {0xb3,0x38},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ {0xb3,0x3d},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ {0xb3,0x40},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ {0xb3,0x44},\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ {0xb3,0x48},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ {0xb3,0x50},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xfe, 0x01},\r
+ {0x33, 0x20},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ {0xfe, 0x01},\r
+ {0x33, 0x30},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ val-=4;\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0){\r
+ err = sensor_write(client, 0x17, ((val |0x1)+4));\r
+ }\r
+ else \r
+ err = sensor_write(client, 0x17, ((val & 0xfe)+4));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ \r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ val-=4;\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0){\r
+ err = sensor_write(client, 0x17, ((val |0x2)+4));\r
+ }\r
+ else {\r
+ err = sensor_write(client, 0x17, ((val & 0xfc)+4));\r
+ }\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
-
+\r
+#include "generic_sensor.h"\r
+\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
- {
- 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);
- }
-
- }
-
-
- return 0;
-}
-#endif
-static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
-{
- struct soc_camera_link *icl = to_soc_camera_link(icd);
- int ret = 0;
-
- SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
- switch (cmd)
- {
- case Sensor_PowerDown:
- {
- if (icl->powerdown) {
- ret = icl->powerdown(icd->pdev, on);
- if (ret == RK29_CAM_IO_SUCCESS) {
- if (on == 0) {
- mdelay(2);
- if (icl->reset)
- icl->reset(icd->pdev);
- }
- } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
- ret = -ENODEV;
- goto sensor_power_end;
- }
- }
- break;
- }
- case Sensor_Flash:
- {
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
- struct sensor *sensor = to_sensor(client);
-
- if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
- sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
- }
- break;
- }
- default:
- {
- SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
- break;
- }
- }
-sensor_power_end:
- return ret;
-}
-
-static int sensor_init(struct v4l2_subdev *sd, u32 val)
-{
- struct i2c_client *client = 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char 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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC0329\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC0329\r
+#define SENSOR_ID 0xc0\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene); \r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ // TODO: add initial code here\r
+ {0xfe, 0x80},\r
+ {0xfc, 0x12}, \r
+ {0xfc, 0x12}, //[4]Clock_en [2] A25_en [1]D18_en [0]Apwdn\r
+ {0xfe, 0x00},\r
+ {0xf0, 0x07}, //vsync_en\r
+ {0xf1, 0x01}, //data_en\r
+ \r
+ {0x73, 0x90}, //R channle gain\r
+ {0x74, 0x80}, //G1 channle gain \r
+ {0x75, 0x80}, //G2 channle gain \r
+ {0x76, 0x94}, //B channle gain \r
+ \r
+ //{0x42, 0x00},\r
+ //{0x77, 0x57},\r
+ //{0x78, 0x4d},\r
+ //{0x79, 0x45},\r
+ //{0x42, 0xfc},\r
+ \r
+ ////////////////////analog////////////////////\r
+ {0xfc, 0x16}, \r
+ \r
+ {0x0a, 0x00}, //row_start_low \r
+ {0x0c, 0x00}, //col_start_low \r
+ {0x17, 0x14}, //cisctl_mode1//[7]hsync_always },[6] NA}, [5:4] CFA sequence [3:2]NA, [1]upside_down, [0] mirror \r
+ //[3:2]NA [1]upside_down}, [0] mirror \r
+ \r
+ {0x19, 0x05}, //cisctl_mode3\r
+ {0x1b, 0x24}, //rsh_width\r
+ {0x1c, 0x04}, //Tsp_width\r
+ {0x1e, 0x00}, //Analog_mode1//[7:6]rsv1},rsv0[5:3] Column bias(coln_r)[1] clk_delay_en\r
+ {0x1f, 0xc0}, //Analog_mode2//[7:6] comv_r\r
+ {0x20, 0x00}, //Analog_mode3//[6:4] cap_low_r for MPW [3:2] da18_r [1] rowclk_mode [0]adclk_mode\r
+ {0x21, 0x48}, //Hrst_rsg//[7] hrst[6:4] da_rsg[3]txhigh_en\r
+ {0x23, 0x22}, //ADC_r//[6:5]opa_r [1:0]sRef\r
+ {0x24, 0x16}, //PAD_drv//[7:6]NA},[5:4]sync_drv [3:2]data_drv [1:0]pclk_drv\r
+ \r
+ \r
+ ////////////////////blk////////////////////\r
+ {0x26, 0xf7}, \r
+ {0x32, 0x04},\r
+ {0x33, 0x20},\r
+ {0x34, 0x20},\r
+ {0x35, 0x20},\r
+ {0x36, 0x20},\r
+ \r
+ ////////////////////ISP BLOCK ENABLE////////////////////\r
+ {0x40, 0xff}, \r
+ {0x41, 0x00},\r
+ {0x42, 0xfe}, \r
+ {0x46, 0x03}, //sync mode\r
+ {0x4b, 0xcb},\r
+ {0x4d, 0x01}, \r
+ {0x4f, 0x01},\r
+ {0x70, 0x48},//global gain\r
+ \r
+ //{0xb0, 0x00},\r
+ //{0xbc, 0x00},\r
+ //{0xbd, 0x00},\r
+ //{0xbe, 0x00},\r
+ \r
+ ////////////////////DNDD////////////////////\r
+ {0x80, 0xe7}, //[7]auto_en [6]one_pixel [5]two_pixel\r
+ {0x82, 0x55}, \r
+ {0x87, 0x4a}, \r
+ \r
+ ////////////////////ASDE////////////////////\r
+ {0xfe, 0x01},\r
+ {0x18, 0x22}, //[7:4]AWB LUMA X [3:0]ASDE LUMA X\r
+ {0xfe, 0x00},//ASDE dn b slope\r
+ {0x9c, 0x0a}, //ASDE dn b slope\r
+ {0xa4, 0x50}, // Auto Sa slope\r
+ {0xa5, 0x21}, // [7:4]Saturation limit x10\r
+ {0xa7, 0x35}, //low luma value th\r
+ {0xdd, 0x54}, //edge dec sat enable & slopes\r
+ {0x95, 0x35}, //Edge effect \r
+ \r
+ ////////////////////RGB gamma////////////////////\r
+ {0xfe, 0x00},\r
+ {0xbf, 0x06},\r
+ {0xc0, 0x14},\r
+ {0xc1, 0x27},\r
+ {0xc2, 0x3b},\r
+ {0xc3, 0x4f},\r
+ {0xc4, 0x62},\r
+ {0xc5, 0x72},\r
+ {0xc6, 0x8d},\r
+ {0xc7, 0xa4},\r
+ {0xc8, 0xb8},\r
+ {0xc9, 0xc9},\r
+ {0xca, 0xd6},\r
+ {0xcb, 0xe0},\r
+ {0xcc, 0xe8},\r
+ {0xcd, 0xf4},\r
+ {0xce, 0xfc},\r
+ {0xcf, 0xff},\r
+ \r
+ //////////////////CC///////////////////\r
+ {0xfe, 0x00},\r
+ {0xb3, 0x44},\r
+ {0xb4, 0xfd},\r
+ {0xb5, 0x02},\r
+ {0xb6, 0xfa},\r
+ {0xb7, 0x48},\r
+ {0xb8, 0xf0},\r
+ \r
+ //skin\r
+ //{0xb3, 0x3c},\r
+ //{0xb4, 0xFF},\r
+ //{0xb5, 0x03},\r
+ //{0xb6, 0x01},\r
+ //{0xb7, 0x3f},\r
+ //{0xb8, 0xF3},\r
+ \r
+ // crop \r
+ {0x50, 0x01},\r
+ {0x19, 0x05},\r
+ {0x20, 0x01},\r
+ {0x22, 0xba},\r
+ {0x21, 0x48},\r
+ \r
+ ////////////////////YCP////////////////////\r
+ {0xfe, 0x00},\r
+ {0xd1, 0x34}, //saturation Cb\r
+ {0xd2, 0x34}, //saturation Cr\r
+ \r
+ ////////////////////AEC////////////////////\r
+ {0xfe, 0x01},\r
+ {0x10, 0x40},\r
+ {0x11, 0x21},//a1\r
+ {0x12, 0x07}, \r
+ {0x13, 0x50}, //Y target\r
+ {0x17, 0x88}, \r
+ {0x21, 0xb0},\r
+ {0x22, 0x48},\r
+ {0x3c, 0x95},\r
+ {0x3d, 0x50},\r
+ {0x3e, 0x48},\r
+ \r
+ ////////////////////AWB////////////////////\r
+ {0xfe, 0x01},\r
+ #if 0\r
+ {0x06, 0x06},\r
+ {0x07, 0x06},\r
+ {0x08, 0xa6},\r
+ {0x09, 0xee},\r
+ {0x50, 0xfc},\r
+ {0x51, 0x28},\r
+ {0x52, 0x10},\r
+ {0x53, 0x1d},\r
+ {0x54, 0x16},\r
+ {0x55, 0x20},\r
+ {0x56, 0x60},\r
+ //{0x57, 0x40}, \r
+ {0x58, 0x60},\r
+ {0x59, 0x28},\r
+ {0x5a, 0x02},\r
+ {0x5b, 0x63},\r
+ {0x5c, 0x34},\r
+ {0x5d, 0x73},\r
+ {0x5e, 0x11},\r
+ {0x5f, 0x40},\r
+ {0x60, 0x40},\r
+ {0x61, 0xc8},\r
+ {0x62, 0xa0},\r
+ {0x63, 0x40},\r
+ {0x64, 0x50},\r
+ {0x65, 0x98},\r
+ {0x66, 0xfa},\r
+ {0x67, 0x70},\r
+ {0x68, 0x58},\r
+ {0x69, 0x85},\r
+ {0x6a, 0x40},\r
+ {0x6b, 0x39},\r
+ {0x6c, 0x40},\r
+ {0x6d, 0x80},\r
+ {0x6e, 0x41},\r
+ {0x70, 0x50},\r
+ {0x71, 0x00},\r
+ {0x72, 0x10},\r
+ {0x73, 0x40},\r
+ {0x74, 0x32},\r
+ {0x75, 0x40},\r
+ {0x76, 0x30},\r
+ {0x77, 0x48},\r
+ {0x7a, 0x50},\r
+ {0x7b, 0x20},\r
+ {0x80, 0x4a},\r
+ {0x81, 0x43},\r
+ {0x82, 0x43},\r
+ {0x83, 0x40},\r
+ {0x84, 0x40},\r
+ {0x85, 0x40},\r
+ #elif 1\r
+ {0x06, 0x08},\r
+ {0x07, 0x06},\r
+ {0x08, 0xa6},\r
+ {0x09, 0xee},\r
+ {0x50,0xfc}, //RGB high\r
+ {0x51,0x28}, //Y2C diff\r
+ {0x52,0x10}, //18\r
+ {0x53,0x08},// //1d //20// \r
+ {0x54,0x12}, //16 //30//C inter\r
+ {0x55,0x10}, //16\r
+ {0x56,0x10}, //20//60\r
+ {0x58,0x80}, //a0//60//number limit X4\r
+ {0x59,0x08}, //0c //08 //AWB adjust temp curve //0c\r
+ {0x5a,0x02}, //01 //03//25//[3:0]light gain range x10\r
+ {0x5b,0x63}, //62\r
+ {0x5c,0x34}, //37 //show and mode [2]big C mode [1]dark mode [0] block move mode\r
+ {0x5d,0x73}, //72 //52//AWB margin\r
+ {0x5e,0x29}, //11 //20 //11 //19//temp curve_enable\r
+ {0x5f,0x40}, //5K gain\r
+ {0x60,0x40}, //5K gain\r
+ {0x61,0xc8}, //sinT\r
+ {0x62,0xa0}, //cosT\r
+ {0x63,0x40}, //38//30//AWB X1 cut\r
+ {0x64,0x38}, //50 //38 //30 //20 //40 //50 //60//AWB X2 cut\r
+ {0x65,0x98}, //a0 //98 //a0//AWB Y1 cut\r
+ {0x66,0xfa}, //ea//AWB Y2 cut\r
+ {0x67,0x80}, //70 //AWB R gain limit\r
+ {0x68,0x60}, //58 //58 //AWB G gain Limit\r
+ {0x69,0x90}, //85 //7d //AWB B gain limit\r
+ {0x6a,0x40},\r
+ {0x6b,0x39},\r
+ {0x6c,0x28}, //40\r
+ {0x6d,0x28}, //40//80\r
+ {0x6e,0x41}, //outdoor gain limit enable [7]use exp or luma value to adjust outdoor \r
+ {0x70,0x10}, //50 //10\r
+ {0x71,0x00}, //when outdoor , add high luma gray pixel weight\r
+ {0x72,0x08}, //10\r
+ {0x73,0x40}, //95// when exp < th, outdoor mode open\r
+ {0x80,0x70}, //R gain high limit\r
+ {0x81,0x58}, //G gain high limit\r
+ {0x82,0x42}, //B gain high limit\r
+ {0x83,0x40}, //R gain low limit\r
+ {0x84,0x40}, //G gain low limit\r
+ {0x85,0x40}, //B gain low limit\r
+ \r
+ #else\r
+ {0x06, 0x06},\r
+ {0x07, 0x06},\r
+ {0x08, 0xa6},\r
+ {0x09, 0xee},\r
+ {0x50, 0xfc},\r
+ {0x51, 0x30},//28\r
+ {0x52, 0x20},//10\r
+ {0x53, 0x0b}, // 1d\r
+ {0x54, 0x0b},// 16\r
+ {0x55, 0x12},//20\r
+ {0x56, 0x10},//60\r
+ //{0x57, 0x40}, \r
+ {0x58, 0x80},//60\r
+ {0x59, 0x28},\r
+ {0x5a, 0x02},\r
+ {0x5b, 0x63},\r
+ {0x5c, 0x37},//34\r
+ {0x5d, 0x72},//73\r
+ {0x5e, 0x11},\r
+ {0x5f, 0x40},\r
+ {0x60, 0x40},\r
+ {0x61, 0xc8},\r
+ {0x62, 0xa0},\r
+ {0x63, 0x40},\r
+ {0x64, 0x60},//50\r
+ {0x65, 0x9c},//98\r
+ {0x66, 0xf0},//fa\r
+ {0x67, 0x70},\r
+ {0x68, 0x58},\r
+ {0x69, 0x85},\r
+ {0x6a, 0x40},\r
+ {0x6b, 0x39},\r
+ {0x6c, 0x40},\r
+ {0x6d, 0x40},//80\r
+ {0x6e, 0x41},\r
+ {0x70, 0x10},//50\r
+ {0x71, 0x00},\r
+ {0x72, 0x20},//10\r
+ {0x73, 0x40},\r
+ {0x74, 0x32},\r
+ {0x75, 0x40},\r
+ {0x76, 0x30},\r
+ {0x77, 0x48},\r
+ {0x7a, 0x50},\r
+ {0x7b, 0x20},\r
+ {0x80, 0x70},//4// 4a\r
+ {0x81, 0x58},//43\r
+ {0x82, 0x42},//43\r
+ {0x83, 0x40},\r
+ {0x84, 0x40},\r
+ {0x85, 0x40},\r
+ \r
+ {0x86, 0x50},\r
+ {0x87, 0x50},\r
+ {0x88, 0xd0},\r
+ {0x88, 0x90},\r
+ #endif\r
+ \r
+ ////////////////////CC-AWB////////////////////\r
+ {0xd0, 0x00},\r
+ {0xd2, 0x2c}, \r
+ {0xd3, 0x80},\r
+ \r
+ ///////////////////ABS///////////////////////\r
+ {0x9c, 0x02},\r
+ {0x9d, 0x10},\r
+ \r
+ ///////////////////LSC //////////////////////\r
+ //// for xuye062d lens setting\r
+ {0xfe, 0x01},\r
+ {0xa0, 0x00},\r
+ {0xa1, 0x3c},\r
+ {0xa2, 0x50},\r
+ {0xa3, 0x00},\r
+ {0xa8, 0x0f},\r
+ {0xa9, 0x08},\r
+ {0xaa, 0x00},\r
+ {0xab, 0x04},\r
+ {0xac, 0x00},\r
+ {0xad, 0x07},\r
+ {0xae, 0x0e},\r
+ {0xaf, 0x00},\r
+ {0xb0, 0x00},\r
+ {0xb1, 0x09},\r
+ {0xb2, 0x00},\r
+ {0xb3, 0x00},\r
+ {0xb4, 0x31},\r
+ {0xb5, 0x19},\r
+ {0xb6, 0x24},\r
+ {0xba, 0x3a},\r
+ {0xbb, 0x24},\r
+ {0xbc, 0x2a},\r
+ {0xc0, 0x17},\r
+ {0xc1, 0x13},\r
+ {0xc2, 0x17},\r
+ {0xc6, 0x21},\r
+ {0xc7, 0x1c},\r
+ {0xc8, 0x1c},\r
+ {0xb7, 0x00},\r
+ {0xb8, 0x00},\r
+ {0xb9, 0x00},\r
+ {0xbd, 0x00},\r
+ {0xbe, 0x00},\r
+ {0xbf, 0x00},\r
+ {0xc3, 0x00},\r
+ {0xc4, 0x00},\r
+ {0xc5, 0x00},\r
+ {0xc9, 0x00},\r
+ {0xca, 0x00},\r
+ {0xcb, 0x00},\r
+ {0xa4, 0x00},\r
+ {0xa5, 0x00},\r
+ {0xa6, 0x00},\r
+ {0xa7, 0x00},\r
+ \r
+ {0xfe, 0x00},\r
+ ////////////////////asde ///////////////////\r
+ {0xa0, 0xaf},\r
+ {0xa2, 0xff},\r
+ \r
+ {0x44, 0xa2}, // YUV order\r
+\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ SensorEnd\r
+\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x77, 0x57},\r
+ {0x78, 0x4d},\r
+ {0x79, 0x45},\r
+ {0x42, 0xfe},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x42, 0xfc},\r
+ {0x77, 0x8c}, //WB_manual_gain \r
+ {0x78, 0x50},\r
+ {0x79, 0x40},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x42, 0xfc},\r
+ {0x77, 0x74}, \r
+ {0x78, 0x52},\r
+ {0x79, 0x40}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x42, 0xfc},\r
+ {0x77, 0x40},\r
+ {0x78, 0x42},\r
+ {0x79, 0x50},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x42, 0xfc},\r
+ {0x77, 0x40},\r
+ {0x78, 0x54},\r
+ {0x79, 0x70},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x40},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x48},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0xf0},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ \r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x50},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0x00},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x58},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0x10},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x60},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0x20},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ \r
+ {0xfe, 0x01}, \r
+ {0x13, 0x68},\r
+ {0xfe, 0x00}, \r
+ {0xd5, 0x30},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x43,0x00}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x43,0x02},\r
+ {0xda,0x00},\r
+ {0xdb,0x00}, \r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x43,0x02},\r
+ {0xda,0xd0},\r
+ {0xdb,0x28}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x43,0x01},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x43,0x02},\r
+ {0xda,0x50},\r
+ {0xdb,0xe0}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x43,0x02},\r
+ {0xda,0xc0},\r
+ {0xdb,0xc0}, \r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Grayscale[]=\r
+{\r
+ {0x23,0x02}, \r
+ {0x2d,0x0a},\r
+ {0x20,0xff},\r
+ {0xd2,0x90},\r
+ {0x73,0x00},\r
+\r
+ {0xb3,0x40},\r
+ {0xb4,0x80},\r
+ {0xba,0x00},\r
+ {0xbb,0x00},\r
+ {0x00,0x00}\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ //-3\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ //-2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ //-1\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ //default\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ // 1\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ // 2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ // 3\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xfe, 0x01},\r
+ {0x33, 0x20},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ {0xfe, 0x01},\r
+ {0x33, 0x30},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ char pid = 0;\r
+ int ret = 0;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ /* check if it is an sensor sensor */\r
+ ret = sensor_write(client, 0xfc, 0x16); //before read id should write 0xfc\r
+ msleep(20);\r
+ ret = sensor_read(client, 0x00, &pid);\r
+ if (ret != 0) {\r
+ SENSOR_TR("%s read chip id high byte failed\n",SENSOR_NAME_STRING());\r
+ ret = -ENODEV;\r
+ }\r
+ SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ if (pid == SENSOR_ID) {\r
+ sensor->model = SENSOR_V4L2_IDENT;\r
+ } else {\r
+ SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ ret = -ENODEV;\r
+ }\r
+ return pid;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0)\r
+ err = sensor_write(client, 0x17, (val |0x1));\r
+ else \r
+ err = sensor_write(client, 0x17, (val & 0xfe));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0)\r
+ err = sensor_write(client, 0x17, (val |0x2));\r
+ else \r
+ err = sensor_write(client, 0x17, (val & 0xfc));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
+ {
+ 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);
+ }
+
+ }
+
+
+ return 0;
+}
+#endif
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)
+{
+ struct soc_camera_link *icl = to_soc_camera_link(icd);
+ int ret = 0;
+
+ SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
+ switch (cmd)
+ {
+ case Sensor_PowerDown:
+ {
+ if (icl->powerdown) {
+ ret = icl->powerdown(icd->pdev, on);
+ if (ret == RK29_CAM_IO_SUCCESS) {
+ if (on == 0) {
+ mdelay(2);
+ if (icl->reset)
+ icl->reset(icd->pdev);
+ }
+ } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {
+ ret = -ENODEV;
+ goto sensor_power_end;
+ }
+ }
+ break;
+ }
+ case Sensor_Flash:
+ {
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+ struct sensor *sensor = to_sensor(client);
+
+ if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {
+ sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);
+ }
+ break;
+ }
+ default:
+ {
+ SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
+ break;
+ }
+ }
+sensor_power_end:
+ return ret;
+}
+
+static int sensor_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct i2c_client *client = 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char 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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
+\r
+#include "generic_sensor.h"\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
-
-
-#define _CONS(a,b) a##b
-#define CONS(a,b) _CONS(a,b)
-
-#define __STR(x) #x
-#define _STR(x) __STR(x)
-#define STR(x) _STR(x)
-
-#define MIN(x,y) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? x: y)
-
-/* Sensor Driver Configuration */
-#define SENSOR_NAME RK29_CAM_SENSOR_GC2015
-#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015
-#define SENSOR_ID 0x2005
-#define SENSOR_MIN_WIDTH 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char value;
- int ret,pid=0;
- struct sensor *sensor = to_sensor(client);
-
- /* We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant. */
- if (!icd->dev.parent ||
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
- return -ENODEV;
-
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- /* soft reset */
- ret = sensor_write(client, 0xfe, 0x80);
- if (ret != 0)
- {
- SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
- return -ENODEV;
- }
- mdelay(5); //delay 5 microseconds
-
- /* check if it is an sensor sensor */
- ret = sensor_read(client, 0x00, &value);
- if (ret != 0) {
- SENSOR_TR("read chip id high byte failed\n");
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- pid |= (value << 8);
-
- ret = sensor_read(client, 0x01, &value);
- if (ret != 0) {
- SENSOR_TR("read chip id low byte failed\n");
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- pid |= (value & 0xff);
- SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
- if (pid == SENSOR_ID) {
- sensor->model = SENSOR_V4L2_IDENT;
- } else {
- SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC2015\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015\r
+#define SENSOR_ID 0x2005\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+ u16 shutter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0xfe, 0x80}, //soft reset\r
+ {0xfe, 0x80}, //soft reset\r
+ {0xfe, 0x80}, //soft reset\r
+ \r
+ {0xfe, 0x00}, //page0\r
+ {0x45, 0x00}, //output_disable\r
+ \r
+ //////////////////////////////////////////////////////////////////////////////////////\r
+ //////////////////////////preview capture switch /////////////////////////////////////\r
+ //////////////////////////////////////////////////////////////////////////////////////\r
+ //preview\r
+ {0x02, 0x01}, //preview mode\r
+ {0x2a, 0xca}, //[7]col_binning, 0x[6]even skip\r
+ {0x48, 0x40}, //manual_gain\r
+ \r
+ ////////////////////////////////////////////////////////////////////////\r
+ ////////////////////////// preview LSC /////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////////\r
+ {0xfe, 0x01}, //page1\r
+ {0xb0, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select\r
+ {0xb1, 0x46}, //P_LSC_red_b2\r
+ {0xb2, 0x40}, //P_LSC_green_b2\r
+ {0xb3, 0x40}, //P_LSC_blue_b2\r
+ {0xb4, 0x24}, //P_LSC_red_b4\r
+ {0xb5, 0x20}, //P_LSC_green_b4\r
+ {0xb6, 0x22}, //P_LSC_blue_b4\r
+ {0xb7, 0x00}, //P_LSC_compensate_b2\r
+ {0xb8, 0x80}, //P_LSC_row_center, 0x344, 0x (1200/2-344)/2=128, 0x, 0x\r
+ {0xb9, 0x80}, //P_LSC_col_center, 0x544, 0x (1600/2-544)/2=128\r
+ \r
+ \r
+ ////////////////////////////////////////////////////////////////////////\r
+ ////////////////////////// capture LSC /////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////////\r
+ {0xba, 0x03}, //[4]Y_LSC_en [3]lsc_compensate [2]signed_b4 [1:0]pixel array select\r
+ {0xbb, 0x46}, //C_LSC_red_b2\r
+ {0xbc, 0x40}, //C_LSC_green_b2\r
+ {0xbd, 0x40}, //C_LSC_blue_b2\r
+ {0xbe, 0x24}, //C_LSC_red_b4\r
+ {0xbf, 0x20}, //C_LSC_green_b4\r
+ {0xc0, 0x22}, //C_LSC_blue_b4\r
+ {0xc1, 0x00}, //C_Lsc_compensate_b2\r
+ {0xc2, 0x80}, //C_LSC_row_center, 0x344, 0x (1200/2-344)/2=128\r
+ {0xc3, 0x80}, //C_LSC_col_center, 0x544, 0x (1600/2-544)/2=128\r
+ {0xfe, 0x00}, //page0\r
+ \r
+ ////////////////////////////////////////////////////////////////////////\r
+ ////////////////////////// analog configure ///////////////////////////\r
+ ////////////////////////////////////////////////////////////////////////\r
+ {0xfe, 0x00}, //page0\r
+ {0x29, 0x00}, //cisctl mode 1\r
+ {0x2b, 0x06}, //cisctl mode 3 \r
+ {0x32, 0x1c}, //analog mode 1\r
+ {0x33, 0x0f}, //analog mode 2\r
+ {0x34, 0x30}, //[6:4]da_rsg\r
+ \r
+ {0x35, 0x88}, //Vref_A25\r
+ {0x37, 0x16}, //Drive Current\r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// ISP Related /////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0x40, 0xff}, \r
+ {0x41, 0x20}, //[5]skin_detectionenable[2]auto_gray, 0x[1]y_gamma\r
+ {0x42, 0xf6}, //[7]auto_sa[6]auto_ee[5]auto_dndd[4]auto_lsc[3]na[2]abs, 0x[1]awb\r
+ {0x4b, 0xe8}, //[1]AWB_gain_mode, 0x1:atpregain0:atpostgain\r
+ {0x4d, 0x03}, //[1]inbf_en\r
+ {0x4f, 0x01}, //AEC enable\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// BLK //////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x63, 0x77}, //BLK mode 1\r
+ {0x66, 0x00}, //BLK global offset\r
+ {0x6d, 0x00},\r
+ {0x6e, 0x1a}, //BLK offset submode,offset R\r
+ {0x6f, 0x20},\r
+ {0x70, 0x1a},\r
+ {0x71, 0x20},\r
+ {0x73, 0x00},\r
+ {0x77, 0x80},\r
+ {0x78, 0x80},\r
+ {0x79, 0x90},\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// DNDD ///////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x80, 0x07}, //[7]dn_inc_or_dec [4]zero_weight_mode[3]share [2]c_weight_adap [1]dn_lsc_mode [0]dn_b\r
+ {0x82, 0x0c}, //DN lilat b base\r
+ {0x83, 0x03},\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// EEINTP ////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x8a, 0x7c},\r
+ {0x8c, 0x02},\r
+ {0x8e, 0x02},\r
+ {0x8f, 0x45},\r
+ \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// CC_t ////////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0xb0, 0x40}, // 0x48\r
+ {0xb1, 0xfe},\r
+ {0xb2, 0x00},\r
+ {0xb3, 0xf0},\r
+ {0xb4, 0x50},\r
+ {0xb5, 0xf8},\r
+ {0xb6, 0x00},\r
+ {0xb7, 0x00},\r
+ {0xb8, 0x00},\r
+ \r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// GAMMA ///////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ //RGB_GAMMA\r
+ {0xbf, 0x08}, \r
+ {0xc0, 0x1e},\r
+ {0xc1, 0x33},\r
+ {0xc2, 0x47},\r
+ {0xc3, 0x59},\r
+ {0xc4, 0x68},\r
+ {0xc5, 0x74},\r
+ {0xc6, 0x86},\r
+ {0xc7, 0x97},\r
+ {0xc8, 0xA5},\r
+ {0xc9, 0xB1},\r
+ {0xca, 0xBd},\r
+ {0xcb, 0xC8},\r
+ {0xcc, 0xD3},\r
+ {0xcd, 0xE4},\r
+ {0xce, 0xF4},\r
+ {0xcf, 0xff},\r
+ \r
+ /*{0xbf, 0x06},\r
+ {0xc0, 0x1f},\r
+ {0xc1, 0x38},\r
+ {0xc2, 0x4c},\r
+ {0xc3, 0x5b},\r
+ {0xc4, 0x6b},\r
+ {0xc5, 0x76},\r
+ {0xc6, 0x8b},\r
+ {0xc7, 0x9b},\r
+ {0xc8, 0xac},\r
+ {0xc9, 0xbb},\r
+ {0xca, 0xc7},\r
+ {0xcb, 0xd2},\r
+ {0xcc, 0xdb},\r
+ {0xcd, 0xea},\r
+ {0xce, 0xf5},\r
+ {0xcf, 0xff}, */\r
+ \r
+ /////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// YCP_t ///////////////////////////////////\r
+ /////////////////////////////////////////////////////////////////////\r
+ {0xd1, 0x40}, //saturation 38\r
+ {0xd2, 0x40}, //saturation 38\r
+ \r
+ {0xd3, 0x46}, // 2011-08-11 kim add\r
+ \r
+ {0xde, 0x21}, //auto_gray\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// ASDE ///////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x98, 0x3a}, \r
+ {0x99, 0x60}, \r
+ {0x9b, 0x00}, \r
+ {0x9f, 0x12}, \r
+ {0xa1, 0x80}, \r
+ {0xa2, 0x21}, \r
+ \r
+ {0xfe, 0x01}, //page1\r
+ {0xc5, 0x10}, \r
+ {0xc6, 0xff}, \r
+ {0xc7, 0xff}, \r
+ {0xc8, 0xff}, \r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// AEC ////////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x10, 0x09}, //AEC mode 1\r
+ {0x11, 0x92}, //[7]fix target // 0xb2 2011-08-11 kim \r
+ {0x12, 0x20}, \r
+ {0x13, 0x78}, // 0x78 2011-08-11 kim \r
+ {0x17, 0x00}, \r
+ {0x1c, 0x96}, \r
+ {0x1d, 0x04}, // sunlight step \r
+ {0x1e, 0x11}, \r
+ {0x21, 0xc0}, //max_post_gain\r
+ {0x22, 0x40}, //max_pre_gain // 0x60 2011-08-11 kim \r
+ {0x2d, 0x06}, //P_N_AEC_exp_level_1[12:8]\r
+ {0x2e, 0x00}, //P_N_AEC_exp_level_1[7:0]\r
+ {0x1e, 0x32}, \r
+ {0x33, 0x00}, //[6:5]max_exp_level [4:0]min_exp_level\r
+ {0x34, 0x04}, // min exp\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// Measure Window /////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x06, 0x07},\r
+ {0x07, 0x03},\r
+ {0x08, 0x64},\r
+ {0x09, 0x4a},\r
+ \r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// AWB ////////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x57, 0x40}, //number limit\r
+ {0x5d, 0x44}, //\r
+ {0x5c, 0x35}, //show mode,close dark_mode\r
+ {0x5e, 0x29}, //close color temp\r
+ {0x5f, 0x50},\r
+ {0x60, 0x50}, \r
+ {0x65, 0xc0},\r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// ABS ////////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0x80, 0x82},\r
+ {0x81, 0x00},\r
+ \r
+ {0x82, 0x03}, /// \r
+ \r
+ {0x83, 0x10}, //ABS Y stretch limit\r
+ {0xfe, 0x00},\r
+ ////////////////////////////////////////////////////////////////////\r
+ /////////////////////////// OUT ////////////////////////////////////\r
+ ////////////////////////////////////////////////////////////////////\r
+ {0xfe, 0x00},\r
+ //crop \r
+ {0x50, 0x01},\r
+ {0x51, 0x00},\r
+ {0x52, 0x00},\r
+ {0x53, 0x00},\r
+ {0x54, 0x00},\r
+ {0x55, 0x02},\r
+ {0x56, 0x58},\r
+ {0x57, 0x03},\r
+ {0x58, 0x20},\r
+ \r
+ {0x44, 0xa0}, //YUV sequence\r
+ {0x45, 0x0f}, //output enable\r
+ {0x46, 0x02}, //sync mode\r
+ \r
+ /* {0xbF, 0x0B}, \r
+ {0xc0, 0x16}, \r
+ {0xc1, 0x29}, \r
+ {0xc2, 0x3C}, \r
+ {0xc3, 0x4F}, \r
+ {0xc4, 0x5F}, \r
+ {0xc5, 0x6F}, \r
+ {0xc6, 0x8A}, \r
+ {0xc7, 0x9F}, \r
+ {0xc8, 0xB4}, \r
+ {0xc9, 0xC6}, \r
+ {0xcA, 0xD3}, \r
+ {0xcB, 0xDD}, \r
+ {0xcC, 0xE5}, \r
+ {0xcD, 0xF1}, \r
+ {0xcE, 0xFA}, \r
+ {0xcF, 0xFF},*/\r
+ \r
+ {0x05, 0x01},//HB\r
+ {0x06, 0xc1},\r
+ {0x07, 0x00},//VB\r
+ {0x08, 0x40},\r
+ \r
+ {0xfe, 0x01},\r
+ {0x29, 0x00},//Anti Step 128\r
+ {0x2a, 0x80},\r
+ \r
+ {0x2b, 0x05},//Level_0 10.00fps\r
+ {0x2c, 0x00},\r
+ {0x2d, 0x06},//Level_1 8.33fps\r
+ {0x2e, 0x00},\r
+ {0x2f, 0x08},//Level_2 6.25fps\r
+ {0x30, 0x00},\r
+ {0x31, 0x09},//Level_3 5.55fps\r
+ {0x32, 0x00},\r
+ {0x33, 0x20},\r
+ {0xfe, 0x00},\r
+ \r
+ //--------------------Updated By Mormo 2011/08/08 Start --------------------//\r
+ {0xfe, 0x00},\r
+ {0x32, 0x34},\r
+ {0x34, 0x00},\r
+ //--------------------Updated By Mormo 2011/08/08 End ---------------------// \r
+ {0x7d, 0x80}, //\r
+ {0x7e, 0x80},\r
+ {0x7f, 0x84},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ {0xfe, 0x00},\r
+ \r
+ {0x48, 0x80}, // 68\r
+ \r
+ {0x4f, 0x00}, // aec off\r
+ \r
+ {0x02, 0x00},\r
+ {0x2a, 0x0a},\r
+ \r
+ //subsample 1/1\r
+ {0x59, 0x11},\r
+ {0x5a, 0x06},\r
+ {0x5b, 0x00},\r
+ {0x5c, 0x00},\r
+ {0x5d, 0x00},\r
+ {0x5e , 0x00},\r
+ {0x5f, 0x00},\r
+ {0x60, 0x00},\r
+ {0x61, 0x00},\r
+ {0x62, 0x00},\r
+ \r
+ //crop \r
+ {0x50, 0x01},\r
+ {0x51, 0x00},\r
+ {0x52, 0x00},\r
+ {0x53, 0x00},\r
+ {0x54, 0x00},\r
+ {0x55, 0x04},\r
+ {0x56, 0xb0},\r
+ {0x57, 0x06},\r
+ {0x58, 0x40},\r
+ SensorEnd\r
+\r
+};\r
+\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0xfe, 0x00},\r
+ \r
+ {0x48, 0x40},\r
+ {0x4f, 0x01}, // aec on\r
+ \r
+ {0x02, 0x01},\r
+ {0x2a, 0xca},\r
+ \r
+ //subsample 1/1\r
+ {0x59, 0x11},\r
+ {0x5a, 0x06},\r
+ {0x5b, 0x00},\r
+ {0x5c, 0x00},\r
+ {0x5d, 0x00},\r
+ {0x5e , 0x00},\r
+ {0x5f, 0x00},\r
+ {0x60, 0x00},\r
+ {0x61, 0x00},\r
+ {0x62, 0x00},\r
+ \r
+ {0x50 , 0x01},//out window\r
+ {0x51 , 0x00},\r
+ {0x52 , 0x00},\r
+ {0x53 , 0x00},\r
+ {0x54 , 0x00},\r
+ {0x55 , 0x02},\r
+ {0x56 , 0x58},// 600\r
+ {0x57 , 0x03},\r
+ {0x58 , 0x20},//800\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0xfe,80),\r
+ SensorWaitMs(5),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x00,0),\r
+ SensorRegVal(0x01,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x42,0x76},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF \r
+ {0x7a , 0x8c}, //AWB_R_gain\r
+ {0x7b , 0x50}, //AWB_G_gain\r
+ {0x7c , 0x40}, //AWB_B_gain\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny \r
+ {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF \r
+ {0x7a , 0x74}, //AWB_R_gain\r
+ {0x7b , 0x52}, //AWB_G_gain\r
+ {0x7c , 0x40}, //AWB_B_gain\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF \r
+ {0x7a , 0x48}, //AWB_R_gain\r
+ {0x7b , 0x40}, //AWB_G_gain\r
+ {0x7c , 0x5c}, //AWB_B_gain \r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x42 , 0x74},// [1] AWB enable ¹¦ÄÜ¿ª¹ØAWB OFF \r
+ {0x7a , 0x40}, //AWB_R_gain\r
+ {0x7b , 0x54}, //AWB_G_gain\r
+ {0x7c , 0x70}, //AWB_B_gain\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ \r
+ {0xfe, 0x01},\r
+ {0x13, 0x68}, //AEC_target_Y \r
+ {0xfe, 0x00},\r
+ {0xd5, 0xe0},// Luma_offset \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ {0xfe, 0x01},\r
+ {0x13, 0x70}, //AEC_target_Y \r
+ {0xfe, 0x00},\r
+ {0xd5, 0xf0},// Luma_offset \r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ \r
+ {0xfe, 0x01},\r
+ {0x13, 0x78}, //AEC_target_Y 48\r
+ {0xfe, 0x00},\r
+ {0xd5, 0x00},// Luma_offset c0\r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0xfe, 0x01},\r
+ {0x13, 0x80}, //AEC_target_Y \r
+ {0xfe, 0x00},\r
+ {0xd5, 0x10},// Luma_offset \r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0xfe, 0x01},\r
+ {0x13, 0x88}, //AEC_target_Y \r
+ {0xfe, 0x00},\r
+ {0xd5, 0x20},// Luma_offset \r
+ \r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0xfe, 0x01},\r
+ {0x13, 0x90}, //AEC_target_Y \r
+ {0xfe, 0x00},\r
+ {0xd5, 0x30},// Luma_offset \r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x43, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x43, 0x02},\r
+ {0xda, 0x50},\r
+ {0xdb, 0xe0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x43, 0x02},\r
+ {0xda, 0xd0},\r
+ {0xdb, 0x28},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x43, 0x01},\r
+ //{0xda, 0xc0},\r
+ //{0xdb, 0xc0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x43, 0x02},\r
+ {0xda, 0x00},\r
+ {0xdb, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x43, 0x02},\r
+ {0xda, 0xc0},\r
+ {0xdb, 0xc0},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ //Contrast -3\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x2c}, \r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ //Contrast -2\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x30},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ // Contrast -1\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x38},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ //Contrast 0\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x40},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ //Contrast +1\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x48},\r
+\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ //Contrast +2\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x50},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ //Contrast +3\r
+ {0xfe, 0x00}, \r
+ {0xd3, 0x58},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xfe, 0x01},\r
+ {0x33, 0x00},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk\r
+ {0xfe, 0x01},\r
+ {0x33, 0x20},\r
+ {0xfe, 0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+static u16 GC2015_read_shutter(struct i2c_client *client); // add 2011-08-11 kim\r
+static void GC2015_set_shutter(struct i2c_client *client, u16 shutter); // add 2011-08-11 kim\r
+\r
+\r
+////// add 2011-08-11 kim\r
+static u16 GC2015_read_shutter(struct i2c_client *client)\r
+{\r
+ u8 temp_reg1, temp_reg2;\r
+ u16 shutter;\r
+ \r
+ /* Backup the preview mode last shutter & sensor gain. */\r
+ sensor_read(client, 0x03, &temp_reg1);\r
+ sensor_read(client, 0x04, &temp_reg2);\r
+ \r
+ shutter = (temp_reg1 << 8) | (temp_reg2 & 0xFF);\r
+ \r
+ return shutter;\r
+} /* GC2015_read_shutter */\r
+\r
+static void GC2015_set_shutter(struct i2c_client *client, u16 shutter)\r
+{\r
+ u16 temp_reg;\r
+\r
+ temp_reg = shutter * 10 / 20; //// \r
+\r
+ /*Set Shutter start*/\r
+ if(temp_reg < 1) temp_reg = 1;\r
+ sensor_write(client ,0x03 , (temp_reg>>8)&0xff); \r
+ sensor_write(client ,0x04 , temp_reg&0xff); \r
+ /*Set Shutter end*/\r
+} \r
+//////// end add kim \r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+ spsensor->shutter= GC2015_read_shutter(client); // add 2011-08-11 kim\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+ if(mf->width >=1024)\r
+ GC2015_set_shutter(client, spsensor->shutter); // add 2011-08-11 kim\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x29, &val);\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0)\r
+ err = sensor_write(client, 0x29, (val |0x1));\r
+ else \r
+ err = sensor_write(client, 0x29, (val & 0xfe));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ \r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x29, &val);\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0)\r
+ err = sensor_write(client, 0x29, (val |0x2));\r
+ else \r
+ err = sensor_write(client, 0x29, (val & 0xfc));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos) {\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
+
+
+#define _CONS(a,b) a##b
+#define CONS(a,b) _CONS(a,b)
+
+#define __STR(x) #x
+#define _STR(x) __STR(x)
+#define STR(x) _STR(x)
+
+#define MIN(x,y) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? x: y)
+
+/* Sensor Driver Configuration */
+#define SENSOR_NAME RK29_CAM_SENSOR_GC2015
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2015
+#define SENSOR_ID 0x2005
+#define SENSOR_MIN_WIDTH 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char value;
+ int ret,pid=0;
+ struct sensor *sensor = to_sensor(client);
+
+ /* We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant. */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+ return -ENODEV;
+
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ /* soft reset */
+ ret = sensor_write(client, 0xfe, 0x80);
+ if (ret != 0)
+ {
+ SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
+ return -ENODEV;
+ }
+ mdelay(5); //delay 5 microseconds
+
+ /* check if it is an sensor sensor */
+ ret = sensor_read(client, 0x00, &value);
+ if (ret != 0) {
+ SENSOR_TR("read chip id high byte failed\n");
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ pid |= (value << 8);
+
+ ret = sensor_read(client, 0x01, &value);
+ if (ret != 0) {
+ SENSOR_TR("read chip id low byte failed\n");
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ pid |= (value & 0xff);
+ SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+ if (pid == SENSOR_ID) {
+ sensor->model = SENSOR_V4L2_IDENT;
+ } else {
+ SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
-/*\r
-o* Driver for MT9M001 CMOS Image Sensor from Micron\r
- *\r
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License version 2 as\r
- * published by the Free Software Foundation.\r
- */\r
-\r
-#include <linux/videodev2.h>\r
-#include <linux/slab.h>\r
-#include <linux/i2c.h>\r
-#include <linux/log2.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/delay.h>\r
-#include <linux/circ_buf.h>\r
-#include <linux/miscdevice.h>\r
-#include <media/v4l2-common.h>\r
-#include <media/v4l2-chip-ident.h>\r
-#include <media/soc_camera.h>\r
-#include <plat/rk_camera.h>\r
+\r
+#include "generic_sensor.h"\r
+\r
+/*
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
\r
static int debug;\r
module_param(debug, int, S_IRUGO|S_IWUSR);\r
if (debug >= level) \\r
printk(KERN_WARNING fmt , ## arg); } while (0)\r
\r
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)\r
-#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)\r
-\r
-\r
-#define _CONS(a,b) a##b\r
-#define CONS(a,b) _CONS(a,b)\r
-\r
-#define __STR(x) #x\r
-#define _STR(x) __STR(x)\r
-#define STR(x) _STR(x)\r
-\r
-#define MIN(x,y) ((x<y) ? x: y)\r
-#define MAX(x,y) ((x>y) ? x: y)\r
-\r
-/* Sensor Driver Configuration */\r
+/* Sensor Driver Configuration Begin */\r
#define SENSOR_NAME RK29_CAM_SENSOR_GC2035\r
-#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035\r
#define SENSOR_ID 0x2035\r
-#define SENSOR_MIN_WIDTH 800\r
-#define SENSOR_MIN_HEIGHT 600\r
-#define SENSOR_MAX_WIDTH 1600\r
-#define SENSOR_MAX_HEIGHT 1200\r
-#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */\r
-#define SENSOR_INIT_HEIGHT 600\r
-#define SENSOR_INIT_WINSEQADR sensor_svga\r
-#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8\r
-\r
-#define CONFIG_SENSOR_WhiteBalance 1\r
-#define CONFIG_SENSOR_Brightness 0\r
-#define CONFIG_SENSOR_Contrast 0\r
-#define CONFIG_SENSOR_Saturation 0\r
-#define CONFIG_SENSOR_Effect 1\r
-#define CONFIG_SENSOR_Scene 1\r
-#define CONFIG_SENSOR_DigitalZoom 0\r
-#define CONFIG_SENSOR_Focus 0\r
-#define CONFIG_SENSOR_Exposure 0\r
-#define CONFIG_SENSOR_Flash 1\r
-#define CONFIG_SENSOR_Mirror 0\r
-#define CONFIG_SENSOR_Flip 0\r
-\r
-#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */\r
-/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */\r
-#define CONFIG_SENSOR_I2C_NOSCHED 0\r
-#define CONFIG_SENSOR_I2C_RDWRCHK 0\r
-\r
-#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\\r
- SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\\r
- SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
-\r
-#define COLOR_TEMPERATURE_CLOUDY_DN 6500\r
-#define COLOR_TEMPERATURE_CLOUDY_UP 8000\r
-#define COLOR_TEMPERATURE_CLEARDAY_DN 5000\r
-#define COLOR_TEMPERATURE_CLEARDAY_UP 6500\r
-#define COLOR_TEMPERATURE_OFFICE_DN 3500\r
-#define COLOR_TEMPERATURE_OFFICE_UP 5000\r
-#define COLOR_TEMPERATURE_HOME_DN 2500\r
-#define COLOR_TEMPERATURE_HOME_UP 3500\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
\r
#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
\r
-#define SENSOR_AF_IS_ERR (0x00<<0)\r
-#define SENSOR_AF_IS_OK (0x01<<0)\r
-#define SENSOR_INIT_IS_ERR (0x00<<28)\r
-#define SENSOR_INIT_IS_OK (0x01<<28)\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
\r
-struct reginfo\r
+struct sensor_parameter\r
{\r
- u8 reg;\r
- u8 val;\r
-};\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
\r
-//flash off in fixed time to prevent from too hot , zyc\r
-struct flash_timer{\r
- struct soc_camera_device *icd;\r
- struct hrtimer timer;\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
};\r
-static enum hrtimer_restart flash_off_func(struct hrtimer *timer);\r
\r
-static struct flash_timer flash_off_timer;\r
-//for user defined if user want to customize the series , zyc\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+ u16 shutter;\r
+\r
+};\r
\r
-/* init 352X288 SVGA */\r
-static struct reginfo sensor_init_data[] ={\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] =\r
+{\r
{0xfe , 0x80},\r
{0xfe , 0x80},\r
{0xfe , 0x80}, \r
{0x47 , 0x09},\r
\r
#endif\r
-\r
- {0x00,0x00}, \r
+ SensorEnd\r
};\r
- \r
-\r
-\r
-/* 1600X1200 UXGA */\r
-static struct reginfo sensor_uxga[] = \r
-{\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
\r
\r
{0xfe , 0x00},\r
{0x97 , 0x06},\r
{0x98 , 0x40},\r
\r
- {0x00 , 0x00}, \r
+ SensorEnd \r
\r
\r
};\r
\r
- \r
-\r
-/* 1280X1024 SXGA */\r
-static struct reginfo sensor_sxga[] =\r
-{\r
- \r
- {0x00,0x00}, \r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
};\r
-\r
-/* 800X600 SVGA*/\r
-static struct reginfo sensor_svga[] =\r
-{ \r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
{0xfe , 0x00},\r
{0xb6 , 0x03},\r
{0xf7 , 0x15},\r
{0x96 , 0x58},\r
{0x97 , 0x03},\r
{0x98 , 0x20},\r
- {0x00,0x00}, \r
+ SensorEnd\r
};\r
- \r
- \r
-\r
-/* 640X480 VGA */\r
-static struct reginfo sensor_vga[] =\r
-{\r
- \r
-\r
- {0x00 , 0x00},\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
};\r
\r
-/* 352X288 CIF */\r
-static struct reginfo sensor_cif[] =\r
-{\r
- {0x00,0x00}, \r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
};\r
\r
-/* 320*240 QVGA */\r
-static struct reginfo sensor_qvga[] =\r
-{\r
- \r
\r
- {0x00,0x00}, \r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0xfe,80),\r
+ SensorWaitMs(5),\r
+ SensorEnd\r
};\r
\r
-/* 176X144 QCIF*/\r
-static struct reginfo sensor_qcif[] =\r
-{\r
- \r
- {0x00,0x00}, \r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0xf0,0),\r
+ SensorRegVal(0xf1,0),\r
+ SensorEnd\r
};\r
-\r
-static struct reginfo sensor_ClrFmt_YUYV[]=\r
-{\r
- \r
- {0x00,0x00}, \r
-};\r
-\r
-static struct reginfo sensor_ClrFmt_UYVY[]=\r
-{\r
- {0x00,0x00}, \r
-};\r
-\r
-#if CONFIG_SENSOR_WhiteBalance\r
-static struct reginfo sensor_WhiteB_Auto[]=\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
{\r
- {0xfe, 0x00},\r
{0xb3, 0x61},\r
{0xb4, 0x40},\r
{0xb5, 0x61},\r
{0x82, 0xfe},\r
- {0x00,0x00}, \r
+ SensorEnd\r
};\r
/* Cloudy Colour Temperature : 6500K - 8000K */\r
-static struct reginfo sensor_WhiteB_Cloudy[]=\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
{\r
- {0xfe, 0x00},\r
{0x82, 0xfc},\r
{0xb3, 0x58},\r
{0xb4, 0x40},\r
{0xb5, 0x50}, \r
- {0x00,0x00}, \r
+ SensorEnd\r
};\r
-/* ClearDay Colour Temperature : 5000K - 6500K */\r
-static struct reginfo sensor_WhiteB_ClearDay[]=\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
{\r
- //Sunny\r
- {0xfe, 0x00},\r
- {0x82, 0xfc},\r
- {0xb3, 0x78},\r
- {0xb4, 0x40},\r
- {0xb5, 0x50},\r
- {0x00,0x00}, \r
+ //Sunny\r
+ {0x82, 0xfc},\r
+ {0xb3, 0x58},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0x50},\r
+ SensorEnd\r
};\r
/* Office Colour Temperature : 3500K - 5000K */\r
-static struct reginfo sensor_WhiteB_TungstenLamp1[]=\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
{\r
- //Office\r
- {0xfe, 0x00},\r
- {0x82, 0xfc},\r
- {0xb3, 0x50},\r
- {0xb4, 0x40},\r
- {0xb5, 0xa8},\r
- {0x00,0x00}, \r
+ //Office\r
+ {0x82, 0xfc},\r
+ {0xb3, 0x50},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0xa8},\r
+ SensorEnd\r
\r
};\r
-/* Home Colour Temperature : 2500K - 3500K */\r
-static struct reginfo sensor_WhiteB_TungstenLamp2[]=\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
{\r
- //Home\r
- {0xfe, 0x00},\r
- {0x82, 0xfc},\r
- {0xb3, 0xa0},\r
- {0xb4, 0x45},\r
- {0xb5, 0x40},\r
- {0x00, 0x00}, \r
+ //Home\r
+ {0x82, 0xfc},\r
+ {0xb3, 0xa0},\r
+ {0xb4, 0x45},\r
+ {0xb5, 0x40},\r
+ SensorEnd\r
};\r
-static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
- sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
};\r
-#endif\r
\r
-#if CONFIG_SENSOR_Brightness\r
-static struct reginfo sensor_Brightness0[]=\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
{\r
- // Brightness -2\r
- \r
+ // Brightness -2\r
+ \r
{0xfe, 0x01},\r
- {0x13, 0x70},\r
+ {0x13, 0x40},\r
{0xfe, 0x02},\r
{0xd5, 0xe0},\r
- {0x00, 0x00},\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Brightness1[]=\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
{\r
- // Brightness -1\r
- \r
+ // Brightness -1\r
+ \r
{0xfe, 0x01},\r
- {0x13, 0x78},\r
+ {0x13, 0x48},\r
{0xfe, 0x02},\r
{0xd5, 0xf0},\r
- {0x00, 0x00}\r
+ \r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Brightness2[]=\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
{\r
- // Brightness 0\r
-\r
+ // Brightness 0\r
+ \r
{0xfe, 0x01},\r
- {0x13, 0x80},\r
+ {0x13, 0x58},\r
{0xfe, 0x02},\r
{0xd5, 0x00},\r
- {0x00, 0x00}\r
+ \r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Brightness3[]=\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
{\r
- // Brightness +1\r
+ // Brightness +1\r
{0xfe, 0x01},\r
- {0x13, 0x88},\r
+ {0x13, 0x60},\r
{0xfe, 0x02},\r
{0xd5, 0x10},\r
- {0x00, 0x00}\r
+ \r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Brightness4[]=\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
{\r
- // Brightness +2\r
+ // Brightness +2\r
{0xfe, 0x01},\r
- {0x13, 0x90},\r
+ {0x13, 0x68},\r
{0xfe, 0x02},\r
{0xd5, 0x20},\r
- {0x00, 0x00}\r
+\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Brightness5[]=\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
{\r
- // Brightness +3\r
+ // Brightness +3\r
{0xfe, 0x01},\r
- {0x13, 0x98},\r
+ {0x13, 0x78},\r
{0xfe, 0x02},\r
{0xd5, 0x30},\r
\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
-static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
- sensor_Brightness4, sensor_Brightness5,NULL,\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
};\r
\r
-#endif\r
-\r
-#if CONFIG_SENSOR_Effect\r
-static struct reginfo sensor_Effect_Normal[] =\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
{\r
{0xfe, 0x00},\r
{0x83, 0xe0},\r
- {0x00, 0x00} \r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Effect_WandB[] =\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
{\r
{0xfe, 0x00},\r
{0x83, 0x12}, \r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Effect_Sepia[] =\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
{\r
{0xfe, 0x00},\r
{0x83, 0x82},\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Effect_Negative[] =\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
{\r
- //Negative\r
+ //Negative\r
{0xfe, 0x00},\r
{0x83, 0x01},\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
-static struct reginfo sensor_Effect_Bluish[] =\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
{\r
- // Bluish\r
+ // Bluish\r
{0xfe, 0x00},\r
{0x83, 0x62},\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Effect_Green[] =\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
{\r
- // Greenish\r
+ // Greenish\r
{0xfe, 0x00},\r
{0x83, 0x52},\r
- {0x00, 0x00}\r
-};\r
-static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
- sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+ SensorEnd\r
};\r
-#endif\r
-#if CONFIG_SENSOR_Exposure\r
-static struct reginfo sensor_Exposure0[]=\r
-{\r
- //-3\r
- \r
- {0x00, 0x00}\r
-};\r
-\r
-static struct reginfo sensor_Exposure1[]=\r
-{\r
- //-2\r
- \r
- {0x00, 0x00}\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
};\r
\r
-static struct reginfo sensor_Exposure2[]=\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
{\r
- //-0.3EV\r
\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Exposure3[]=\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
{\r
- //default\r
- \r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Exposure4[]=\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
{\r
- // 1\r
-\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Exposure5[]=\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
{\r
- // 2\r
- \r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Exposure6[]=\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
{\r
- // 3\r
- \r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
- sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
-};\r
-#endif\r
-#if CONFIG_SENSOR_Saturation\r
-static struct reginfo sensor_Saturation0[]=\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
{\r
\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Saturation1[]=\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
{\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Saturation2[]=\r
-{\r
- {0x00, 0x00}\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
};\r
-static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
\r
-#endif\r
-#if CONFIG_SENSOR_Contrast\r
-static struct reginfo sensor_Contrast0[]=\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
{\r
- //Contrast -3\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Contrast1[]=\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
{\r
- //Contrast -2\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Contrast2[]=\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
{\r
- // Contrast -1\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
\r
-static struct reginfo sensor_Contrast3[]=\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
{\r
- //Contrast 0\r
- {0x00, 0x00}\r
-};\r
+ //Contrast -3\r
\r
-static struct reginfo sensor_Contrast4[]=\r
-{\r
- //Contrast +1\r
- {0x00, 0x00}\r
+ SensorEnd\r
};\r
\r
-\r
-static struct reginfo sensor_Contrast5[]=\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
{\r
- //Contrast +2\r
- {0x00, 0x00}\r
+ //Contrast -2\r
+\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Contrast6[]=\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
{\r
- \r
- //Contrast +3\r
- {0x00, 0x00}\r
+ // Contrast -1\r
\r
-};\r
-static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
- sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+ SensorEnd\r
};\r
\r
-#endif\r
-#if CONFIG_SENSOR_Mirror\r
-static struct reginfo sensor_MirrorOn[]=\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
{\r
- {0x17 , 0x14},\r
- {0x00 , 0x00}\r
-};\r
+ //Contrast 0\r
\r
-static struct reginfo sensor_MirrorOff[]=\r
-{\r
- {0x17 , 0x15},\r
- {0x00 , 0x00}\r
-};\r
-static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};\r
-#endif\r
-#if CONFIG_SENSOR_Flip\r
-static struct reginfo sensor_FlipOn[]=\r
-{\r
- {0x17 , 0x16},\r
- {0x00 , 0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_FlipOff[]=\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
{\r
- {0x17 , 0x17},\r
- {0x00 , 0x00}\r
+ //Contrast +1\r
+\r
+ SensorEnd\r
};\r
-static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};\r
\r
-#endif\r
-#if CONFIG_SENSOR_Scene\r
-static struct reginfo sensor_SceneAuto[] =\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
{\r
-{0xfe,0x01},\r
-{0x3e,0x40}, \r
-{0xfe,0x00},\r
+ //Contrast +2\r
\r
-{0x00,0x00}\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_SceneNight[] =\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
{\r
-{0xfe,0x01},\r
-{0x3e,0x60}, \r
-{0xfe,0x00},\r
-{0x00,0x00}\r
+ //Contrast +3\r
\r
+ SensorEnd\r
};\r
-static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
-\r
-#endif\r
-#if CONFIG_SENSOR_DigitalZoom\r
-static struct reginfo sensor_Zoom0[] =\r
-{\r
- {0x0, 0x0},\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
};\r
-\r
-static struct reginfo sensor_Zoom1[] =\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
{\r
- {0x0, 0x0},\r
+ {0xfe,0x01},\r
+ \r
+ {0x3e,0x40}, \r
+ {0xfe,0x00},\r
+ SensorEnd\r
};\r
\r
-static struct reginfo sensor_Zoom2[] =\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
{\r
- {0x0, 0x0},\r
+ {0xfe,0x01},\r
+ \r
+ {0x3e,0x60}, \r
+ {0xfe,0x00},\r
+ SensorEnd\r
};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
\r
-\r
-static struct reginfo sensor_Zoom3[] =\r
-{\r
- {0x0, 0x0},\r
-};\r
-static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
-#endif\r
-static const struct v4l2_querymenu sensor_menus[] =\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
{\r
- #if CONFIG_SENSOR_WhiteBalance\r
- { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,},\r
- { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,},\r
- { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,},\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Effect\r
- { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,},\r
- { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,},\r
- { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,},\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Scene\r
- { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,},\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Flash\r
- { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,},\r
- { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,},\r
- #endif\r
+ SensorEnd\r
};\r
\r
-static struct v4l2_queryctrl sensor_controls[] =\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
{\r
- #if CONFIG_SENSOR_WhiteBalance\r
- {\r
- .id = V4L2_CID_DO_WHITE_BALANCE,\r
- .type = V4L2_CTRL_TYPE_MENU,\r
- .name = "White Balance Control",\r
- .minimum = 0,\r
- .maximum = 4,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Brightness\r
- {\r
- .id = V4L2_CID_BRIGHTNESS,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Brightness Control",\r
- .minimum = -3,\r
- .maximum = 2,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Effect\r
- {\r
- .id = V4L2_CID_EFFECT,\r
- .type = V4L2_CTRL_TYPE_MENU,\r
- .name = "Effect Control",\r
- .minimum = 0,\r
- .maximum = 5,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Exposure\r
- {\r
- .id = V4L2_CID_EXPOSURE,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Exposure Control",\r
- .minimum = 0,\r
- .maximum = 6,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Saturation\r
- {\r
- .id = V4L2_CID_SATURATION,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Saturation Control",\r
- .minimum = 0,\r
- .maximum = 2,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Contrast\r
- {\r
- .id = V4L2_CID_CONTRAST,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Contrast Control",\r
- .minimum = -3,\r
- .maximum = 3,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Mirror\r
- {\r
- .id = V4L2_CID_HFLIP,\r
- .type = V4L2_CTRL_TYPE_BOOLEAN,\r
- .name = "Mirror Control",\r
- .minimum = 0,\r
- .maximum = 1,\r
- .step = 1,\r
- .default_value = 1,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Flip\r
- {\r
- .id = V4L2_CID_VFLIP,\r
- .type = V4L2_CTRL_TYPE_BOOLEAN,\r
- .name = "Flip Control",\r
- .minimum = 0,\r
- .maximum = 1,\r
- .step = 1,\r
- .default_value = 1,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Scene\r
- {\r
- .id = V4L2_CID_SCENE,\r
- .type = V4L2_CTRL_TYPE_MENU,\r
- .name = "Scene Control",\r
- .minimum = 0,\r
- .maximum = 1,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_DigitalZoom\r
- {\r
- .id = V4L2_CID_ZOOM_RELATIVE,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "DigitalZoom Control",\r
- .minimum = -1,\r
- .maximum = 1,\r
- .step = 1,\r
- .default_value = 0,\r
- }, {\r
- .id = V4L2_CID_ZOOM_ABSOLUTE,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "DigitalZoom Control",\r
- .minimum = 0,\r
- .maximum = 3,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Focus\r
- {\r
- .id = V4L2_CID_FOCUS_RELATIVE,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Focus Control",\r
- .minimum = -1,\r
- .maximum = 1,\r
- .step = 1,\r
- .default_value = 0,\r
- }, {\r
- .id = V4L2_CID_FOCUS_ABSOLUTE,\r
- .type = V4L2_CTRL_TYPE_INTEGER,\r
- .name = "Focus Control",\r
- .minimum = 0,\r
- .maximum = 255,\r
- .step = 1,\r
- .default_value = 125,\r
- },\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Flash\r
- {\r
- .id = V4L2_CID_FLASH,\r
- .type = V4L2_CTRL_TYPE_MENU,\r
- .name = "Flash Control",\r
- .minimum = 0,\r
- .maximum = 3,\r
- .step = 1,\r
- .default_value = 0,\r
- },\r
- #endif\r
+ SensorEnd\r
};\r
\r
-static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);\r
-static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);\r
-static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
-static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
-static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
-static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);\r
-static int sensor_resume(struct soc_camera_device *icd);\r
-static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);\r
-static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);\r
-static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
-static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
-static int sensor_deactivate(struct i2c_client *client);\r
-\r
-static struct soc_camera_ops sensor_ops =\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
{\r
- .suspend = sensor_suspend,\r
- .resume = sensor_resume,\r
- .set_bus_param = sensor_set_bus_param,\r
- .query_bus_param = sensor_query_bus_param,\r
- .controls = sensor_controls,\r
- .menus = sensor_menus,\r
- .num_controls = ARRAY_SIZE(sensor_controls),\r
- .num_menus = ARRAY_SIZE(sensor_menus),\r
+ SensorEnd\r
};\r
\r
-/* only one fixed colorspace per pixelcode */\r
-struct sensor_datafmt {\r
- enum v4l2_mbus_pixelcode code;\r
- enum v4l2_colorspace colorspace;\r
-};\r
\r
-/* Find a data format by a pixel code in an array */\r
-static const struct sensor_datafmt *sensor_find_datafmt(\r
- enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt,\r
- int n)\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
{\r
- int i;\r
- for (i = 0; i < n; i++)\r
- if (fmt[i].code == code)\r
- return fmt + i;\r
-\r
- return NULL;\r
-}\r
-\r
-static const struct sensor_datafmt sensor_colour_fmts[] = {\r
- {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
- {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+ SensorEnd\r
};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
\r
-typedef struct sensor_info_priv_s\r
-{\r
- int whiteBalance;\r
- int brightness;\r
- int contrast;\r
- int saturation;\r
- int effect;\r
- int scene;\r
- int digitalzoom;\r
- int focus;\r
- int flash;\r
- int exposure;\r
- bool snap2preview;\r
- bool video2preview;\r
- unsigned char mirror; /* HFLIP */\r
- unsigned char flip; /* VFLIP */\r
- unsigned int winseqe_cur_addr;\r
- struct sensor_datafmt fmt;\r
- unsigned int funmodule_state;\r
-} sensor_info_priv_t;\r
-\r
-struct sensor\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
{\r
- struct v4l2_subdev subdev;\r
- struct i2c_client *client;\r
- sensor_info_priv_t info_priv;\r
- int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */\r
-#if CONFIG_SENSOR_I2C_NOSCHED\r
- atomic_t tasklock_cnt;\r
-#endif\r
- struct rk29camera_platform_data *sensor_io_request;\r
- struct rk29camera_gpio_res *sensor_gpio_res;\r
};\r
-\r
-static struct sensor* to_sensor(const struct i2c_client *client)\r
-{\r
- return container_of(i2c_get_clientdata(client), struct sensor, subdev);\r
-}\r
-\r
-static int sensor_task_lock(struct i2c_client *client, int lock)\r
-{\r
-#if CONFIG_SENSOR_I2C_NOSCHED\r
- int cnt = 3;\r
- struct sensor *sensor = to_sensor(client);\r
-\r
- if (lock) {\r
- if (atomic_read(&sensor->tasklock_cnt) == 0) {\r
- while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {\r
- SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());\r
- msleep(35);\r
- cnt--;\r
- }\r
- if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {\r
- SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());\r
- goto sensor_task_lock_err;\r
- }\r
- preempt_disable();\r
- }\r
-\r
- atomic_add(1, &sensor->tasklock_cnt);\r
- } else {\r
- if (atomic_read(&sensor->tasklock_cnt) > 0) {\r
- atomic_sub(1, &sensor->tasklock_cnt);\r
-\r
- if (atomic_read(&sensor->tasklock_cnt) == 0)\r
- preempt_enable();\r
- }\r
- }\r
- return 0;\r
-sensor_task_lock_err:\r
- return -1; \r
-#else\r
- return 0;\r
-#endif\r
-\r
-}\r
-\r
-/* sensor register write */\r
-static int sensor_write(struct i2c_client *client, u8 reg, u8 val)\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
{\r
- int err,cnt;\r
- u8 buf[2];\r
- struct i2c_msg msg[1];\r
-\r
- buf[0] = reg;\r
- buf[1] = val;\r
-\r
-\r
- msg->addr = client->addr;\r
- msg->flags = client->flags;\r
- msg->buf = buf;\r
- msg->len = sizeof(buf);\r
- msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
- msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */\r
-\r
- cnt = 3;\r
- err = -EAGAIN;\r
-\r
- while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
- err = i2c_transfer(client->adapter, msg, 1);\r
+};\r
\r
- if (err >= 0) {\r
- return 0;\r
- } else {\r
- SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);\r
- udelay(10);\r
- }\r
- }\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
\r
- return err;\r
-}\r
\r
-/* sensor register read */\r
-static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
{\r
- int err,cnt;\r
- u8 buf[1];\r
- struct i2c_msg msg[2];\r
-\r
- buf[0] = reg ;\r
-\r
- msg[0].addr = client->addr;\r
- msg[0].flags = client->flags;\r
- msg[0].buf = buf;\r
- msg[0].len = sizeof(buf);\r
- msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
- msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
-\r
- msg[1].addr = client->addr;\r
- msg[1].flags = client->flags|I2C_M_RD;\r
- msg[1].buf = buf;\r
- msg[1].len = 1;\r
- msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
- msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
-\r
- cnt = 3;\r
- err = -EAGAIN;\r
- while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
- err = i2c_transfer(client->adapter, msg, 2);\r
-\r
- if (err >= 0) {\r
- *val = buf[0];\r
- return 0;\r
- } else {\r
- SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);\r
- udelay(10);\r
- }\r
- }\r
-\r
- return err;\r
+ \r
+ return 0;\r
}\r
-\r
-/* write a array of registers */\r
-static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
{\r
- int err = 0, cnt;\r
- int i = 0;\r
-#if CONFIG_SENSOR_I2C_RDWRCHK \r
- char valchk;\r
-#endif\r
-\r
- cnt = 0;\r
- if (sensor_task_lock(client, 1) < 0)\r
- goto sensor_write_array_end;\r
-\r
- while (regarray[i].reg != 0)\r
- {\r
- err = sensor_write(client, regarray[i].reg, regarray[i].val);\r
- if (err < 0)\r
- {\r
- if (cnt-- > 0) {\r
- SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);\r
- i = 0;\r
- continue;\r
- } else {\r
- SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());\r
- err = -EPERM;\r
- goto sensor_write_array_end;\r
- }\r
- } else {\r
- #if CONFIG_SENSOR_I2C_RDWRCHK\r
- sensor_read(client, regarray[i].reg, &valchk);\r
- if (valchk != regarray[i].val)\r
- SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
- #endif\r
- }\r
- i++;\r
- }\r
-\r
-sensor_write_array_end:\r
- sensor_task_lock(client,0);\r
- return err;\r
+ \r
+ return 0;\r
}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ char value;\r
+ unsigned int pid=0,shutter,temp_reg;\r
+ if(mf->width == 1600 && mf->height == 1200){\r
+ sensor_write(client, 0xfe, 0x00);\r
+ sensor_write(client, 0xb6, 0x02);\r
+ \r
+ \r
+ sensor_read(client, 0x03, &value);\r
+ pid |= (value << 8);\r
+ sensor_read(client, 0x04, &value);\r
+ pid |= (value & 0xff);\r
+ shutter=pid;\r
+ \r
+ \r
+ temp_reg= shutter /2; // 2\r
+ \r
+ if(temp_reg < 1) temp_reg = 1;\r
+ \r
+ \r
+ sensor_write(client, 0x03, ((temp_reg>>8)&0xff));\r
+ sensor_write(client, 0x04, (temp_reg&0xff));\r
+ }\r
\r
-#if CONFIG_SENSOR_I2C_RDWRCHK\r
-static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray)\r
-{\r
- int cnt;\r
- int i = 0;\r
- char valchk;\r
-\r
- cnt = 0;\r
- valchk = 0;\r
- while (regarray[i].reg != 0)\r
- {\r
- sensor_read(client, regarray[i].reg, &valchk);\r
- if (valchk != regarray[i].val)\r
- SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
-\r
- i++;\r
- }\r
- return 0;\r
+ return 0;\r
}\r
-#endif\r
-static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
{\r
- struct soc_camera_link *icl = to_soc_camera_link(icd);\r
- int ret = 0;\r
-\r
- SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);\r
- switch (cmd)\r
- {\r
- case Sensor_PowerDown:\r
- {\r
- if (icl->powerdown) {\r
- ret = icl->powerdown(icd->pdev, on);\r
- if (ret == RK29_CAM_IO_SUCCESS) {\r
- if (on == 0) {\r
- mdelay(2);\r
- if (icl->reset)\r
- icl->reset(icd->pdev);\r
- }\r
- } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {\r
- ret = -ENODEV;\r
- goto sensor_power_end;\r
- }\r
- }\r
- break;\r
- }\r
- case Sensor_Flash:\r
- {\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
- struct sensor *sensor = to_sensor(client);\r
-\r
- if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {\r
- sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);\r
- if(on){\r
- //flash off after 2 secs\r
- hrtimer_cancel(&(flash_off_timer.timer));\r
- hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL);\r
- }\r
- }\r
- break;\r
- }\r
- default:\r
- {\r
- SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
- break;\r
- }\r
- }\r
-sensor_power_end:\r
- return ret;\r
-}\r
-static enum hrtimer_restart flash_off_func(struct hrtimer *timer){\r
- struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer);\r
- sensor_ioctrl(fps_timer->icd,Sensor_Flash,0);\r
- SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__);\r
- return 0;\r
- \r
+ return 0;\r
}\r
-static int sensor_init(struct v4l2_subdev *sd, u32 val)\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- struct sensor *sensor = to_sensor(client);\r
- const struct v4l2_queryctrl *qctrl;\r
- const struct sensor_datafmt *fmt;\r
- char value;\r
- int ret,pid = 0;\r
-\r
- SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
-\r
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
- ret = -ENODEV;\r
- goto sensor_INIT_ERR;\r
- }\r
-\r
- /* soft reset */\r
- if (sensor_task_lock(client,1)<0)\r
- goto sensor_INIT_ERR;\r
- /* check if it is an sensor sensor */\r
- ret = sensor_read(client, 0xf0, &value);\r
- if (ret != 0) {\r
- SENSOR_TR("read chip id high byte failed\n");\r
- ret = -ENODEV;\r
- goto sensor_INIT_ERR;\r
- }\r
-\r
- pid |= (value << 8);\r
-\r
- ret = sensor_read(client, 0xf1, &value);\r
- if (ret != 0) {\r
- SENSOR_TR("read chip id low byte failed\n");\r
- ret = -ENODEV;\r
- goto sensor_INIT_ERR;\r
- }\r
-\r
- pid |= (value & 0xff);\r
- SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
- if (pid == SENSOR_ID) {\r
- sensor->model = SENSOR_V4L2_IDENT;\r
- } else {\r
- SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
- ret = -ENODEV;\r
- goto sensor_INIT_ERR;\r
- }\r
-\r
- ret = sensor_write_array(client, sensor_init_data);\r
-\r
-\r
- mdelay(300);\r
-\r
\r
- if (ret != 0)\r
- {\r
- SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());\r
- goto sensor_INIT_ERR;\r
- }\r
- sensor_task_lock(client,0);\r
- \r
- sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR;\r
- fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts));\r
- if (!fmt) {\r
- SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING());\r
- ret = -EINVAL;\r
- goto sensor_INIT_ERR;\r
- }\r
- sensor->info_priv.fmt = *fmt;\r
-\r
- /* sensor sensor information for initialization */\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
- if (qctrl)\r
- sensor->info_priv.whiteBalance = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);\r
- if (qctrl)\r
- sensor->info_priv.brightness = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
- if (qctrl)\r
- sensor->info_priv.effect = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);\r
- if (qctrl)\r
- sensor->info_priv.exposure = qctrl->default_value;\r
-\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);\r
- if (qctrl)\r
- sensor->info_priv.saturation = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);\r
- if (qctrl)\r
- sensor->info_priv.contrast = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);\r
- if (qctrl)\r
- sensor->info_priv.mirror = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);\r
- if (qctrl)\r
- sensor->info_priv.flip = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);\r
- if (qctrl)\r
- sensor->info_priv.scene = qctrl->default_value;\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
- if (qctrl)\r
- sensor->info_priv.digitalzoom = qctrl->default_value;\r
-\r
- /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */\r
- #if CONFIG_SENSOR_Focus\r
- sensor_set_focus();\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);\r
- if (qctrl)\r
- sensor->info_priv.focus = qctrl->default_value;\r
- #endif\r
-\r
- #if CONFIG_SENSOR_Flash \r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);\r
- if (qctrl)\r
- sensor->info_priv.flash = qctrl->default_value;\r
- flash_off_timer.icd = icd;\r
- flash_off_timer.timer.function = flash_off_func;\r
- #endif\r
-\r
- SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);\r
- sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK;\r
- return 0;\r
-sensor_INIT_ERR:\r
- sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
- sensor_task_lock(client,0);\r
- sensor_deactivate(client);\r
- return ret;\r
+ return 0;\r
}\r
-\r
-static int sensor_deactivate(struct i2c_client *client)\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
{\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
-\r
- struct sensor *sensor = to_sensor(client);\r
- SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
-\r
- /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */\r
- if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
- }\r
- sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
- msleep(100); \r
-\r
- /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */\r
- icd->user_width = SENSOR_INIT_WIDTH;\r
- icd->user_height = SENSOR_INIT_HEIGHT;\r
- sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
- \r
return 0;\r
}\r
-\r
-static struct reginfo sensor_power_down_sequence[]=\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
{\r
-\r
- {0x00,0x00}\r
-};\r
+ return 0;\r
+}\r
static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
{\r
- int ret;\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if (pm_msg.event == PM_EVENT_SUSPEND) {\r
- SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());\r
- ret = sensor_write_array(client, sensor_power_down_sequence) ;\r
- if (ret != 0) {\r
- SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);\r
- return ret;\r
- } else {\r
- ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
- if (ret < 0) {\r
- SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());\r
- return -EINVAL;\r
- }\r
- }\r
- } else {\r
- SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());\r
- return -EINVAL;\r
- }\r
- return 0;\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
}\r
\r
static int sensor_resume(struct soc_camera_device *icd)\r
-{\r
- int ret;\r
-\r
- ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);\r
- if (ret < 0) {\r
- SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());\r
- return -EINVAL;\r
- }\r
-\r
- SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());\r
-\r
- return 0;\r
-\r
-}\r
-\r
-static int sensor_set_bus_param(struct soc_camera_device *icd,\r
- unsigned long flags)\r
{\r
\r
- return 0;\r
-}\r
+ SENSOR_DG("Resume");\r
\r
-static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)\r
-{\r
- struct soc_camera_link *icl = to_soc_camera_link(icd);\r
- unsigned long flags = SENSOR_BUS_PARAM;\r
+ return 0;\r
\r
- return soc_camera_apply_sensor_flags(icl, flags);\r
}\r
-\r
-static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- struct sensor *sensor = to_sensor(client);\r
-\r
- mf->width = icd->user_width;\r
- mf->height = icd->user_height;\r
- mf->code = sensor->info_priv.fmt.code;\r
- mf->colorspace = sensor->info_priv.fmt.colorspace;\r
- mf->field = V4L2_FIELD_NONE;\r
-\r
- return 0;\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ val-=4;\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0){\r
+ err = sensor_write(client, 0x17, ((val |0x1)+4));\r
+ }\r
+ else \r
+ err = sensor_write(client, 0x17, ((val & 0xfe)+4));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+ return err; \r
}\r
-static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
{\r
- bool ret = false;\r
-\r
- if ((mf->width == 1024) && (mf->height == 768)) {\r
- ret = true;\r
- } else if ((mf->width == 1280) && (mf->height == 1024)) {\r
- ret = true;\r
- } else if ((mf->width == 1600) && (mf->height == 1200)) {\r
- ret = true;\r
- } else if ((mf->width == 2048) && (mf->height == 1536)) {\r
- ret = true;\r
- } else if ((mf->width == 2592) && (mf->height == 1944)) {\r
- ret = true;\r
- }\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
\r
- if (ret == true)\r
- SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height);\r
- return ret;\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
}\r
\r
-static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
{\r
- bool ret = false;\r
-\r
- if ((mf->width == 1280) && (mf->height == 720)) {\r
- ret = true;\r
- } else if ((mf->width == 1920) && (mf->height == 1080)) {\r
- ret = true;\r
- }\r
+ char val;\r
+ int err = 0; \r
\r
- if (ret == true)\r
- SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height);\r
- return ret;\r
-}\r
-static unsigned int shutter_h,shutter_l;\r
-static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
-{\r
- int ret1;\r
-\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- const struct sensor_datafmt *fmt;\r
- struct sensor *sensor = to_sensor(client);\r
- const struct v4l2_queryctrl *qctrl;\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- struct reginfo *winseqe_set_addr=NULL;\r
- int ret=0, set_w,set_h;\r
-#if 1\r
-char value;\r
-unsigned int pid=0,shutter,temp_reg;\r
-\r
-#endif\r
-\r
- fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,\r
- ARRAY_SIZE(sensor_colour_fmts));\r
- if (!fmt) {\r
- ret = -EINVAL;\r
- goto sensor_s_fmt_end;\r
- }\r
-\r
- if (sensor->info_priv.fmt.code != mf->code) {\r
- switch (mf->code)\r
- {\r
- case V4L2_MBUS_FMT_YUYV8_2X8:\r
- {\r
- winseqe_set_addr = sensor_ClrFmt_YUYV;\r
- break;\r
- }\r
- case V4L2_MBUS_FMT_UYVY8_2X8:\r
- {\r
- winseqe_set_addr = sensor_ClrFmt_UYVY;\r
- break;\r
- }\r
- default:\r
- break;\r
- }\r
- if (winseqe_set_addr != NULL) {\r
- sensor_write_array(client, winseqe_set_addr);\r
- sensor->info_priv.fmt.code = mf->code;\r
- sensor->info_priv.fmt.colorspace= mf->colorspace; \r
- SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code);\r
- } else {\r
- SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ \r
+ sensor_write(client, 0xfe, 0);\r
+ err = sensor_read(client, 0x17, &val);\r
+ val-=4;\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0){\r
+ err = sensor_write(client, 0x17, ((val |0x2)+4));\r
+ }\r
+ else {\r
+ err = sensor_write(client, 0x17, ((val & 0xfc)+4));\r
+ }\r
}\r
+ } else {\r
+ //do nothing\r
}\r
\r
- set_w = mf->width;\r
- set_h = mf->height;\r
-\r
- if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)\r
- {\r
- winseqe_set_addr = sensor_qcif;\r
- set_w = 176;\r
- set_h = 144;\r
- }\r
- else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)\r
- {\r
- winseqe_set_addr = sensor_qvga;\r
- set_w = 320;\r
- set_h = 240;\r
- }\r
- else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)\r
- {\r
- winseqe_set_addr = sensor_cif;\r
- set_w = 352;\r
- set_h = 288;\r
- }\r
- else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)\r
- {\r
- winseqe_set_addr = sensor_vga;\r
- set_w = 640;\r
- set_h = 480;\r
- }\r
- else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)\r
- {\r
- winseqe_set_addr = sensor_svga;\r
- set_w = 800;\r
- set_h = 600;\r
- }\r
- else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)\r
- {\r
- winseqe_set_addr = sensor_sxga;\r
- set_w = 1280;\r
- set_h = 1024;\r
- }\r
- else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)\r
- {\r
- winseqe_set_addr = sensor_uxga;\r
- set_w = 1600;\r
- set_h = 1200;\r
- }\r
- else\r
- {\r
- winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */\r
- set_w = SENSOR_INIT_WIDTH;\r
- set_h = SENSOR_INIT_HEIGHT;\r
- SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height);\r
- }\r
-\r
- if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) {\r
- #if CONFIG_SENSOR_Flash\r
- if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */\r
- if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
- sensor_ioctrl(icd, Sensor_Flash, Flash_On);\r
- SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());\r
- } \r
- } else { /* ddl@rock-chips.com : Video */\r
- if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
- sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
- SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());\r
- }\r
- }\r
- #endif\r
-\r
- if ((winseqe_set_addr == sensor_svga)||(winseqe_set_addr == sensor_vga) )\r
- {\r
- sensor_write(client, 0xb6, 0x00); // AEC ON\r
- sensor_write(client, 0x03, shutter_h);\r
- sensor_write(client, 0x04, shutter_l);\r
- msleep(50);\r
- printk("set preview for rewrite 0x03");\r
- \r
- } \r
- ret |= sensor_write_array(client, winseqe_set_addr);\r
-#if 1\r
- if (winseqe_set_addr == sensor_uxga) \r
- { \r
- sensor_write(client, 0xfe, 0x00);\r
- sensor_write(client, 0xb6, 0x02); // AEC OFF\r
- sensor_read(client, 0x03, &value);\r
- shutter_h=value;\r
- pid |= (value << 8);\r
- sensor_read(client, 0x04, &value);\r
- shutter_l=value;\r
- pid |= (value & 0xff);\r
- shutter=pid;\r
- temp_reg= shutter /2;\r
- if(temp_reg < 1) temp_reg = 1;\r
- sensor_write(client, 0x03, ((temp_reg>>8)&0xff));\r
- sensor_write(client, 0x04, (temp_reg&0xff));\r
- }\r
-#endif \r
-\r
- if (ret != 0) {\r
- SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());\r
- #if CONFIG_SENSOR_Flash\r
- if (sensor_fmt_capturechk(sd,mf) == true) {\r
- if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
- sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
- SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());\r
- }\r
- }\r
- #endif\r
- goto sensor_s_fmt_end;\r
- }\r
-\r
- sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr;\r
-\r
- if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
- sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
- if (sensor->info_priv.whiteBalance != 0) {\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
- sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
- }\r
- sensor->info_priv.snap2preview = true;\r
- } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
- sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
- sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
- sensor->info_priv.video2preview = true;\r
- } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
- sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
- sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
- msleep(600);\r
- sensor->info_priv.video2preview = false;\r
- sensor->info_priv.snap2preview = false;\r
- }\r
-\r
- SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);\r
- }\r
- else\r
- {\r
- SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);\r
- }\r
-\r
- mf->width = set_w;\r
- mf->height = set_h;\r
- msleep(100); //james added\r
-sensor_s_fmt_end:\r
- return ret;\r
+ return err; \r
}\r
-\r
-static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct sensor *sensor = to_sensor(client);\r
- const struct sensor_datafmt *fmt;\r
- int ret = 0,set_w,set_h;\r
- \r
- fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,\r
- ARRAY_SIZE(sensor_colour_fmts));\r
- if (fmt == NULL) {\r
- fmt = &sensor->info_priv.fmt;\r
- mf->code = fmt->code;\r
- } \r
-\r
- if (mf->height > SENSOR_MAX_HEIGHT)\r
- mf->height = SENSOR_MAX_HEIGHT;\r
- else if (mf->height < SENSOR_MIN_HEIGHT)\r
- mf->height = SENSOR_MIN_HEIGHT;\r
-\r
- if (mf->width > SENSOR_MAX_WIDTH)\r
- mf->width = SENSOR_MAX_WIDTH;\r
- else if (mf->width < SENSOR_MIN_WIDTH)\r
- mf->width = SENSOR_MIN_WIDTH;\r
-\r
- set_w = mf->width;\r
- set_h = mf->height;\r
-\r
- if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)\r
- {\r
- set_w = 176;\r
- set_h = 144;\r
- }\r
- else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)\r
- {\r
- set_w = 320;\r
- set_h = 240;\r
- }\r
- else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)\r
- {\r
- set_w = 352;\r
- set_h = 288;\r
- }\r
- else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)\r
- {\r
- set_w = 640;\r
- set_h = 480;\r
- }\r
- else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)\r
- {\r
- set_w = 800;\r
- set_h = 600;\r
- }\r
- else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)\r
- {\r
- set_w = 1280;\r
- set_h = 1024;\r
- }\r
- else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)\r
- {\r
- set_w = 1600;\r
- set_h = 1200;\r
- }\r
- else\r
- {\r
- set_w = SENSOR_INIT_WIDTH;\r
- set_h = SENSOR_INIT_HEIGHT;\r
- }\r
-\r
- mf->width = set_w;\r
- mf->height = set_h;\r
- mf->colorspace = fmt->colorspace;\r
- \r
- return ret;\r
-}\r
-\r
- static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
\r
- if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)\r
- return -EINVAL;\r
-\r
- if (id->match.addr != client->addr)\r
- return -ENODEV;\r
-\r
- id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gc2035 identifier */\r
- id->revision = 0;\r
-\r
- return 0;\r
-}\r
-#if CONFIG_SENSOR_Brightness\r
-static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Effect\r
-static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Exposure\r
-static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Saturation\r
-static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Contrast\r
-static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Mirror\r
-static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Flip\r
-static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Scene\r
-static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
}\r
-#endif\r
-#if CONFIG_SENSOR_WhiteBalance\r
-static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
-\r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
- {\r
- if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- }\r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
-#endif\r
-#if CONFIG_SENSOR_DigitalZoom\r
-static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)\r
-{\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
- struct sensor *sensor = to_sensor(client);\r
- const struct v4l2_queryctrl *qctrl_info;\r
- int digitalzoom_cur, digitalzoom_total;\r
-\r
- qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
- if (qctrl_info)\r
- return -EINVAL;\r
\r
- digitalzoom_cur = sensor->info_priv.digitalzoom;\r
- digitalzoom_total = qctrl_info->maximum;\r
-\r
- if ((value > 0) && (digitalzoom_cur >= digitalzoom_total))\r
- {\r
- SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
- return -EINVAL;\r
- }\r
-\r
- if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum))\r
- {\r
- SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
- return -EINVAL;\r
- }\r
-\r
- if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total))\r
- {\r
- value = digitalzoom_total - digitalzoom_cur;\r
- }\r
-\r
- if ((value < 0) && ((digitalzoom_cur + value) < 0))\r
- {\r
- value = 0 - digitalzoom_cur;\r
- }\r
-\r
- digitalzoom_cur += value;\r
-\r
- if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)\r
- {\r
- if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)\r
- {\r
- SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
- return -EINVAL;\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
-\r
- return -EINVAL;\r
-}\r
-#endif\r
-#if CONFIG_SENSOR_Flash\r
-static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
-{ \r
- if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {\r
- if (value == 3) { /* ddl@rock-chips.com: torch */\r
- sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */\r
- } else {\r
- sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
- }\r
- SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
- return 0;\r
- }\r
- \r
- SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
- return -EINVAL;\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
-#endif\r
\r
-static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct sensor *sensor = to_sensor(client);\r
- const struct v4l2_queryctrl *qctrl;\r
-\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
-\r
- if (!qctrl)\r
- {\r
- SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
- return -EINVAL;\r
- }\r
-\r
- switch (ctrl->id)\r
- {\r
- case V4L2_CID_BRIGHTNESS:\r
- {\r
- ctrl->value = sensor->info_priv.brightness;\r
- break;\r
- }\r
- case V4L2_CID_SATURATION:\r
- {\r
- ctrl->value = sensor->info_priv.saturation;\r
- break;\r
- }\r
- case V4L2_CID_CONTRAST:\r
- {\r
- ctrl->value = sensor->info_priv.contrast;\r
- break;\r
- }\r
- case V4L2_CID_DO_WHITE_BALANCE:\r
- {\r
- ctrl->value = sensor->info_priv.whiteBalance;\r
- break;\r
- }\r
- case V4L2_CID_EXPOSURE:\r
- {\r
- ctrl->value = sensor->info_priv.exposure;\r
- break;\r
- }\r
- case V4L2_CID_HFLIP:\r
- {\r
- ctrl->value = sensor->info_priv.mirror;\r
- break;\r
- }\r
- case V4L2_CID_VFLIP:\r
- {\r
- ctrl->value = sensor->info_priv.flip;\r
- break;\r
- }\r
- default :\r
- break;\r
- }\r
- return 0;\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
\r
-\r
-\r
-static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct sensor *sensor = to_sensor(client);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- const struct v4l2_queryctrl *qctrl;\r
-\r
-\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
-\r
- if (!qctrl)\r
- {\r
- SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
- return -EINVAL;\r
- }\r
-\r
- switch (ctrl->id)\r
- {\r
-#if CONFIG_SENSOR_Brightness\r
- case V4L2_CID_BRIGHTNESS:\r
- {\r
- if (ctrl->value != sensor->info_priv.brightness)\r
- {\r
- if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)\r
- {\r
- return -EINVAL;\r
- }\r
- sensor->info_priv.brightness = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Exposure\r
- case V4L2_CID_EXPOSURE:\r
- {\r
- if (ctrl->value != sensor->info_priv.exposure)\r
- {\r
- if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)\r
- {\r
- return -EINVAL;\r
- }\r
- sensor->info_priv.exposure = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Saturation\r
- case V4L2_CID_SATURATION:\r
- {\r
- if (ctrl->value != sensor->info_priv.saturation)\r
- {\r
- if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)\r
- {\r
- return -EINVAL;\r
- }\r
- sensor->info_priv.saturation = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Contrast\r
- case V4L2_CID_CONTRAST:\r
- {\r
- if (ctrl->value != sensor->info_priv.contrast)\r
- {\r
- if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)\r
- {\r
- return -EINVAL;\r
- }\r
- sensor->info_priv.contrast = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_WhiteBalance\r
- case V4L2_CID_DO_WHITE_BALANCE:\r
- {\r
- if (ctrl->value != sensor->info_priv.whiteBalance)\r
- {\r
- if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)\r
- {\r
- return -EINVAL;\r
- }\r
- sensor->info_priv.whiteBalance = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Mirror\r
- case V4L2_CID_HFLIP:\r
- {\r
- if (ctrl->value != sensor->info_priv.mirror)\r
- {\r
- if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.mirror = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Flip\r
- case V4L2_CID_VFLIP:\r
- {\r
- if (ctrl->value != sensor->info_priv.flip)\r
- {\r
- if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.flip = ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
- default:\r
- break;\r
- }\r
-\r
- return 0;\r
-}\r
-static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)\r
-{\r
- const struct v4l2_queryctrl *qctrl;\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
- struct sensor *sensor = to_sensor(client);\r
-\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
-\r
- if (!qctrl)\r
- {\r
- SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
- return -EINVAL;\r
- }\r
-\r
- switch (ext_ctrl->id)\r
- {\r
- case V4L2_CID_SCENE:\r
- {\r
- ext_ctrl->value = sensor->info_priv.scene;\r
- break;\r
- }\r
- case V4L2_CID_EFFECT:\r
- {\r
- ext_ctrl->value = sensor->info_priv.effect;\r
- break;\r
- }\r
- case V4L2_CID_ZOOM_ABSOLUTE:\r
- {\r
- ext_ctrl->value = sensor->info_priv.digitalzoom;\r
- break;\r
- }\r
- case V4L2_CID_ZOOM_RELATIVE:\r
- {\r
- return -EINVAL;\r
- }\r
- case V4L2_CID_FOCUS_ABSOLUTE:\r
- {\r
- ext_ctrl->value = sensor->info_priv.focus;\r
- break;\r
- }\r
- case V4L2_CID_FOCUS_RELATIVE:\r
- {\r
- return -EINVAL;\r
- }\r
- case V4L2_CID_FLASH:\r
- {\r
- ext_ctrl->value = sensor->info_priv.flash;\r
- break;\r
- }\r
- default :\r
- break;\r
- }\r
- return 0;\r
-}\r
-static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)\r
-{\r
- const struct v4l2_queryctrl *qctrl;\r
- struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
- struct sensor *sensor = to_sensor(client);\r
- int val_offset;\r
-\r
- qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
-\r
- if (!qctrl)\r
- {\r
- SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
- return -EINVAL;\r
- }\r
-\r
- val_offset = 0;\r
- switch (ext_ctrl->id)\r
- {\r
-#if CONFIG_SENSOR_Scene\r
- case V4L2_CID_SCENE:\r
- {\r
- if (ext_ctrl->value != sensor->info_priv.scene)\r
- {\r
- if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.scene = ext_ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Effect\r
- case V4L2_CID_EFFECT:\r
- {\r
- if (ext_ctrl->value != sensor->info_priv.effect)\r
- {\r
- if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.effect= ext_ctrl->value;\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_DigitalZoom\r
- case V4L2_CID_ZOOM_ABSOLUTE:\r
- {\r
- if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
- return -EINVAL;\r
-\r
- if (ext_ctrl->value != sensor->info_priv.digitalzoom)\r
- {\r
- val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;\r
-\r
- if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.digitalzoom += val_offset;\r
-\r
- SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);\r
- }\r
-\r
- break;\r
- }\r
- case V4L2_CID_ZOOM_RELATIVE:\r
- {\r
- if (ext_ctrl->value)\r
- {\r
- if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.digitalzoom += ext_ctrl->value;\r
-\r
- SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Focus\r
- case V4L2_CID_FOCUS_ABSOLUTE:\r
- {\r
- if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
- return -EINVAL;\r
-\r
- if (ext_ctrl->value != sensor->info_priv.focus)\r
- {\r
- val_offset = ext_ctrl->value -sensor->info_priv.focus;\r
-\r
- sensor->info_priv.focus += val_offset;\r
- }\r
-\r
- break;\r
- }\r
- case V4L2_CID_FOCUS_RELATIVE:\r
- {\r
- if (ext_ctrl->value)\r
- {\r
- sensor->info_priv.focus += ext_ctrl->value;\r
-\r
- SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);\r
- }\r
- break;\r
- }\r
-#endif\r
-#if CONFIG_SENSOR_Flash\r
- case V4L2_CID_FLASH:\r
- {\r
- if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)\r
- return -EINVAL;\r
- sensor->info_priv.flash = ext_ctrl->value;\r
-\r
- SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);\r
- break;\r
- }\r
-#endif\r
- default:\r
- break;\r
- }\r
-\r
- return 0;\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
\r
-static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- int i, error_cnt=0, error_idx=-1;\r
-\r
-\r
- for (i=0; i<ext_ctrl->count; i++) {\r
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
- error_cnt++;\r
- error_idx = i;\r
- }\r
- }\r
-\r
- if (error_cnt > 1)\r
- error_idx = ext_ctrl->count;\r
-\r
- if (error_idx != -1) {\r
- ext_ctrl->error_idx = error_idx;\r
- return -EINVAL;\r
- } else {\r
- return 0;\r
- }\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
}\r
\r
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- int i, error_cnt=0, error_idx=-1;\r
-\r
-\r
- for (i=0; i<ext_ctrl->count; i++) {\r
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
- error_cnt++;\r
- error_idx = i;\r
- }\r
- }\r
-\r
- if (error_cnt > 1)\r
- error_idx = ext_ctrl->count;\r
-\r
- if (error_idx != -1) {\r
- ext_ctrl->error_idx = error_idx;\r
- return -EINVAL;\r
- } else {\r
- return 0;\r
- }\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
-\r
-/* Interface active, can use i2c. If it fails, it can indeed mean, that\r
- * this wasn't our capture interface, so, we wait for the right one */\r
-static int sensor_video_probe(struct soc_camera_device *icd,\r
- struct i2c_client *client)\r
-{\r
- char value;\r
- int ret,pid = 0;\r
- struct sensor *sensor = to_sensor(client);\r
-\r
- /* We must have a parent by now. And it cannot be a wrong one.\r
- * So this entire test is completely redundant. */\r
- if (!icd->dev.parent ||\r
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)\r
- return -ENODEV;\r
-\r
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
- ret = -ENODEV;\r
- goto sensor_video_probe_err;\r
- }\r
-\r
- /* soft reset */\r
-\r
- /* check if it is an sensor sensor */\r
- ret = sensor_read(client, 0xf0, &value);\r
- if (ret != 0) {\r
- SENSOR_TR("read chip id high byte failed\n");\r
- ret = -ENODEV;\r
- goto sensor_video_probe_err;\r
- }\r
-\r
- pid |= (value << 8);\r
-\r
- ret = sensor_read(client, 0xf1, &value);\r
- if (ret != 0) {\r
- SENSOR_TR("read chip id low byte failed\n");\r
- ret = -ENODEV;\r
- goto sensor_video_probe_err;\r
- }\r
-\r
- pid |= (value & 0xff);\r
- SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
- if (pid == SENSOR_ID) {\r
- sensor->model = SENSOR_V4L2_IDENT;\r
- } else {\r
- SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
- ret = -ENODEV;\r
- goto sensor_video_probe_err;\r
- }\r
-\r
- return 0;\r
-\r
-sensor_video_probe_err:\r
-\r
- return ret;\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
-static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)\r
-{\r
- struct i2c_client *client = v4l2_get_subdevdata(sd);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- struct sensor *sensor = to_sensor(client);\r
-#if CONFIG_SENSOR_Flash\r
- int i;\r
-#endif\r
- int ret = 0;\r
- \r
- SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
- switch (cmd)\r
- {\r
- case RK29_CAM_SUBDEV_DEACTIVATE:\r
- {\r
- sensor_deactivate(client);\r
- break;\r
- }\r
-\r
- case RK29_CAM_SUBDEV_IOREQUEST:\r
- {\r
- sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; \r
- if (sensor->sensor_io_request != NULL) { \r
- sensor->sensor_gpio_res = NULL;\r
- for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {\r
- if (sensor->sensor_io_request->gpio_res[i].dev_name && \r
- (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {\r
- sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];\r
- }\r
- }\r
- if (sensor->sensor_gpio_res == NULL) {\r
- SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
- ret = -EINVAL;\r
- goto sensor_ioctl_end;\r
- }\r
- } else {\r
- SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
- ret = -EINVAL;\r
- goto sensor_ioctl_end;\r
- }\r
- /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control \r
- for this project */\r
- #if CONFIG_SENSOR_Flash \r
- if (sensor->sensor_gpio_res) {\r
- if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {\r
- for (i = 0; i < icd->ops->num_controls; i++) {\r
- if (V4L2_CID_FLASH == icd->ops->controls[i].id) {\r
- //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); \r
- sensor_controls[i].id=0xffff; \r
- }\r
- }\r
- sensor->info_priv.flash = 0xff;\r
- SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());\r
- }else{ //two cameras are the same,need to deal diffrently ,zyc\r
- for (i = 0; i < icd->ops->num_controls; i++) {\r
- if(0xffff == icd->ops->controls[i].id){\r
- sensor_controls[i].id=V4L2_CID_FLASH;\r
- } \r
- }\r
- }\r
- }\r
- #endif\r
- break;\r
- }\r
- default:\r
- {\r
- SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
- break;\r
- }\r
- }\r
-sensor_ioctl_end:\r
- return ret;\r
\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
}\r
-static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,\r
- enum v4l2_mbus_pixelcode *code)\r
-{\r
- if (index >= ARRAY_SIZE(sensor_colour_fmts))\r
- return -EINVAL;\r
\r
- *code = sensor_colour_fmts[index].code;\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
return 0;\r
}\r
-static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\r
- .init = sensor_init,\r
- .g_ctrl = sensor_g_control,\r
- .s_ctrl = sensor_s_control,\r
- .g_ext_ctrls = sensor_g_ext_controls,\r
- .s_ext_ctrls = sensor_s_ext_controls,\r
- .g_chip_ident = sensor_g_chip_ident,\r
- .ioctl = sensor_ioctl,\r
-};\r
-\r
-static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\r
- .s_mbus_fmt = sensor_s_fmt,\r
- .g_mbus_fmt = sensor_g_fmt,\r
- .try_mbus_fmt = sensor_try_fmt,\r
- .enum_mbus_fmt = sensor_enum_fmt,\r
-};\r
\r
-static struct v4l2_subdev_ops sensor_subdev_ops = {\r
- .core = &sensor_subdev_core_ops,\r
- .video = &sensor_subdev_video_ops,\r
-};\r
-\r
-static int sensor_probe(struct i2c_client *client,\r
- const struct i2c_device_id *did)\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
{\r
- struct sensor *sensor;\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);\r
- struct soc_camera_link *icl;\r
- int ret;\r
-\r
- SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);\r
- if (!icd) {\r
- dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());\r
- return -EINVAL;\r
- }\r
-\r
- icl = to_soc_camera_link(icd);\r
- if (!icl) {\r
- dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());\r
- return -EINVAL;\r
- }\r
-\r
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {\r
- dev_warn(&adapter->dev,\r
- "I2C-Adapter doesn't support I2C_FUNC_I2C\n");\r
- return -EIO;\r
- }\r
-\r
- sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);\r
- if (!sensor)\r
- return -ENOMEM;\r
-\r
- v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);\r
-\r
- /* Second stage probe - when a capture adapter is there */\r
- icd->ops = &sensor_ops;\r
-\r
- sensor->info_priv.fmt = sensor_colour_fmts[0];\r
- \r
- #if CONFIG_SENSOR_I2C_NOSCHED\r
- atomic_set(&sensor->tasklock_cnt,0);\r
- #endif\r
-\r
- ret = sensor_video_probe(icd, client);\r
- if (ret < 0) {\r
- icd->ops = NULL;\r
- i2c_set_clientdata(client, NULL);\r
- kfree(sensor);\r
- sensor = NULL;\r
- }\r
- hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);\r
- SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);\r
- return ret;\r
+ return;\r
}\r
\r
-static int sensor_remove(struct i2c_client *client)\r
-{\r
- struct sensor *sensor = to_sensor(client);\r
- struct soc_camera_device *icd = client->dev.platform_data;\r
-\r
- icd->ops = NULL;\r
- i2c_set_clientdata(client, NULL);\r
- client->driver = NULL;\r
- kfree(sensor);\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
\r
- return 0;\r
-}\r
+sensor_init_parameters_default_code();\r
\r
-static const struct i2c_device_id sensor_id[] = {\r
- {SENSOR_NAME_STRING(), 0 },\r
- { }\r
-};\r
-MODULE_DEVICE_TABLE(i2c, sensor_id);\r
-\r
-static struct i2c_driver sensor_i2c_driver = {\r
- .driver = {\r
- .name = SENSOR_NAME_STRING(),\r
- },\r
- .probe = sensor_probe,\r
- .remove = sensor_remove,\r
- .id_table = sensor_id,\r
-};\r
+sensor_v4l2_struct_initialization();\r
\r
-static int __init sensor_mod_init(void)\r
-{\r
- SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());\r
- return i2c_add_driver(&sensor_i2c_driver);\r
-}\r
+sensor_probe_default_code();\r
\r
-static void __exit sensor_mod_exit(void)\r
-{\r
- i2c_del_driver(&sensor_i2c_driver);\r
-}\r
+sensor_remove_default_code();\r
\r
-device_initcall_sync(sensor_mod_init);\r
-module_exit(sensor_mod_exit);\r
+sensor_driver_default_module_code();\r
\r
-MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));\r
-MODULE_AUTHOR("ddl <kernel@rock-chips>");\r
-MODULE_LICENSE("GPL");\r
\r
\r
\r
--- /dev/null
+/*\r
+o* Driver for MT9M001 CMOS Image Sensor from Micron\r
+ *\r
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ */\r
+\r
+#include <linux/videodev2.h>\r
+#include <linux/slab.h>\r
+#include <linux/i2c.h>\r
+#include <linux/log2.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/delay.h>\r
+#include <linux/circ_buf.h>\r
+#include <linux/miscdevice.h>\r
+#include <media/v4l2-common.h>\r
+#include <media/v4l2-chip-ident.h>\r
+#include <media/soc_camera.h>\r
+#include <plat/rk_camera.h>\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)\r
+#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)\r
+\r
+\r
+#define _CONS(a,b) a##b\r
+#define CONS(a,b) _CONS(a,b)\r
+\r
+#define __STR(x) #x\r
+#define _STR(x) __STR(x)\r
+#define STR(x) _STR(x)\r
+\r
+#define MIN(x,y) ((x<y) ? x: y)\r
+#define MAX(x,y) ((x>y) ? x: y)\r
+\r
+/* Sensor Driver Configuration */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GC2035\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GC2035\r
+#define SENSOR_ID 0x2035\r
+#define SENSOR_MIN_WIDTH 800\r
+#define SENSOR_MIN_HEIGHT 600\r
+#define SENSOR_MAX_WIDTH 1600\r
+#define SENSOR_MAX_HEIGHT 1200\r
+#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */\r
+#define SENSOR_INIT_HEIGHT 600\r
+#define SENSOR_INIT_WINSEQADR sensor_svga\r
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8\r
+\r
+#define CONFIG_SENSOR_WhiteBalance 1\r
+#define CONFIG_SENSOR_Brightness 0\r
+#define CONFIG_SENSOR_Contrast 0\r
+#define CONFIG_SENSOR_Saturation 0\r
+#define CONFIG_SENSOR_Effect 1\r
+#define CONFIG_SENSOR_Scene 1\r
+#define CONFIG_SENSOR_DigitalZoom 0\r
+#define CONFIG_SENSOR_Focus 0\r
+#define CONFIG_SENSOR_Exposure 0\r
+#define CONFIG_SENSOR_Flash 1\r
+#define CONFIG_SENSOR_Mirror 0\r
+#define CONFIG_SENSOR_Flip 0\r
+\r
+#define CONFIG_SENSOR_I2C_SPEED 100000 /* Hz */\r
+/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */\r
+#define CONFIG_SENSOR_I2C_NOSCHED 0\r
+#define CONFIG_SENSOR_I2C_RDWRCHK 0\r
+\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\\r
+ SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+\r
+#define COLOR_TEMPERATURE_CLOUDY_DN 6500\r
+#define COLOR_TEMPERATURE_CLOUDY_UP 8000\r
+#define COLOR_TEMPERATURE_CLEARDAY_DN 5000\r
+#define COLOR_TEMPERATURE_CLEARDAY_UP 6500\r
+#define COLOR_TEMPERATURE_OFFICE_DN 3500\r
+#define COLOR_TEMPERATURE_OFFICE_UP 5000\r
+#define COLOR_TEMPERATURE_HOME_DN 2500\r
+#define COLOR_TEMPERATURE_HOME_UP 3500\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SENSOR_AF_IS_ERR (0x00<<0)\r
+#define SENSOR_AF_IS_OK (0x01<<0)\r
+#define SENSOR_INIT_IS_ERR (0x00<<28)\r
+#define SENSOR_INIT_IS_OK (0x01<<28)\r
+\r
+struct reginfo\r
+{\r
+ u8 reg;\r
+ u8 val;\r
+};\r
+\r
+//flash off in fixed time to prevent from too hot , zyc\r
+struct flash_timer{\r
+ struct soc_camera_device *icd;\r
+ struct hrtimer timer;\r
+};\r
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer);\r
+\r
+static struct flash_timer flash_off_timer;\r
+//for user defined if user want to customize the series , zyc\r
+\r
+/* init 352X288 SVGA */\r
+static struct reginfo sensor_init_data[] ={\r
+ {0xfe , 0x80},\r
+ {0xfe , 0x80},\r
+ {0xfe , 0x80}, \r
+ {0xfc , 0x06},\r
+ {0xf2 , 0x00},\r
+ {0xf3 , 0x00},\r
+ {0xf4 , 0x00},\r
+ {0xf5 , 0x00},\r
+ {0xf9 , 0xfe}, //[0] pll enable\r
+ {0xfa , 0x00},\r
+ {0xf6 , 0x00},\r
+ {0xf7 , 0x15}, //pll enable\r
+\r
+ {0xf8 , 0x85},\r
+ {0xfe , 0x00},\r
+ {0x82 , 0x00},\r
+ {0xb3 , 0x60},\r
+ {0xb4 , 0x40},\r
+ {0xb5 , 0x60},\r
+\r
+ {0x03 , 0x02},\r
+ {0x04 , 0x80},\r
+\r
+ //////////measure window ///////////\r
+ {0xfe , 0x00},\r
+ {0xec , 0x06},//04 \r
+ {0xed , 0x06},//04 \r
+ {0xee , 0x62},//60 \r
+ {0xef , 0x92},//90 \r
+\r
+ ///////////analog/////////////\r
+ {0x0a , 0x00}, //row start\r
+ {0x0c , 0x00}, //col start\r
+ {0x0d , 0x04},\r
+ {0x0e , 0xc0},\r
+ {0x0f , 0x06}, //Window setting\r
+ {0x10 , 0x58}, \r
+ {0x17 , 0x14}, //[0]mirror [1]flip\r
+\r
+\r
+ {0x18 , 0x0e}, //sdark 4 row in even frame??\r
+ {0x19 , 0x0c}, //AD pipe number\r
+\r
+ /*\r
+ /// ë´Ì ÏÖÏó\r
+ {0x18 , 0x0a}, //sdark 4 row in even frame??\r
+ {0x19 , 0x0a}, //AD pipe number\r
+ */\r
+ \r
+ {0x1a , 0x01}, //CISCTL mode4\r
+ {0x1b , 0x8b},\r
+ {0x1e , 0x88}, //analog mode1 [7] tx-high en [5:3]COL_bias\r
+ {0x1f , 0x08}, //[3] tx-low en//\r
+ {0x20 , 0x05}, //[0]adclk mode , 0x[1]rowclk_MODE [2]rsthigh_en\r
+ {0x21 , 0x0f}, //[6:4]rsg\r
+ {0x22 , 0xf0}, //[3:0]vref\r
+ {0x23 , 0xc3}, //f3//ADC_r\r
+ {0x24 , 0x17}, //pad drive 16\r
+\r
+ //AEC\r
+ {0xfe , 0x01},\r
+ {0x11 , 0x20},//AEC_out_slope , 0x\r
+ {0x1f , 0xc0},//max_post_gain\r
+ {0x20 , 0x60},//max_pre_gain\r
+ {0x47 , 0x30},//AEC_outdoor_th\r
+ {0x0b , 0x10},//\r
+ {0x13 , 0x75},//y_target\r
+ {0xfe , 0x00},\r
+\r
+\r
+ {0x05 , 0x01},//hb\r
+ {0x06 , 0x11},\r
+ {0x07 , 0x00},//vb\r
+ {0x08 , 0x50},\r
+ {0xfe , 0x01},\r
+ {0x27 , 0x00},//step\r
+ {0x28 , 0xa0},\r
+ {0x29 , 0x05},//level1\r
+ {0x2a , 0x00},\r
+ {0x2b , 0x05},//level2\r
+ {0x2c , 0x00},\r
+ {0x2d , 0x06},//6e8//level3\r
+ {0x2e , 0xe0},\r
+ {0x2f , 0x0a},//level4\r
+ {0x30 , 0x00},\r
+ {0x3e , 0x40},\r
+ {0xfe , 0x00},\r
+ {0xfe , 0x00}, //0x , 0x , 0x , 0x , 0x \r
+ {0xb6 , 0x03}, //AEC enable\r
+ {0xfe , 0x00},\r
+\r
+ /////////BLK//////\r
+ {0x3f , 0x00}, //prc close\r
+ {0x40 , 0x77},//\r
+ {0x42 , 0x7f},\r
+ {0x43 , 0x30},\r
+ {0x5c , 0x08},\r
+ {0x5e , 0x20},\r
+ {0x5f , 0x20},\r
+ {0x60 , 0x20},\r
+ {0x61 , 0x20},\r
+ {0x62 , 0x20},\r
+ {0x63 , 0x20},\r
+ {0x64 , 0x20},\r
+ {0x65 , 0x20},\r
+\r
+ ///block////////////\r
+ {0x80 , 0xff},\r
+ {0x81 , 0x26},//38 , 0x//skin_Y 8c_debug\r
+ {0x87 , 0x90}, //[7]middle gamma \r
+ {0x84 , 0x00}, //output put foramat\r
+ {0x86 , 0x07}, //02 //sync plority \r
+ {0x8b , 0xbc},\r
+ {0xb0 , 0x80}, //globle gain\r
+ {0xc0 , 0x40},//Yuv bypass\r
+\r
+ //////lsc/////////////\r
+ {0xfe , 0x01},\r
+ {0xc2 , 0x38},\r
+ {0xc3 , 0x25},\r
+ {0xc4 , 0x21},\r
+ {0xc8 , 0x19},\r
+ {0xc9 , 0x12},\r
+ {0xca , 0x0e},\r
+ {0xbc , 0x43},\r
+ {0xbd , 0x18},\r
+ {0xbe , 0x1b},\r
+ {0xb6 , 0x40},\r
+ {0xb7 , 0x2e},\r
+ {0xb8 , 0x26},\r
+ {0xc5 , 0x05},\r
+ {0xc6 , 0x03},\r
+ {0xc7 , 0x04},\r
+ {0xcb , 0x00},\r
+ {0xcc , 0x00},\r
+ {0xcd , 0x00},\r
+ {0xbf , 0x14},\r
+ {0xc0 , 0x22},\r
+ {0xc1 , 0x1b},\r
+ {0xb9 , 0x00},\r
+ {0xba , 0x05},\r
+ {0xbb , 0x05},\r
+ {0xaa , 0x35},\r
+ {0xab , 0x33},\r
+ {0xac , 0x33},\r
+ {0xad , 0x25},\r
+ {0xae , 0x22},\r
+ {0xaf , 0x27},\r
+ {0xb0 , 0x1d},\r
+ {0xb1 , 0x20},\r
+ {0xb2 , 0x22},\r
+ {0xb3 , 0x14},\r
+ {0xb4 , 0x15},\r
+ {0xb5 , 0x16},\r
+ {0xd0 , 0x00},\r
+ {0xd2 , 0x07},\r
+ {0xd3 , 0x08},\r
+ {0xd8 , 0x00},\r
+ {0xda , 0x13},\r
+ {0xdb , 0x17},\r
+ {0xdc , 0x00},\r
+ {0xde , 0x0a},\r
+ {0xdf , 0x08},\r
+ {0xd4 , 0x00},\r
+ {0xd6 , 0x00},\r
+ {0xd7 , 0x0c},\r
+ {0xa4 , 0x00},\r
+ {0xa5 , 0x00},\r
+ {0xa6 , 0x00},\r
+ {0xa7 , 0x00},\r
+ {0xa8 , 0x00},\r
+ {0xa9 , 0x00},\r
+ {0xa1 , 0x80},\r
+ {0xa2 , 0x80},\r
+\r
+ //////////cc//////////////\r
+ {0xfe , 0x02},\r
+ {0xc0 , 0x01},\r
+ {0xc1 , 0x40}, //Green_cc for d\r
+ {0xc2 , 0xfc},\r
+ {0xc3 , 0x05},\r
+ {0xc4 , 0xec},\r
+ {0xc5 , 0x42},\r
+ {0xc6 , 0xf8},\r
+ {0xc7 , 0x40},//for cwf \r
+ {0xc8 , 0xf8},\r
+ {0xc9 , 0x06},\r
+ {0xca , 0xfd},\r
+ {0xcb , 0x3e},\r
+ {0xcc , 0xf3},\r
+ {0xcd , 0x36},//for A\r
+ {0xce , 0xf6},\r
+ {0xcf , 0x04},\r
+ {0xe3 , 0x0c},\r
+ {0xe4 , 0x44},\r
+ {0xe5 , 0xe5},\r
+ {0xfe , 0x00},\r
+\r
+ ///////awb start ////////////////\r
+ //AWB clear\r
+ {0xfe , 0x01},\r
+ {0x4f , 0x00},\r
+ {0x4d , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x10}, // 10\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x20}, // 20\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x30},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00}, // 30\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x40}, // 40\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x50}, // 50\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x60}, // 60\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x70}, // 70\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x80}, // 80\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0x90}, // 90\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0xa0}, // a0\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0xb0}, // b0\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0xc0}, // c0\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4d , 0xd0}, // d0\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x00},\r
+ {0x4f , 0x01},\r
+ /////// awb value////////\r
+ {0xfe , 0x01},\r
+ {0x4f , 0x00},\r
+ {0x4d , 0x30},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x80},\r
+ {0x4e , 0x80},\r
+ {0x4e , 0x02},\r
+ {0x4e , 0x02},\r
+ {0x4d , 0x40},\r
+ {0x4e , 0x00},\r
+ {0x4e , 0x80},\r
+ {0x4e , 0x80},\r
+ {0x4e , 0x02},\r
+ {0x4e , 0x02},\r
+ {0x4e , 0x02},\r
+ {0x4d , 0x53},\r
+ {0x4e , 0x08},\r
+ {0x4e , 0x04},\r
+ {0x4d , 0x62},\r
+ {0x4e , 0x10},\r
+ {0x4d , 0x72},\r
+ {0x4e , 0x20},\r
+ {0x4f , 0x01},\r
+\r
+ /////awb////\r
+ {0xfe , 0x01},\r
+ {0x50 , 0x88},//c0//[6]green mode\r
+ {0x52 , 0x40},\r
+ {0x54 , 0x60},\r
+ {0x56 , 0x06},\r
+ {0x57 , 0x20}, //pre adjust\r
+ {0x58 , 0x01}, \r
+ {0x5b , 0x02}, //AWB_gain_delta\r
+ {0x61 , 0xaa},//R/G stand\r
+ {0x62 , 0xaa},//R/G stand\r
+ {0x71 , 0x00},\r
+ {0x74 , 0x10}, //0x//AWB_C_max\r
+ {0x77 , 0x08}, // 0x//AWB_p2_x\r
+ {0x78 , 0xfd}, //AWB_p2_y\r
+ {0x86 , 0x30},\r
+ {0x87 , 0x00},\r
+ {0x88 , 0x04},//06 , 0x//[1]dark mode\r
+ {0x8a , 0xc0},//awb move mode\r
+ {0x89 , 0x75},\r
+ {0x84 , 0x08}, //0x//auto_window\r
+ {0x8b , 0x00}, // 0x//awb compare luma\r
+ {0x8d , 0x70}, //awb gain limit R \r
+ {0x8e , 0x70},//G\r
+ {0x8f , 0xf4},//B\r
+ {0xfe , 0x00},\r
+ {0x82 , 0x02},//awb_en\r
+ /////////awb end /////////////\r
+ \r
+ ///==========asde\r
+ {0xfe , 0x01},\r
+ {0x21 , 0xbf},\r
+ {0xfe , 0x02},\r
+ {0xa4 , 0x00},//\r
+ {0xa5 , 0x40}, //lsc_th\r
+ {0xa2 , 0xa0}, //lsc_dec_slope\r
+ {0xa6 , 0x80}, //dd_th\r
+ {0xa7 , 0x80}, //ot_th\r
+ {0xab , 0x31}, //\r
+ {0xa9 , 0x6f}, //\r
+ {0xb0 , 0x99}, //0x//edge effect slope low\r
+ {0xb1 , 0x34},//edge effect slope low\r
+ {0xb3 , 0x80}, //saturation dec slope\r
+ {0xde , 0xb6}, //\r
+ {0x38 , 0x0f}, // \r
+ {0x39 , 0x60}, //\r
+ {0xfe , 0x00},\r
+ {0x81 , 0x26},\r
+ {0xfe , 0x02},\r
+ {0x83 , 0x00},//\r
+ {0x84 , 0x45},//\r
+ ////////////YCP//////////\r
+ {0xd1 , 0x38},//saturation_cb\r
+ {0xd2 , 0x38},//saturation_Cr\r
+ {0xd3 , 0x40},//contrast ?\r
+ {0xd4 , 0x80},//contrast center \r
+ {0xd5 , 0x00},//luma_offset \r
+ {0xdc , 0x30},\r
+ {0xdd , 0xb8},//edge_sa_g,b\r
+ {0xfe , 0x00},\r
+ ///////dndd///////////\r
+ {0xfe , 0x02},\r
+ {0x88 , 0x15},//dn_b_base\r
+ {0x8c , 0xf6}, //[2]b_in_dark_inc\r
+ {0x89 , 0x03}, //dn_c_weight\r
+ ////////EE ///////////\r
+ {0xfe , 0x02},\r
+ {0x90 , 0x6c},// EEINTP mode1\r
+ {0x97 , 0x45},// edge effect\r
+ ////==============RGB Gamma \r
+ {0xfe , 0x02},\r
+ {0x15 , 0x0a},\r
+ {0x16 , 0x12},\r
+ {0x17 , 0x19},\r
+ {0x18 , 0x1f},\r
+ {0x19 , 0x2c},\r
+ {0x1a , 0x38},\r
+ {0x1b , 0x42},\r
+ {0x1c , 0x4e},\r
+ {0x1d , 0x63},\r
+ {0x1e , 0x76},\r
+ {0x1f , 0x87},\r
+ {0x20 , 0x96},\r
+ {0x21 , 0xa2},\r
+ {0x22 , 0xb8},\r
+ {0x23 , 0xca},\r
+ {0x24 , 0xd8},\r
+ {0x25 , 0xe3},\r
+ {0x26 , 0xf0},\r
+ {0x27 , 0xf8},\r
+ {0x28 , 0xfd},\r
+ {0x29 , 0xff},\r
+\r
+ ///=================y gamma\r
+ {0xfe , 0x02},\r
+ {0x2b , 0x00},\r
+ {0x2c , 0x04},\r
+ {0x2d , 0x09},\r
+ {0x2e , 0x18},\r
+ {0x2f , 0x27},\r
+ {0x30 , 0x37},\r
+ {0x31 , 0x49},\r
+ {0x32 , 0x5c},\r
+ {0x33 , 0x7e},\r
+ {0x34 , 0xa0},\r
+ {0x35 , 0xc0},\r
+ {0x36 , 0xe0},\r
+ {0x37 , 0xff},\r
+ /////1600x1200size// \r
+ {0xfe , 0x00},//\r
+ {0x90 , 0x01}, //0x//crop enable\r
+ {0x95 , 0x04}, //0x//1600x1200\r
+ {0x96 , 0xb0},\r
+ {0x97 , 0x06},\r
+ {0x98 , 0x40},\r
+\r
+ {0xfe , 0x03},\r
+ {0x42 , 0x40}, \r
+ {0x43 , 0x06}, //output buf width\r
+ {0x41 , 0x02}, // Pclk_polarity\r
+ {0x40 , 0x40}, //00 \r
+ {0x17 , 0x00}, //widv \r
+ {0xfe , 0x00},\r
+ ////output DVP/////\r
+ {0xfe , 0x00},\r
+ {0xb6 , 0x03},\r
+ {0xf7 , 0x15},\r
+\r
+ {0xc8 , 0x00},//close scaler\r
+ {0x99 , 0x22},// 1/2 subsample\r
+ {0x9a , 0x06},\r
+ {0x9b , 0x00},\r
+ {0x9c , 0x00},\r
+ {0x9d , 0x00},\r
+ {0x9e , 0x00},\r
+ {0x9f , 0x00},\r
+ {0xa0 , 0x00}, \r
+ {0xa1 , 0x00},\r
+ {0xa2 ,0x00},\r
+ \r
+ {0x90 , 0x01}, //crop enable\r
+ {0x94 , 0x02},\r
+ {0x95 , 0x02},\r
+ {0x96 , 0x58},\r
+ {0x97 , 0x03},\r
+ {0x98 , 0x20},\r
+ {0xfe , 0x00},\r
+ {0x82 , 0xfe}, // fe\r
+ {0xf2 , 0x70}, \r
+ {0xf3 , 0xff},\r
+ {0xf4 , 0x00},\r
+ {0xf5 , 0x30},\r
+ \r
+ #if 0 \r
+ ///////// re zao///\r
+ {0xfe,0x00},\r
+ {0x22,0xd0},\r
+ {0xfe,0x01},\r
+ {0x21,0xff},\r
+ {0xfe,0x02}, \r
+ {0x8a,0x33},\r
+ {0x8c,0x76},\r
+ {0x8d,0x85},\r
+ {0xa6,0xf0}, \r
+ {0xae,0x9f},\r
+ {0xa2,0x90},\r
+ {0xa5,0x40}, \r
+ {0xa7,0x30},\r
+ {0xb0,0x88},\r
+ {0x38,0x0b},\r
+ {0x39,0x30},\r
+ {0xfe,0x00}, \r
+ {0x87,0xb0},\r
+\r
+ //// small RGB gamma////\r
+ {0xfe , 0x02},\r
+ {0x15 , 0x0b},\r
+ {0x16 , 0x0e},\r
+ {0x17 , 0x10},\r
+ {0x18 , 0x12},\r
+ {0x19 , 0x19},\r
+ {0x1a , 0x21},\r
+ {0x1b , 0x29},\r
+ {0x1c , 0x31},\r
+ {0x1d , 0x41},\r
+ {0x1e , 0x50},\r
+ {0x1f , 0x5f},\r
+ {0x20 , 0x6d},\r
+ {0x21 , 0x79},\r
+ {0x22 , 0x91},\r
+ {0x23 , 0xa5},\r
+ {0x24 , 0xb9},\r
+ {0x25 , 0xc9},\r
+ {0x26 , 0xe1},\r
+ {0x27 , 0xee},\r
+ {0x28 , 0xf7},\r
+ {0x29 , 0xff},\r
+ \r
+ ////dark sun/////\r
+ {0xfe , 0x02},\r
+ {0x40 , 0x06},\r
+ {0x41 , 0x23},\r
+ {0x42 , 0x3f},\r
+ {0x43 , 0x06},\r
+ {0x44 , 0x00},\r
+ {0x45 , 0x00},\r
+ {0x46 , 0x14},\r
+ {0x47 , 0x09},\r
+ \r
+ #endif\r
+\r
+ {0x00,0x00}, \r
+};\r
+ \r
+\r
+\r
+/* 1600X1200 UXGA */\r
+static struct reginfo sensor_uxga[] = \r
+{\r
+ \r
+ \r
+ {0xfe , 0x00},\r
+ {0xc8 , 0x00},\r
+ {0xf7 , 0x17},\r
+\r
+ {0x99 , 0x11}, // disable sambsample\r
+ {0x9a , 0x06},\r
+ {0x9b , 0x00},\r
+ {0x9c , 0x00},\r
+ {0x9d , 0x00},\r
+ {0x9e , 0x00},\r
+ {0x9f , 0x00},\r
+ {0xa0 , 0x00}, \r
+ {0xa1 , 0x00},\r
+ {0xa2 , 0x00},\r
+ \r
+ {0x90 , 0x01},\r
+ {0x95 , 0x04},\r
+ {0x96 , 0xb0}, \r
+ {0x97 , 0x06},\r
+ {0x98 , 0x40},\r
+ \r
+ {0x00 , 0x00}, \r
+\r
+\r
+};\r
+\r
+ \r
+\r
+/* 1280X1024 SXGA */\r
+static struct reginfo sensor_sxga[] =\r
+{\r
+ \r
+ {0x00,0x00}, \r
+};\r
+\r
+/* 800X600 SVGA*/\r
+static struct reginfo sensor_svga[] =\r
+{ \r
+ {0xfe , 0x00},\r
+ {0xb6 , 0x03},\r
+ {0xf7 , 0x15},\r
+\r
+ {0xc8 , 0x00},//close scaler\r
+ {0x99 , 0x22},// 1/2 subsample\r
+ {0x9a , 0x06},\r
+ {0x9b , 0x00},\r
+ {0x9c , 0x00},\r
+ {0x9d , 0x00},\r
+ {0x9e , 0x00},\r
+ {0x9f , 0x00},\r
+ {0xa0 , 0x00}, \r
+ {0xa1 , 0x00},\r
+ {0xa2 , 0x00},\r
+ \r
+ {0x90 , 0x01}, //crop enable\r
+ {0x94 , 0x02},\r
+ {0x95 , 0x02},\r
+ {0x96 , 0x58},\r
+ {0x97 , 0x03},\r
+ {0x98 , 0x20},\r
+ {0x00,0x00}, \r
+};\r
+ \r
+ \r
+\r
+/* 640X480 VGA */\r
+static struct reginfo sensor_vga[] =\r
+{\r
+ \r
+\r
+ {0x00 , 0x00},\r
+};\r
+\r
+/* 352X288 CIF */\r
+static struct reginfo sensor_cif[] =\r
+{\r
+ {0x00,0x00}, \r
+};\r
+\r
+/* 320*240 QVGA */\r
+static struct reginfo sensor_qvga[] =\r
+{\r
+ \r
+\r
+ {0x00,0x00}, \r
+};\r
+\r
+/* 176X144 QCIF*/\r
+static struct reginfo sensor_qcif[] =\r
+{\r
+ \r
+ {0x00,0x00}, \r
+};\r
+\r
+static struct reginfo sensor_ClrFmt_YUYV[]=\r
+{\r
+ \r
+ {0x00,0x00}, \r
+};\r
+\r
+static struct reginfo sensor_ClrFmt_UYVY[]=\r
+{\r
+ {0x00,0x00}, \r
+};\r
+\r
+#if CONFIG_SENSOR_WhiteBalance\r
+static struct reginfo sensor_WhiteB_Auto[]=\r
+{\r
+ {0xfe, 0x00},\r
+ {0xb3, 0x61},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0x61},\r
+ {0x82, 0xfe},\r
+ {0x00,0x00}, \r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct reginfo sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0xfe, 0x00},\r
+ {0x82, 0xfc},\r
+ {0xb3, 0x58},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0x50}, \r
+ {0x00,0x00}, \r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct reginfo sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0xfe, 0x00},\r
+ {0x82, 0xfc},\r
+ {0xb3, 0x78},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0x50},\r
+ {0x00,0x00}, \r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct reginfo sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0xfe, 0x00},\r
+ {0x82, 0xfc},\r
+ {0xb3, 0x50},\r
+ {0xb4, 0x40},\r
+ {0xb5, 0xa8},\r
+ {0x00,0x00}, \r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct reginfo sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0xfe, 0x00},\r
+ {0x82, 0xfc},\r
+ {0xb3, 0xa0},\r
+ {0xb4, 0x45},\r
+ {0xb5, 0x40},\r
+ {0x00, 0x00}, \r
+};\r
+static struct reginfo *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+#endif\r
+\r
+#if CONFIG_SENSOR_Brightness\r
+static struct reginfo sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ \r
+ {0xfe, 0x01},\r
+ {0x13, 0x70},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0xe0},\r
+ {0x00, 0x00},\r
+};\r
+\r
+static struct reginfo sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ \r
+ {0xfe, 0x01},\r
+ {0x13, 0x78},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0xf0},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ {0xfe, 0x01},\r
+ {0x13, 0x80},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0x00},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0xfe, 0x01},\r
+ {0x13, 0x88},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0x10},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0xfe, 0x01},\r
+ {0x13, 0x90},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0x20},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0xfe, 0x01},\r
+ {0x13, 0x98},\r
+ {0xfe, 0x02},\r
+ {0xd5, 0x30},\r
+\r
+ {0x00, 0x00}\r
+};\r
+static struct reginfo *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+#endif\r
+\r
+#if CONFIG_SENSOR_Effect\r
+static struct reginfo sensor_Effect_Normal[] =\r
+{\r
+ {0xfe, 0x00},\r
+ {0x83, 0xe0},\r
+ {0x00, 0x00} \r
+};\r
+\r
+static struct reginfo sensor_Effect_WandB[] =\r
+{\r
+ {0xfe, 0x00},\r
+ {0x83, 0x12}, \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Effect_Sepia[] =\r
+{\r
+ {0xfe, 0x00},\r
+ {0x83, 0x82},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0xfe, 0x00},\r
+ {0x83, 0x01},\r
+ {0x00, 0x00}\r
+};\r
+static struct reginfo sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0xfe, 0x00},\r
+ {0x83, 0x62},\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0xfe, 0x00},\r
+ {0x83, 0x52},\r
+ {0x00, 0x00}\r
+};\r
+static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+static struct reginfo sensor_Exposure0[]=\r
+{\r
+ //-3\r
+ \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure1[]=\r
+{\r
+ //-2\r
+ \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure2[]=\r
+{\r
+ //-0.3EV\r
+\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure3[]=\r
+{\r
+ //default\r
+ \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure4[]=\r
+{\r
+ // 1\r
+\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure5[]=\r
+{\r
+ // 2\r
+ \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Exposure6[]=\r
+{\r
+ // 3\r
+ \r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+static struct reginfo sensor_Saturation0[]=\r
+{\r
+\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Saturation1[]=\r
+{\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Saturation2[]=\r
+{\r
+ {0x00, 0x00}\r
+};\r
+static struct reginfo *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+static struct reginfo sensor_Contrast0[]=\r
+{\r
+ //Contrast -3\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Contrast1[]=\r
+{\r
+ //Contrast -2\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Contrast2[]=\r
+{\r
+ // Contrast -1\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Contrast3[]=\r
+{\r
+ //Contrast 0\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Contrast4[]=\r
+{\r
+ //Contrast +1\r
+ {0x00, 0x00}\r
+};\r
+\r
+\r
+static struct reginfo sensor_Contrast5[]=\r
+{\r
+ //Contrast +2\r
+ {0x00, 0x00}\r
+};\r
+\r
+static struct reginfo sensor_Contrast6[]=\r
+{\r
+ \r
+ //Contrast +3\r
+ {0x00, 0x00}\r
+\r
+};\r
+static struct reginfo *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+static struct reginfo sensor_MirrorOn[]=\r
+{\r
+ {0x17 , 0x14},\r
+ {0x00 , 0x00}\r
+};\r
+\r
+static struct reginfo sensor_MirrorOff[]=\r
+{\r
+ {0x17 , 0x15},\r
+ {0x00 , 0x00}\r
+};\r
+static struct reginfo *sensor_MirrorSeqe[] = {sensor_MirrorOff, sensor_MirrorOn,NULL,};\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+static struct reginfo sensor_FlipOn[]=\r
+{\r
+ {0x17 , 0x16},\r
+ {0x00 , 0x00}\r
+};\r
+\r
+static struct reginfo sensor_FlipOff[]=\r
+{\r
+ {0x17 , 0x17},\r
+ {0x00 , 0x00}\r
+};\r
+static struct reginfo *sensor_FlipSeqe[] = {sensor_FlipOff, sensor_FlipOn,NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_Scene\r
+static struct reginfo sensor_SceneAuto[] =\r
+{\r
+{0xfe,0x01},\r
+{0x3e,0x40}, \r
+{0xfe,0x00},\r
+\r
+{0x00,0x00}\r
+};\r
+\r
+static struct reginfo sensor_SceneNight[] =\r
+{\r
+{0xfe,0x01},\r
+{0x3e,0x60}, \r
+{0xfe,0x00},\r
+{0x00,0x00}\r
+\r
+};\r
+static struct reginfo *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+static struct reginfo sensor_Zoom0[] =\r
+{\r
+ {0x0, 0x0},\r
+};\r
+\r
+static struct reginfo sensor_Zoom1[] =\r
+{\r
+ {0x0, 0x0},\r
+};\r
+\r
+static struct reginfo sensor_Zoom2[] =\r
+{\r
+ {0x0, 0x0},\r
+};\r
+\r
+\r
+static struct reginfo sensor_Zoom3[] =\r
+{\r
+ {0x0, 0x0},\r
+};\r
+static struct reginfo *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+#endif\r
+static const struct v4l2_querymenu sensor_menus[] =\r
+{\r
+ #if CONFIG_SENSOR_WhiteBalance\r
+ { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 0, .name = "auto", .reserved = 0, }, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 1, .name = "incandescent", .reserved = 0,},\r
+ { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 2, .name = "fluorescent", .reserved = 0,}, { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 3, .name = "daylight", .reserved = 0,},\r
+ { .id = V4L2_CID_DO_WHITE_BALANCE, .index = 4, .name = "cloudy-daylight", .reserved = 0,},\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Effect\r
+ { .id = V4L2_CID_EFFECT, .index = 0, .name = "none", .reserved = 0, }, { .id = V4L2_CID_EFFECT, .index = 1, .name = "mono", .reserved = 0,},\r
+ { .id = V4L2_CID_EFFECT, .index = 2, .name = "negative", .reserved = 0,}, { .id = V4L2_CID_EFFECT, .index = 3, .name = "sepia", .reserved = 0,},\r
+ { .id = V4L2_CID_EFFECT, .index = 4, .name = "posterize", .reserved = 0,} ,{ .id = V4L2_CID_EFFECT, .index = 5, .name = "aqua", .reserved = 0,},\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Scene\r
+ { .id = V4L2_CID_SCENE, .index = 0, .name = "auto", .reserved = 0,} ,{ .id = V4L2_CID_SCENE, .index = 1, .name = "night", .reserved = 0,},\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Flash\r
+ { .id = V4L2_CID_FLASH, .index = 0, .name = "off", .reserved = 0, }, { .id = V4L2_CID_FLASH, .index = 1, .name = "auto", .reserved = 0,},\r
+ { .id = V4L2_CID_FLASH, .index = 2, .name = "on", .reserved = 0,}, { .id = V4L2_CID_FLASH, .index = 3, .name = "torch", .reserved = 0,},\r
+ #endif\r
+};\r
+\r
+static struct v4l2_queryctrl sensor_controls[] =\r
+{\r
+ #if CONFIG_SENSOR_WhiteBalance\r
+ {\r
+ .id = V4L2_CID_DO_WHITE_BALANCE,\r
+ .type = V4L2_CTRL_TYPE_MENU,\r
+ .name = "White Balance Control",\r
+ .minimum = 0,\r
+ .maximum = 4,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Brightness\r
+ {\r
+ .id = V4L2_CID_BRIGHTNESS,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Brightness Control",\r
+ .minimum = -3,\r
+ .maximum = 2,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Effect\r
+ {\r
+ .id = V4L2_CID_EFFECT,\r
+ .type = V4L2_CTRL_TYPE_MENU,\r
+ .name = "Effect Control",\r
+ .minimum = 0,\r
+ .maximum = 5,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Exposure\r
+ {\r
+ .id = V4L2_CID_EXPOSURE,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Exposure Control",\r
+ .minimum = 0,\r
+ .maximum = 6,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Saturation\r
+ {\r
+ .id = V4L2_CID_SATURATION,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Saturation Control",\r
+ .minimum = 0,\r
+ .maximum = 2,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Contrast\r
+ {\r
+ .id = V4L2_CID_CONTRAST,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Contrast Control",\r
+ .minimum = -3,\r
+ .maximum = 3,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Mirror\r
+ {\r
+ .id = V4L2_CID_HFLIP,\r
+ .type = V4L2_CTRL_TYPE_BOOLEAN,\r
+ .name = "Mirror Control",\r
+ .minimum = 0,\r
+ .maximum = 1,\r
+ .step = 1,\r
+ .default_value = 1,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Flip\r
+ {\r
+ .id = V4L2_CID_VFLIP,\r
+ .type = V4L2_CTRL_TYPE_BOOLEAN,\r
+ .name = "Flip Control",\r
+ .minimum = 0,\r
+ .maximum = 1,\r
+ .step = 1,\r
+ .default_value = 1,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Scene\r
+ {\r
+ .id = V4L2_CID_SCENE,\r
+ .type = V4L2_CTRL_TYPE_MENU,\r
+ .name = "Scene Control",\r
+ .minimum = 0,\r
+ .maximum = 1,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_DigitalZoom\r
+ {\r
+ .id = V4L2_CID_ZOOM_RELATIVE,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "DigitalZoom Control",\r
+ .minimum = -1,\r
+ .maximum = 1,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ }, {\r
+ .id = V4L2_CID_ZOOM_ABSOLUTE,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "DigitalZoom Control",\r
+ .minimum = 0,\r
+ .maximum = 3,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Focus\r
+ {\r
+ .id = V4L2_CID_FOCUS_RELATIVE,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Focus Control",\r
+ .minimum = -1,\r
+ .maximum = 1,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ }, {\r
+ .id = V4L2_CID_FOCUS_ABSOLUTE,\r
+ .type = V4L2_CTRL_TYPE_INTEGER,\r
+ .name = "Focus Control",\r
+ .minimum = 0,\r
+ .maximum = 255,\r
+ .step = 1,\r
+ .default_value = 125,\r
+ },\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Flash\r
+ {\r
+ .id = V4L2_CID_FLASH,\r
+ .type = V4L2_CTRL_TYPE_MENU,\r
+ .name = "Flash Control",\r
+ .minimum = 0,\r
+ .maximum = 3,\r
+ .step = 1,\r
+ .default_value = 0,\r
+ },\r
+ #endif\r
+};\r
+\r
+static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *did);\r
+static int sensor_video_probe(struct soc_camera_device *icd, struct i2c_client *client);\r
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg);\r
+static int sensor_resume(struct soc_camera_device *icd);\r
+static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);\r
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd);\r
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value);\r
+static int sensor_deactivate(struct i2c_client *client);\r
+\r
+static struct soc_camera_ops sensor_ops =\r
+{\r
+ .suspend = sensor_suspend,\r
+ .resume = sensor_resume,\r
+ .set_bus_param = sensor_set_bus_param,\r
+ .query_bus_param = sensor_query_bus_param,\r
+ .controls = sensor_controls,\r
+ .menus = sensor_menus,\r
+ .num_controls = ARRAY_SIZE(sensor_controls),\r
+ .num_menus = ARRAY_SIZE(sensor_menus),\r
+};\r
+\r
+/* only one fixed colorspace per pixelcode */\r
+struct sensor_datafmt {\r
+ enum v4l2_mbus_pixelcode code;\r
+ enum v4l2_colorspace colorspace;\r
+};\r
+\r
+/* Find a data format by a pixel code in an array */\r
+static const struct sensor_datafmt *sensor_find_datafmt(\r
+ enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt,\r
+ int n)\r
+{\r
+ int i;\r
+ for (i = 0; i < n; i++)\r
+ if (fmt[i].code == code)\r
+ return fmt + i;\r
+\r
+ return NULL;\r
+}\r
+\r
+static const struct sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+\r
+typedef struct sensor_info_priv_s\r
+{\r
+ int whiteBalance;\r
+ int brightness;\r
+ int contrast;\r
+ int saturation;\r
+ int effect;\r
+ int scene;\r
+ int digitalzoom;\r
+ int focus;\r
+ int flash;\r
+ int exposure;\r
+ bool snap2preview;\r
+ bool video2preview;\r
+ unsigned char mirror; /* HFLIP */\r
+ unsigned char flip; /* VFLIP */\r
+ unsigned int winseqe_cur_addr;\r
+ struct sensor_datafmt fmt;\r
+ unsigned int funmodule_state;\r
+} sensor_info_priv_t;\r
+\r
+struct sensor\r
+{\r
+ struct v4l2_subdev subdev;\r
+ struct i2c_client *client;\r
+ sensor_info_priv_t info_priv;\r
+ int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */\r
+#if CONFIG_SENSOR_I2C_NOSCHED\r
+ atomic_t tasklock_cnt;\r
+#endif\r
+ struct rk29camera_platform_data *sensor_io_request;\r
+ struct rk29camera_gpio_res *sensor_gpio_res;\r
+};\r
+\r
+static struct sensor* to_sensor(const struct i2c_client *client)\r
+{\r
+ return container_of(i2c_get_clientdata(client), struct sensor, subdev);\r
+}\r
+\r
+static int sensor_task_lock(struct i2c_client *client, int lock)\r
+{\r
+#if CONFIG_SENSOR_I2C_NOSCHED\r
+ int cnt = 3;\r
+ struct sensor *sensor = to_sensor(client);\r
+\r
+ if (lock) {\r
+ if (atomic_read(&sensor->tasklock_cnt) == 0) {\r
+ while ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt>0)) {\r
+ SENSOR_TR("\n %s will obtain i2c in atomic, but i2c bus is locked! Wait...\n",SENSOR_NAME_STRING());\r
+ msleep(35);\r
+ cnt--;\r
+ }\r
+ if ((atomic_read(&client->adapter->bus_lock.count) < 1) && (cnt<=0)) {\r
+ SENSOR_TR("\n %s obtain i2c fail in atomic!!\n",SENSOR_NAME_STRING());\r
+ goto sensor_task_lock_err;\r
+ }\r
+ preempt_disable();\r
+ }\r
+\r
+ atomic_add(1, &sensor->tasklock_cnt);\r
+ } else {\r
+ if (atomic_read(&sensor->tasklock_cnt) > 0) {\r
+ atomic_sub(1, &sensor->tasklock_cnt);\r
+\r
+ if (atomic_read(&sensor->tasklock_cnt) == 0)\r
+ preempt_enable();\r
+ }\r
+ }\r
+ return 0;\r
+sensor_task_lock_err:\r
+ return -1; \r
+#else\r
+ return 0;\r
+#endif\r
+\r
+}\r
+\r
+/* sensor register write */\r
+static int sensor_write(struct i2c_client *client, u8 reg, u8 val)\r
+{\r
+ int err,cnt;\r
+ u8 buf[2];\r
+ struct i2c_msg msg[1];\r
+\r
+ buf[0] = reg;\r
+ buf[1] = val;\r
+\r
+\r
+ msg->addr = client->addr;\r
+ msg->flags = client->flags;\r
+ msg->buf = buf;\r
+ msg->len = sizeof(buf);\r
+ msg->scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
+ msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+ cnt = 3;\r
+ err = -EAGAIN;\r
+\r
+ while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
+ err = i2c_transfer(client->adapter, msg, 1);\r
+\r
+ if (err >= 0) {\r
+ return 0;\r
+ } else {\r
+ SENSOR_TR("\n %s write reg(0x%x, val:0x%x) failed, try to write again!\n",SENSOR_NAME_STRING(),reg, val);\r
+ udelay(10);\r
+ }\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+/* sensor register read */\r
+static int sensor_read(struct i2c_client *client, u8 reg, u8 *val)\r
+{\r
+ int err,cnt;\r
+ u8 buf[1];\r
+ struct i2c_msg msg[2];\r
+\r
+ buf[0] = reg ;\r
+\r
+ msg[0].addr = client->addr;\r
+ msg[0].flags = client->flags;\r
+ msg[0].buf = buf;\r
+ msg[0].len = sizeof(buf);\r
+ msg[0].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
+ msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+ msg[1].addr = client->addr;\r
+ msg[1].flags = client->flags|I2C_M_RD;\r
+ msg[1].buf = buf;\r
+ msg[1].len = 1;\r
+ msg[1].scl_rate = CONFIG_SENSOR_I2C_SPEED; /* ddl@rock-chips.com : 100kHz */\r
+ msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+ cnt = 3;\r
+ err = -EAGAIN;\r
+ while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
+ err = i2c_transfer(client->adapter, msg, 2);\r
+\r
+ if (err >= 0) {\r
+ *val = buf[0];\r
+ return 0;\r
+ } else {\r
+ SENSOR_TR("\n %s read reg(0x%x val:0x%x) failed, try to read again! \n",SENSOR_NAME_STRING(),reg, *val);\r
+ udelay(10);\r
+ }\r
+ }\r
+\r
+ return err;\r
+}\r
+\r
+/* write a array of registers */\r
+static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray)\r
+{\r
+ int err = 0, cnt;\r
+ int i = 0;\r
+#if CONFIG_SENSOR_I2C_RDWRCHK \r
+ char valchk;\r
+#endif\r
+\r
+ cnt = 0;\r
+ if (sensor_task_lock(client, 1) < 0)\r
+ goto sensor_write_array_end;\r
+\r
+ while (regarray[i].reg != 0)\r
+ {\r
+ err = sensor_write(client, regarray[i].reg, regarray[i].val);\r
+ if (err < 0)\r
+ {\r
+ if (cnt-- > 0) {\r
+ SENSOR_TR("%s..write failed current reg:0x%x, Write array again !\n", SENSOR_NAME_STRING(),regarray[i].reg);\r
+ i = 0;\r
+ continue;\r
+ } else {\r
+ SENSOR_TR("%s..write array failed!!!\n", SENSOR_NAME_STRING());\r
+ err = -EPERM;\r
+ goto sensor_write_array_end;\r
+ }\r
+ } else {\r
+ #if CONFIG_SENSOR_I2C_RDWRCHK\r
+ sensor_read(client, regarray[i].reg, &valchk);\r
+ if (valchk != regarray[i].val)\r
+ SENSOR_TR("%s Reg:0x%x write(0x%x, 0x%x) fail\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
+ #endif\r
+ }\r
+ i++;\r
+ }\r
+\r
+sensor_write_array_end:\r
+ sensor_task_lock(client,0);\r
+ return err;\r
+}\r
+\r
+#if CONFIG_SENSOR_I2C_RDWRCHK\r
+static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray)\r
+{\r
+ int cnt;\r
+ int i = 0;\r
+ char valchk;\r
+\r
+ cnt = 0;\r
+ valchk = 0;\r
+ while (regarray[i].reg != 0)\r
+ {\r
+ sensor_read(client, regarray[i].reg, &valchk);\r
+ if (valchk != regarray[i].val)\r
+ SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk);\r
+\r
+ i++;\r
+ }\r
+ return 0;\r
+}\r
+#endif\r
+static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)\r
+{\r
+ struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+ int ret = 0;\r
+\r
+ SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);\r
+ switch (cmd)\r
+ {\r
+ case Sensor_PowerDown:\r
+ {\r
+ if (icl->powerdown) {\r
+ ret = icl->powerdown(icd->pdev, on);\r
+ if (ret == RK29_CAM_IO_SUCCESS) {\r
+ if (on == 0) {\r
+ mdelay(2);\r
+ if (icl->reset)\r
+ icl->reset(icd->pdev);\r
+ }\r
+ } else if (ret == RK29_CAM_EIO_REQUESTFAIL) {\r
+ ret = -ENODEV;\r
+ goto sensor_power_end;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case Sensor_Flash:\r
+ {\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct sensor *sensor = to_sensor(client);\r
+\r
+ if (sensor->sensor_io_request && sensor->sensor_io_request->sensor_ioctrl) {\r
+ sensor->sensor_io_request->sensor_ioctrl(icd->pdev,Cam_Flash, on);\r
+ if(on){\r
+ //flash off after 2 secs\r
+ hrtimer_cancel(&(flash_off_timer.timer));\r
+ hrtimer_start(&(flash_off_timer.timer),ktime_set(0, 800*1000*1000),HRTIMER_MODE_REL);\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+ break;\r
+ }\r
+ }\r
+sensor_power_end:\r
+ return ret;\r
+}\r
+static enum hrtimer_restart flash_off_func(struct hrtimer *timer){\r
+ struct flash_timer *fps_timer = container_of(timer, struct flash_timer, timer);\r
+ sensor_ioctrl(fps_timer->icd,Sensor_Flash,0);\r
+ SENSOR_DG("%s %s !!!!!!",SENSOR_NAME_STRING(),__FUNCTION__);\r
+ return 0;\r
+ \r
+}\r
+static int sensor_init(struct v4l2_subdev *sd, u32 val)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct sensor *sensor = to_sensor(client);\r
+ const struct v4l2_queryctrl *qctrl;\r
+ const struct sensor_datafmt *fmt;\r
+ char value;\r
+ int ret,pid = 0;\r
+\r
+ SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+\r
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
+ ret = -ENODEV;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+\r
+ /* soft reset */\r
+ if (sensor_task_lock(client,1)<0)\r
+ goto sensor_INIT_ERR;\r
+ /* check if it is an sensor sensor */\r
+ ret = sensor_read(client, 0xf0, &value);\r
+ if (ret != 0) {\r
+ SENSOR_TR("read chip id high byte failed\n");\r
+ ret = -ENODEV;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+\r
+ pid |= (value << 8);\r
+\r
+ ret = sensor_read(client, 0xf1, &value);\r
+ if (ret != 0) {\r
+ SENSOR_TR("read chip id low byte failed\n");\r
+ ret = -ENODEV;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+\r
+ pid |= (value & 0xff);\r
+ SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ if (pid == SENSOR_ID) {\r
+ sensor->model = SENSOR_V4L2_IDENT;\r
+ } else {\r
+ SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ ret = -ENODEV;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+\r
+ ret = sensor_write_array(client, sensor_init_data);\r
+\r
+\r
+ mdelay(300);\r
+\r
+ \r
+ if (ret != 0)\r
+ {\r
+ SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());\r
+ goto sensor_INIT_ERR;\r
+ }\r
+ sensor_task_lock(client,0);\r
+ \r
+ sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR;\r
+ fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts));\r
+ if (!fmt) {\r
+ SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING());\r
+ ret = -EINVAL;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+ sensor->info_priv.fmt = *fmt;\r
+\r
+ /* sensor sensor information for initialization */\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+ if (qctrl)\r
+ sensor->info_priv.whiteBalance = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_BRIGHTNESS);\r
+ if (qctrl)\r
+ sensor->info_priv.brightness = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+ if (qctrl)\r
+ sensor->info_priv.effect = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EXPOSURE);\r
+ if (qctrl)\r
+ sensor->info_priv.exposure = qctrl->default_value;\r
+\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SATURATION);\r
+ if (qctrl)\r
+ sensor->info_priv.saturation = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_CONTRAST);\r
+ if (qctrl)\r
+ sensor->info_priv.contrast = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_HFLIP);\r
+ if (qctrl)\r
+ sensor->info_priv.mirror = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_VFLIP);\r
+ if (qctrl)\r
+ sensor->info_priv.flip = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_SCENE);\r
+ if (qctrl)\r
+ sensor->info_priv.scene = qctrl->default_value;\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
+ if (qctrl)\r
+ sensor->info_priv.digitalzoom = qctrl->default_value;\r
+\r
+ /* ddl@rock-chips.com : if sensor support auto focus and flash, programer must run focus and flash code */\r
+ #if CONFIG_SENSOR_Focus\r
+ sensor_set_focus();\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE);\r
+ if (qctrl)\r
+ sensor->info_priv.focus = qctrl->default_value;\r
+ #endif\r
+\r
+ #if CONFIG_SENSOR_Flash \r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH);\r
+ if (qctrl)\r
+ sensor->info_priv.flash = qctrl->default_value;\r
+ flash_off_timer.icd = icd;\r
+ flash_off_timer.timer.function = flash_off_func;\r
+ #endif\r
+\r
+ SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height);\r
+ sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK;\r
+ return 0;\r
+sensor_INIT_ERR:\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ sensor_task_lock(client,0);\r
+ sensor_deactivate(client);\r
+ return ret;\r
+}\r
+\r
+static int sensor_deactivate(struct i2c_client *client)\r
+{\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+ struct sensor *sensor = to_sensor(client);\r
+ SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+\r
+ /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */\r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ }\r
+ sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+ msleep(100); \r
+\r
+ /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */\r
+ icd->user_width = SENSOR_INIT_WIDTH;\r
+ icd->user_height = SENSOR_INIT_HEIGHT;\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ \r
+ return 0;\r
+}\r
+\r
+static struct reginfo sensor_power_down_sequence[]=\r
+{\r
+\r
+ {0x00,0x00}\r
+};\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ int ret;\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());\r
+ ret = sensor_write_array(client, sensor_power_down_sequence) ;\r
+ if (ret != 0) {\r
+ SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);\r
+ return ret;\r
+ } else {\r
+ ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+ if (ret < 0) {\r
+ SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());\r
+ return -EINVAL;\r
+ }\r
+ }\r
+ } else {\r
+ SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+ int ret;\r
+\r
+ ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);\r
+ if (ret < 0) {\r
+ SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());\r
+ return -EINVAL;\r
+ }\r
+\r
+ SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());\r
+\r
+ return 0;\r
+\r
+}\r
+\r
+static int sensor_set_bus_param(struct soc_camera_device *icd,\r
+ unsigned long flags)\r
+{\r
+\r
+ return 0;\r
+}\r
+\r
+static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)\r
+{\r
+ struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+ unsigned long flags = SENSOR_BUS_PARAM;\r
+\r
+ return soc_camera_apply_sensor_flags(icl, flags);\r
+}\r
+\r
+static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct sensor *sensor = to_sensor(client);\r
+\r
+ mf->width = icd->user_width;\r
+ mf->height = icd->user_height;\r
+ mf->code = sensor->info_priv.fmt.code;\r
+ mf->colorspace = sensor->info_priv.fmt.colorspace;\r
+ mf->field = V4L2_FIELD_NONE;\r
+\r
+ return 0;\r
+}\r
+static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ bool ret = false;\r
+\r
+ if ((mf->width == 1024) && (mf->height == 768)) {\r
+ ret = true;\r
+ } else if ((mf->width == 1280) && (mf->height == 1024)) {\r
+ ret = true;\r
+ } else if ((mf->width == 1600) && (mf->height == 1200)) {\r
+ ret = true;\r
+ } else if ((mf->width == 2048) && (mf->height == 1536)) {\r
+ ret = true;\r
+ } else if ((mf->width == 2592) && (mf->height == 1944)) {\r
+ ret = true;\r
+ }\r
+\r
+ if (ret == true)\r
+ SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height);\r
+ return ret;\r
+}\r
+\r
+static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ bool ret = false;\r
+\r
+ if ((mf->width == 1280) && (mf->height == 720)) {\r
+ ret = true;\r
+ } else if ((mf->width == 1920) && (mf->height == 1080)) {\r
+ ret = true;\r
+ }\r
+\r
+ if (ret == true)\r
+ SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height);\r
+ return ret;\r
+}\r
+static unsigned int shutter_h,shutter_l;\r
+static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ int ret1;\r
+\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ const struct sensor_datafmt *fmt;\r
+ struct sensor *sensor = to_sensor(client);\r
+ const struct v4l2_queryctrl *qctrl;\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct reginfo *winseqe_set_addr=NULL;\r
+ int ret=0, set_w,set_h;\r
+#if 1\r
+char value;\r
+unsigned int pid=0,shutter,temp_reg;\r
+\r
+#endif\r
+\r
+ fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,\r
+ ARRAY_SIZE(sensor_colour_fmts));\r
+ if (!fmt) {\r
+ ret = -EINVAL;\r
+ goto sensor_s_fmt_end;\r
+ }\r
+\r
+ if (sensor->info_priv.fmt.code != mf->code) {\r
+ switch (mf->code)\r
+ {\r
+ case V4L2_MBUS_FMT_YUYV8_2X8:\r
+ {\r
+ winseqe_set_addr = sensor_ClrFmt_YUYV;\r
+ break;\r
+ }\r
+ case V4L2_MBUS_FMT_UYVY8_2X8:\r
+ {\r
+ winseqe_set_addr = sensor_ClrFmt_UYVY;\r
+ break;\r
+ }\r
+ default:\r
+ break;\r
+ }\r
+ if (winseqe_set_addr != NULL) {\r
+ sensor_write_array(client, winseqe_set_addr);\r
+ sensor->info_priv.fmt.code = mf->code;\r
+ sensor->info_priv.fmt.colorspace= mf->colorspace; \r
+ SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code);\r
+ } else {\r
+ SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code);\r
+ }\r
+ }\r
+\r
+ set_w = mf->width;\r
+ set_h = mf->height;\r
+\r
+ if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_qcif;\r
+ set_w = 176;\r
+ set_h = 144;\r
+ }\r
+ else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_qvga;\r
+ set_w = 320;\r
+ set_h = 240;\r
+ }\r
+ else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_cif;\r
+ set_w = 352;\r
+ set_h = 288;\r
+ }\r
+ else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_vga;\r
+ set_w = 640;\r
+ set_h = 480;\r
+ }\r
+ else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_svga;\r
+ set_w = 800;\r
+ set_h = 600;\r
+ }\r
+ else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_sxga;\r
+ set_w = 1280;\r
+ set_h = 1024;\r
+ }\r
+ else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)\r
+ {\r
+ winseqe_set_addr = sensor_uxga;\r
+ set_w = 1600;\r
+ set_h = 1200;\r
+ }\r
+ else\r
+ {\r
+ winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */\r
+ set_w = SENSOR_INIT_WIDTH;\r
+ set_h = SENSOR_INIT_HEIGHT;\r
+ SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height);\r
+ }\r
+\r
+ if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) {\r
+ #if CONFIG_SENSOR_Flash\r
+ if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */\r
+ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+ sensor_ioctrl(icd, Sensor_Flash, Flash_On);\r
+ SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING());\r
+ } \r
+ } else { /* ddl@rock-chips.com : Video */\r
+ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+ sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+ SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING());\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if ((winseqe_set_addr == sensor_svga)||(winseqe_set_addr == sensor_vga) )\r
+ {\r
+ sensor_write(client, 0xb6, 0x00); // AEC ON\r
+ sensor_write(client, 0x03, shutter_h);\r
+ sensor_write(client, 0x04, shutter_l);\r
+ msleep(50);\r
+ printk("set preview for rewrite 0x03");\r
+ \r
+ } \r
+ ret |= sensor_write_array(client, winseqe_set_addr);\r
+#if 1\r
+ if (winseqe_set_addr == sensor_uxga) \r
+ { \r
+ sensor_write(client, 0xfe, 0x00);\r
+ sensor_write(client, 0xb6, 0x02); // AEC OFF\r
+ sensor_read(client, 0x03, &value);\r
+ shutter_h=value;\r
+ pid |= (value << 8);\r
+ sensor_read(client, 0x04, &value);\r
+ shutter_l=value;\r
+ pid |= (value & 0xff);\r
+ shutter=pid;\r
+ temp_reg= shutter /2;\r
+ if(temp_reg < 1) temp_reg = 1;\r
+ sensor_write(client, 0x03, ((temp_reg>>8)&0xff));\r
+ sensor_write(client, 0x04, (temp_reg&0xff));\r
+ }\r
+#endif \r
+\r
+ if (ret != 0) {\r
+ SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING());\r
+ #if CONFIG_SENSOR_Flash\r
+ if (sensor_fmt_capturechk(sd,mf) == true) {\r
+ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {\r
+ sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+ SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING());\r
+ }\r
+ }\r
+ #endif\r
+ goto sensor_s_fmt_end;\r
+ }\r
+\r
+ sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr;\r
+\r
+ if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+ sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+ if (sensor->info_priv.whiteBalance != 0) {\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+ sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+ }\r
+ sensor->info_priv.snap2preview = true;\r
+ } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+ sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+ sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+ sensor->info_priv.video2preview = true;\r
+ } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) {\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT);\r
+ sensor_set_effect(icd, qctrl,sensor->info_priv.effect);\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE);\r
+ sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance);\r
+ msleep(600);\r
+ sensor->info_priv.video2preview = false;\r
+ sensor->info_priv.snap2preview = false;\r
+ }\r
+\r
+ SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);\r
+ }\r
+ else\r
+ {\r
+ SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);\r
+ }\r
+\r
+ mf->width = set_w;\r
+ mf->height = set_h;\r
+ msleep(100); //james added\r
+sensor_s_fmt_end:\r
+ return ret;\r
+}\r
+\r
+static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct sensor *sensor = to_sensor(client);\r
+ const struct sensor_datafmt *fmt;\r
+ int ret = 0,set_w,set_h;\r
+ \r
+ fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,\r
+ ARRAY_SIZE(sensor_colour_fmts));\r
+ if (fmt == NULL) {\r
+ fmt = &sensor->info_priv.fmt;\r
+ mf->code = fmt->code;\r
+ } \r
+\r
+ if (mf->height > SENSOR_MAX_HEIGHT)\r
+ mf->height = SENSOR_MAX_HEIGHT;\r
+ else if (mf->height < SENSOR_MIN_HEIGHT)\r
+ mf->height = SENSOR_MIN_HEIGHT;\r
+\r
+ if (mf->width > SENSOR_MAX_WIDTH)\r
+ mf->width = SENSOR_MAX_WIDTH;\r
+ else if (mf->width < SENSOR_MIN_WIDTH)\r
+ mf->width = SENSOR_MIN_WIDTH;\r
+\r
+ set_w = mf->width;\r
+ set_h = mf->height;\r
+\r
+ if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)\r
+ {\r
+ set_w = 176;\r
+ set_h = 144;\r
+ }\r
+ else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)\r
+ {\r
+ set_w = 320;\r
+ set_h = 240;\r
+ }\r
+ else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)\r
+ {\r
+ set_w = 352;\r
+ set_h = 288;\r
+ }\r
+ else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)\r
+ {\r
+ set_w = 640;\r
+ set_h = 480;\r
+ }\r
+ else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)\r
+ {\r
+ set_w = 800;\r
+ set_h = 600;\r
+ }\r
+ else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)\r
+ {\r
+ set_w = 1280;\r
+ set_h = 1024;\r
+ }\r
+ else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)\r
+ {\r
+ set_w = 1600;\r
+ set_h = 1200;\r
+ }\r
+ else\r
+ {\r
+ set_w = SENSOR_INIT_WIDTH;\r
+ set_h = SENSOR_INIT_HEIGHT;\r
+ }\r
+\r
+ mf->width = set_w;\r
+ mf->height = set_h;\r
+ mf->colorspace = fmt->colorspace;\r
+ \r
+ return ret;\r
+}\r
+\r
+ static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+\r
+ if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)\r
+ return -EINVAL;\r
+\r
+ if (id->match.addr != client->addr)\r
+ return -ENODEV;\r
+\r
+ id->ident = SENSOR_V4L2_IDENT; /* ddl@rock-chips.com : Return gc2035 identifier */\r
+ id->revision = 0;\r
+\r
+ return 0;\r
+}\r
+#if CONFIG_SENSOR_Brightness\r
+static int sensor_set_brightness(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_BrightnessSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_BrightnessSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Effect\r
+static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_EffectSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_EffectSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+static int sensor_set_exposure(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_ExposureSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_ExposureSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+static int sensor_set_saturation(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_SaturationSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_SaturationSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+static int sensor_set_contrast(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_ContrastSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_ContrastSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+static int sensor_set_mirror(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_MirrorSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_MirrorSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+static int sensor_set_flip(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_FlipSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_FlipSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Scene\r
+static int sensor_set_scene(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_SceneSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_SceneSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_WhiteBalance\r
+static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum))\r
+ {\r
+ if (sensor_WhiteBalanceSeqe[value - qctrl->minimum] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_WhiteBalanceSeqe[value - qctrl->minimum]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ }\r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct sensor *sensor = to_sensor(client);\r
+ const struct v4l2_queryctrl *qctrl_info;\r
+ int digitalzoom_cur, digitalzoom_total;\r
+\r
+ qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_ZOOM_ABSOLUTE);\r
+ if (qctrl_info)\r
+ return -EINVAL;\r
+\r
+ digitalzoom_cur = sensor->info_priv.digitalzoom;\r
+ digitalzoom_total = qctrl_info->maximum;\r
+\r
+ if ((value > 0) && (digitalzoom_cur >= digitalzoom_total))\r
+ {\r
+ SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
+ return -EINVAL;\r
+ }\r
+\r
+ if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum))\r
+ {\r
+ SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur);\r
+ return -EINVAL;\r
+ }\r
+\r
+ if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total))\r
+ {\r
+ value = digitalzoom_total - digitalzoom_cur;\r
+ }\r
+\r
+ if ((value < 0) && ((digitalzoom_cur + value) < 0))\r
+ {\r
+ value = 0 - digitalzoom_cur;\r
+ }\r
+\r
+ digitalzoom_cur += value;\r
+\r
+ if (sensor_ZoomSeqe[digitalzoom_cur] != NULL)\r
+ {\r
+ if (sensor_write_array(client, sensor_ZoomSeqe[digitalzoom_cur]) != 0)\r
+ {\r
+ SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__);\r
+ return -EINVAL;\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+\r
+ return -EINVAL;\r
+}\r
+#endif\r
+#if CONFIG_SENSOR_Flash\r
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{ \r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {\r
+ if (value == 3) { /* ddl@rock-chips.com: torch */\r
+ sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */\r
+ } else {\r
+ sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+ }\r
+ SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+ \r
+ SENSOR_TR("\n %s..%s valure = %d is invalidate.. \n",SENSOR_NAME_STRING(),__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+#endif\r
+\r
+static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct sensor *sensor = to_sensor(client);\r
+ const struct v4l2_queryctrl *qctrl;\r
+\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
+\r
+ if (!qctrl)\r
+ {\r
+ SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
+ return -EINVAL;\r
+ }\r
+\r
+ switch (ctrl->id)\r
+ {\r
+ case V4L2_CID_BRIGHTNESS:\r
+ {\r
+ ctrl->value = sensor->info_priv.brightness;\r
+ break;\r
+ }\r
+ case V4L2_CID_SATURATION:\r
+ {\r
+ ctrl->value = sensor->info_priv.saturation;\r
+ break;\r
+ }\r
+ case V4L2_CID_CONTRAST:\r
+ {\r
+ ctrl->value = sensor->info_priv.contrast;\r
+ break;\r
+ }\r
+ case V4L2_CID_DO_WHITE_BALANCE:\r
+ {\r
+ ctrl->value = sensor->info_priv.whiteBalance;\r
+ break;\r
+ }\r
+ case V4L2_CID_EXPOSURE:\r
+ {\r
+ ctrl->value = sensor->info_priv.exposure;\r
+ break;\r
+ }\r
+ case V4L2_CID_HFLIP:\r
+ {\r
+ ctrl->value = sensor->info_priv.mirror;\r
+ break;\r
+ }\r
+ case V4L2_CID_VFLIP:\r
+ {\r
+ ctrl->value = sensor->info_priv.flip;\r
+ break;\r
+ }\r
+ default :\r
+ break;\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+\r
+static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct sensor *sensor = to_sensor(client);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ const struct v4l2_queryctrl *qctrl;\r
+\r
+\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id);\r
+\r
+ if (!qctrl)\r
+ {\r
+ SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ctrl->id);\r
+ return -EINVAL;\r
+ }\r
+\r
+ switch (ctrl->id)\r
+ {\r
+#if CONFIG_SENSOR_Brightness\r
+ case V4L2_CID_BRIGHTNESS:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.brightness)\r
+ {\r
+ if (sensor_set_brightness(icd, qctrl,ctrl->value) != 0)\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ sensor->info_priv.brightness = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Exposure\r
+ case V4L2_CID_EXPOSURE:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.exposure)\r
+ {\r
+ if (sensor_set_exposure(icd, qctrl,ctrl->value) != 0)\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ sensor->info_priv.exposure = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Saturation\r
+ case V4L2_CID_SATURATION:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.saturation)\r
+ {\r
+ if (sensor_set_saturation(icd, qctrl,ctrl->value) != 0)\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ sensor->info_priv.saturation = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Contrast\r
+ case V4L2_CID_CONTRAST:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.contrast)\r
+ {\r
+ if (sensor_set_contrast(icd, qctrl,ctrl->value) != 0)\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ sensor->info_priv.contrast = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_WhiteBalance\r
+ case V4L2_CID_DO_WHITE_BALANCE:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.whiteBalance)\r
+ {\r
+ if (sensor_set_whiteBalance(icd, qctrl,ctrl->value) != 0)\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ sensor->info_priv.whiteBalance = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Mirror\r
+ case V4L2_CID_HFLIP:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.mirror)\r
+ {\r
+ if (sensor_set_mirror(icd, qctrl,ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.mirror = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Flip\r
+ case V4L2_CID_VFLIP:\r
+ {\r
+ if (ctrl->value != sensor->info_priv.flip)\r
+ {\r
+ if (sensor_set_flip(icd, qctrl,ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.flip = ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return 0;\r
+}\r
+static int sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ const struct v4l2_queryctrl *qctrl;\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct sensor *sensor = to_sensor(client);\r
+\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
+\r
+ if (!qctrl)\r
+ {\r
+ SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
+ return -EINVAL;\r
+ }\r
+\r
+ switch (ext_ctrl->id)\r
+ {\r
+ case V4L2_CID_SCENE:\r
+ {\r
+ ext_ctrl->value = sensor->info_priv.scene;\r
+ break;\r
+ }\r
+ case V4L2_CID_EFFECT:\r
+ {\r
+ ext_ctrl->value = sensor->info_priv.effect;\r
+ break;\r
+ }\r
+ case V4L2_CID_ZOOM_ABSOLUTE:\r
+ {\r
+ ext_ctrl->value = sensor->info_priv.digitalzoom;\r
+ break;\r
+ }\r
+ case V4L2_CID_ZOOM_RELATIVE:\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ case V4L2_CID_FOCUS_ABSOLUTE:\r
+ {\r
+ ext_ctrl->value = sensor->info_priv.focus;\r
+ break;\r
+ }\r
+ case V4L2_CID_FOCUS_RELATIVE:\r
+ {\r
+ return -EINVAL;\r
+ }\r
+ case V4L2_CID_FLASH:\r
+ {\r
+ ext_ctrl->value = sensor->info_priv.flash;\r
+ break;\r
+ }\r
+ default :\r
+ break;\r
+ }\r
+ return 0;\r
+}\r
+static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ const struct v4l2_queryctrl *qctrl;\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct sensor *sensor = to_sensor(client);\r
+ int val_offset;\r
+\r
+ qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);\r
+\r
+ if (!qctrl)\r
+ {\r
+ SENSOR_TR("\n %s ioctrl id = %d is invalidate \n", SENSOR_NAME_STRING(), ext_ctrl->id);\r
+ return -EINVAL;\r
+ }\r
+\r
+ val_offset = 0;\r
+ switch (ext_ctrl->id)\r
+ {\r
+#if CONFIG_SENSOR_Scene\r
+ case V4L2_CID_SCENE:\r
+ {\r
+ if (ext_ctrl->value != sensor->info_priv.scene)\r
+ {\r
+ if (sensor_set_scene(icd, qctrl,ext_ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.scene = ext_ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Effect\r
+ case V4L2_CID_EFFECT:\r
+ {\r
+ if (ext_ctrl->value != sensor->info_priv.effect)\r
+ {\r
+ if (sensor_set_effect(icd, qctrl,ext_ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.effect= ext_ctrl->value;\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_DigitalZoom\r
+ case V4L2_CID_ZOOM_ABSOLUTE:\r
+ {\r
+ if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
+ return -EINVAL;\r
+\r
+ if (ext_ctrl->value != sensor->info_priv.digitalzoom)\r
+ {\r
+ val_offset = ext_ctrl->value -sensor->info_priv.digitalzoom;\r
+\r
+ if (sensor_set_digitalzoom(icd, qctrl,&val_offset) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.digitalzoom += val_offset;\r
+\r
+ SENSOR_DG("%s digitalzoom is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);\r
+ }\r
+\r
+ break;\r
+ }\r
+ case V4L2_CID_ZOOM_RELATIVE:\r
+ {\r
+ if (ext_ctrl->value)\r
+ {\r
+ if (sensor_set_digitalzoom(icd, qctrl,&ext_ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.digitalzoom += ext_ctrl->value;\r
+\r
+ SENSOR_DG("%s digitalzoom is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.digitalzoom);\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Focus\r
+ case V4L2_CID_FOCUS_ABSOLUTE:\r
+ {\r
+ if ((ext_ctrl->value < qctrl->minimum) || (ext_ctrl->value > qctrl->maximum))\r
+ return -EINVAL;\r
+\r
+ if (ext_ctrl->value != sensor->info_priv.focus)\r
+ {\r
+ val_offset = ext_ctrl->value -sensor->info_priv.focus;\r
+\r
+ sensor->info_priv.focus += val_offset;\r
+ }\r
+\r
+ break;\r
+ }\r
+ case V4L2_CID_FOCUS_RELATIVE:\r
+ {\r
+ if (ext_ctrl->value)\r
+ {\r
+ sensor->info_priv.focus += ext_ctrl->value;\r
+\r
+ SENSOR_DG("%s focus is %x\n", SENSOR_NAME_STRING(), sensor->info_priv.focus);\r
+ }\r
+ break;\r
+ }\r
+#endif\r
+#if CONFIG_SENSOR_Flash\r
+ case V4L2_CID_FLASH:\r
+ {\r
+ if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)\r
+ return -EINVAL;\r
+ sensor->info_priv.flash = ext_ctrl->value;\r
+\r
+ SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);\r
+ break;\r
+ }\r
+#endif\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ int i, error_cnt=0, error_idx=-1;\r
+\r
+\r
+ for (i=0; i<ext_ctrl->count; i++) {\r
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+ error_cnt++;\r
+ error_idx = i;\r
+ }\r
+ }\r
+\r
+ if (error_cnt > 1)\r
+ error_idx = ext_ctrl->count;\r
+\r
+ if (error_idx != -1) {\r
+ ext_ctrl->error_idx = error_idx;\r
+ return -EINVAL;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ int i, error_cnt=0, error_idx=-1;\r
+\r
+\r
+ for (i=0; i<ext_ctrl->count; i++) {\r
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+ error_cnt++;\r
+ error_idx = i;\r
+ }\r
+ }\r
+\r
+ if (error_cnt > 1)\r
+ error_idx = ext_ctrl->count;\r
+\r
+ if (error_idx != -1) {\r
+ ext_ctrl->error_idx = error_idx;\r
+ return -EINVAL;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/* Interface active, can use i2c. If it fails, it can indeed mean, that\r
+ * this wasn't our capture interface, so, we wait for the right one */\r
+static int sensor_video_probe(struct soc_camera_device *icd,\r
+ struct i2c_client *client)\r
+{\r
+ char value;\r
+ int ret,pid = 0;\r
+ struct sensor *sensor = to_sensor(client);\r
+\r
+ /* We must have a parent by now. And it cannot be a wrong one.\r
+ * So this entire test is completely redundant. */\r
+ if (!icd->dev.parent ||\r
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)\r
+ return -ENODEV;\r
+\r
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {\r
+ ret = -ENODEV;\r
+ goto sensor_video_probe_err;\r
+ }\r
+\r
+ /* soft reset */\r
+\r
+ /* check if it is an sensor sensor */\r
+ ret = sensor_read(client, 0xf0, &value);\r
+ if (ret != 0) {\r
+ SENSOR_TR("read chip id high byte failed\n");\r
+ ret = -ENODEV;\r
+ goto sensor_video_probe_err;\r
+ }\r
+\r
+ pid |= (value << 8);\r
+\r
+ ret = sensor_read(client, 0xf1, &value);\r
+ if (ret != 0) {\r
+ SENSOR_TR("read chip id low byte failed\n");\r
+ ret = -ENODEV;\r
+ goto sensor_video_probe_err;\r
+ }\r
+\r
+ pid |= (value & 0xff);\r
+ SENSOR_DG("\n %s pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ if (pid == SENSOR_ID) {\r
+ sensor->model = SENSOR_V4L2_IDENT;\r
+ } else {\r
+ SENSOR_TR("error: %s mismatched pid = 0x%x\n", SENSOR_NAME_STRING(), pid);\r
+ ret = -ENODEV;\r
+ goto sensor_video_probe_err;\r
+ }\r
+\r
+ return 0;\r
+\r
+sensor_video_probe_err:\r
+\r
+ return ret;\r
+}\r
+static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct sensor *sensor = to_sensor(client);\r
+#if CONFIG_SENSOR_Flash\r
+ int i;\r
+#endif\r
+ int ret = 0;\r
+ \r
+ SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+ switch (cmd)\r
+ {\r
+ case RK29_CAM_SUBDEV_DEACTIVATE:\r
+ {\r
+ sensor_deactivate(client);\r
+ break;\r
+ }\r
+\r
+ case RK29_CAM_SUBDEV_IOREQUEST:\r
+ {\r
+ sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; \r
+ if (sensor->sensor_io_request != NULL) { \r
+ sensor->sensor_gpio_res = NULL;\r
+ for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {\r
+ if (sensor->sensor_io_request->gpio_res[i].dev_name && \r
+ (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {\r
+ sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];\r
+ }\r
+ }\r
+ if (sensor->sensor_gpio_res == NULL) {\r
+ SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+ ret = -EINVAL;\r
+ goto sensor_ioctl_end;\r
+ }\r
+ } else {\r
+ SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
+ ret = -EINVAL;\r
+ goto sensor_ioctl_end;\r
+ }\r
+ /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control \r
+ for this project */\r
+ #if CONFIG_SENSOR_Flash \r
+ if (sensor->sensor_gpio_res) {\r
+ if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {\r
+ for (i = 0; i < icd->ops->num_controls; i++) {\r
+ if (V4L2_CID_FLASH == icd->ops->controls[i].id) {\r
+ //memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); \r
+ sensor_controls[i].id=0xffff; \r
+ }\r
+ }\r
+ sensor->info_priv.flash = 0xff;\r
+ SENSOR_DG("%s flash gpio is invalidate!\n",SENSOR_NAME_STRING());\r
+ }else{ //two cameras are the same,need to deal diffrently ,zyc\r
+ for (i = 0; i < icd->ops->num_controls; i++) {\r
+ if(0xffff == icd->ops->controls[i].id){\r
+ sensor_controls[i].id=V4L2_CID_FLASH;\r
+ } \r
+ }\r
+ }\r
+ }\r
+ #endif\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);\r
+ break;\r
+ }\r
+ }\r
+sensor_ioctl_end:\r
+ return ret;\r
+\r
+}\r
+static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,\r
+ enum v4l2_mbus_pixelcode *code)\r
+{\r
+ if (index >= ARRAY_SIZE(sensor_colour_fmts))\r
+ return -EINVAL;\r
+\r
+ *code = sensor_colour_fmts[index].code;\r
+ return 0;\r
+}\r
+static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\r
+ .init = sensor_init,\r
+ .g_ctrl = sensor_g_control,\r
+ .s_ctrl = sensor_s_control,\r
+ .g_ext_ctrls = sensor_g_ext_controls,\r
+ .s_ext_ctrls = sensor_s_ext_controls,\r
+ .g_chip_ident = sensor_g_chip_ident,\r
+ .ioctl = sensor_ioctl,\r
+};\r
+\r
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\r
+ .s_mbus_fmt = sensor_s_fmt,\r
+ .g_mbus_fmt = sensor_g_fmt,\r
+ .try_mbus_fmt = sensor_try_fmt,\r
+ .enum_mbus_fmt = sensor_enum_fmt,\r
+};\r
+\r
+static struct v4l2_subdev_ops sensor_subdev_ops = {\r
+ .core = &sensor_subdev_core_ops,\r
+ .video = &sensor_subdev_video_ops,\r
+};\r
+\r
+static int sensor_probe(struct i2c_client *client,\r
+ const struct i2c_device_id *did)\r
+{\r
+ struct sensor *sensor;\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);\r
+ struct soc_camera_link *icl;\r
+ int ret;\r
+\r
+ SENSOR_DG("\n%s..%s..%d..\n",__FUNCTION__,__FILE__,__LINE__);\r
+ if (!icd) {\r
+ dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());\r
+ return -EINVAL;\r
+ }\r
+\r
+ icl = to_soc_camera_link(icd);\r
+ if (!icl) {\r
+ dev_err(&client->dev, "%s driver needs platform data\n", SENSOR_NAME_STRING());\r
+ return -EINVAL;\r
+ }\r
+\r
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {\r
+ dev_warn(&adapter->dev,\r
+ "I2C-Adapter doesn't support I2C_FUNC_I2C\n");\r
+ return -EIO;\r
+ }\r
+\r
+ sensor = kzalloc(sizeof(struct sensor), GFP_KERNEL);\r
+ if (!sensor)\r
+ return -ENOMEM;\r
+\r
+ v4l2_i2c_subdev_init(&sensor->subdev, client, &sensor_subdev_ops);\r
+\r
+ /* Second stage probe - when a capture adapter is there */\r
+ icd->ops = &sensor_ops;\r
+\r
+ sensor->info_priv.fmt = sensor_colour_fmts[0];\r
+ \r
+ #if CONFIG_SENSOR_I2C_NOSCHED\r
+ atomic_set(&sensor->tasklock_cnt,0);\r
+ #endif\r
+\r
+ ret = sensor_video_probe(icd, client);\r
+ if (ret < 0) {\r
+ icd->ops = NULL;\r
+ i2c_set_clientdata(client, NULL);\r
+ kfree(sensor);\r
+ sensor = NULL;\r
+ }\r
+ hrtimer_init(&(flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);\r
+ SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret);\r
+ return ret;\r
+}\r
+\r
+static int sensor_remove(struct i2c_client *client)\r
+{\r
+ struct sensor *sensor = to_sensor(client);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+ icd->ops = NULL;\r
+ i2c_set_clientdata(client, NULL);\r
+ client->driver = NULL;\r
+ kfree(sensor);\r
+\r
+ return 0;\r
+}\r
+\r
+static const struct i2c_device_id sensor_id[] = {\r
+ {SENSOR_NAME_STRING(), 0 },\r
+ { }\r
+};\r
+MODULE_DEVICE_TABLE(i2c, sensor_id);\r
+\r
+static struct i2c_driver sensor_i2c_driver = {\r
+ .driver = {\r
+ .name = SENSOR_NAME_STRING(),\r
+ },\r
+ .probe = sensor_probe,\r
+ .remove = sensor_remove,\r
+ .id_table = sensor_id,\r
+};\r
+\r
+static int __init sensor_mod_init(void)\r
+{\r
+ SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING());\r
+ return i2c_add_driver(&sensor_i2c_driver);\r
+}\r
+\r
+static void __exit sensor_mod_exit(void)\r
+{\r
+ i2c_del_driver(&sensor_i2c_driver);\r
+}\r
+\r
+device_initcall_sync(sensor_mod_init);\r
+module_exit(sensor_mod_exit);\r
+\r
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));\r
+MODULE_AUTHOR("ddl <kernel@rock-chips>");\r
+MODULE_LICENSE("GPL");\r
+\r
+\r
+\r
+\r
--- /dev/null
+#include <linux/videodev2.h>\r
+#include <linux/slab.h>\r
+#include <linux/i2c.h>\r
+#include <linux/log2.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/delay.h>\r
+#include <linux/circ_buf.h>\r
+#include <linux/miscdevice.h>\r
+#include <media/v4l2-common.h>\r
+#include <media/v4l2-chip-ident.h>\r
+#include <media/soc_camera.h>\r
+#include <linux/vmalloc.h>\r
+#include <linux/hardirq.h>\r
+#include "generic_sensor.h"\r
+\r
+/*
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define CAMMODULE_NAME "rk_cam_sensor"\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+#define SENSOR_NAME_STRING() sensor->dev_name\r
+\r
+#undef SENSOR_TR\r
+#undef SENSOR_DG\r
+#define SENSOR_TR(format, ...) printk(KERN_ERR "%s(%s:%d): " format"\n", SENSOR_NAME_STRING(),CAMMODULE_NAME,__LINE__, ## __VA_ARGS__)\r
+#define SENSOR_DG(format, ...) dprintk(1, "%s(%s:%d): "format"\n", SENSOR_NAME_STRING(),CAMMODULE_NAME,__LINE__,## __VA_ARGS__)\r
+\r
+\r
+#define CONFIG_SENSOR_I2C_RDWRCHK 0\r
+\r
+static const struct rk_sensor_datafmt *generic_sensor_find_datafmt(\r
+ enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt,\r
+ int n);\r
+\r
+int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val){ \r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xffff;\r
+ tmp_reg.val_mask = 0xff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = val;\r
+ return generic_sensor_write(client, &tmp_reg);\r
+}\r
+int sensor_write_reg2val2(struct i2c_client *client, u16 reg,u16 val){\r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xffff;\r
+ tmp_reg.val_mask = 0xffff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = val;\r
+ return generic_sensor_write(client, &tmp_reg);\r
+}\r
+int sensor_write_reg1val1(struct i2c_client *client, u8 reg,u8 val){\r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xff;\r
+ tmp_reg.val_mask = 0xff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = val;\r
+ return generic_sensor_write(client, &tmp_reg);\r
+}\r
+int sensor_write_reg1val2(struct i2c_client *client, u8 reg,u16 val){\r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xff;\r
+ tmp_reg.val_mask = 0xffff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = val;\r
+ return generic_sensor_write(client, &tmp_reg);\r
+}\r
+int sensor_write_reg0val0(struct i2c_client *client, u8 reg,u16 val) \r
+{\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_TR("SENSOR_REGISTER_LEN and SENSOR_VALUE_LEN is 0, please use generic_sensor_write directly!");\r
+ return -1;\r
+}\r
+/* sensor register write */\r
+int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_reg)\r
+{\r
+ int err,cnt = 0,i;\r
+ u8 buf[6];\r
+ struct i2c_msg msg[1];\r
+ u32 i2c_speed;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ i2c_speed = sensor->info_priv.gI2c_speed;\r
+\r
+ err = 0;\r
+ switch(sensor_reg->reg){\r
+ case SEQCMD_WAIT_MS:\r
+ if (in_atomic())\r
+ mdelay(sensor_reg->val);\r
+ else\r
+ msleep(sensor_reg->val);\r
+ break;\r
+ case SEQCMD_WAIT_US:\r
+ udelay(sensor_reg->val);\r
+ break;\r
+ default: \r
+ cnt=0;\r
+ for (i=2; i>=0; i--) {\r
+ if(((sensor_reg->reg_mask) & (0xff<<(i*8)))) {\r
+ buf[cnt++] = ((sensor_reg->reg)>>(i*8))&0xff;\r
+ }\r
+ }\r
+ for (i=2; i>=0; i--) {\r
+ if(((sensor_reg->val_mask) & (0xff<<(i*8)))) {\r
+ buf[cnt++] = ((sensor_reg->val)>>(i*8))&0xff;\r
+ }\r
+ }\r
+ \r
+ msg->addr = client->addr;\r
+ msg->flags = client->flags;\r
+ msg->buf = buf;\r
+ msg->scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */\r
+ msg->read_type = 0; /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */\r
+ msg->len = cnt;\r
+ cnt = 3;\r
+ err = -EAGAIN;\r
+ \r
+ while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
+ err = i2c_transfer(client->adapter, msg, 1);\r
+ \r
+ if (err >= 0) {\r
+ err = 0;\r
+ goto write_end;\r
+ } else {\r
+ SENSOR_TR("write reg(0x%x, val:0x%x) failed, try to write again!",sensor_reg->reg, sensor_reg->val);\r
+ udelay(10);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+write_end:\r
+ return err;\r
+}\r
+\r
+/* sensor register write buffer */\r
+int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size)\r
+{\r
+ int err=0,cnt = 0,i;\r
+ struct i2c_msg msg[1];\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ msg->addr = client->addr;\r
+ msg->flags = client->flags;\r
+ msg->buf = buf;\r
+ msg->scl_rate = sensor->info_priv.gI2c_speed; /* ddl@rock-chips.com : 100kHz */\r
+ msg->read_type = 0; \r
+ msg->len = buf_size;\r
+ cnt = 3;\r
+ err = -EAGAIN;\r
+ \r
+ while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
+ err = i2c_transfer(client->adapter, msg, 1);\r
+ \r
+ if (err >= 0) {\r
+ err = 0;\r
+ goto write_end;\r
+ } else {\r
+ SENSOR_TR("generic_sensor_writebuf failed!");\r
+ udelay(10);\r
+ }\r
+ }\r
+\r
+\r
+write_end:\r
+ return err;\r
+}\r
+int sensor_read_reg1val1(struct i2c_client *client, u8 reg,u8* val){\r
+ \r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xff;\r
+ tmp_reg.val_mask = 0xff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = 0;\r
+ if(generic_sensor_read(client, &tmp_reg)==0){\r
+ *val = (u8)(tmp_reg.val & tmp_reg.val_mask);\r
+ }else{\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+int sensor_read_reg2val1(struct i2c_client *client, u16 reg,u8* val){\r
+ \r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xffff;\r
+ tmp_reg.val_mask = 0xff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = 0;\r
+ if(generic_sensor_read(client, &tmp_reg)==0){\r
+ *val = (u8)(tmp_reg.val & tmp_reg.val_mask);\r
+ }else{\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+int sensor_read_reg2val2(struct i2c_client *client, u16 reg,u16* val){\r
+ \r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xffff;\r
+ tmp_reg.val_mask = 0xffff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = 0;\r
+ if(generic_sensor_read(client, &tmp_reg)==0){\r
+ *val = (u16)(tmp_reg.val & tmp_reg.val_mask);\r
+ }else{\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+int sensor_read_reg1val2(struct i2c_client *client, u8 reg,u16* val){\r
+ \r
+ struct rk_sensor_reg tmp_reg;\r
+ \r
+ tmp_reg.reg_mask = 0xff;\r
+ tmp_reg.val_mask = 0xffff;\r
+ tmp_reg.reg = reg;\r
+ tmp_reg.val = 0;\r
+ if(generic_sensor_read(client, &tmp_reg)==0){\r
+ *val = (u16)(tmp_reg.val & tmp_reg.val_mask);\r
+ }else{\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+int sensor_read_reg0val0(struct i2c_client *client, u8 reg,u16 val) \r
+{\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_TR("SENSOR_REGISTER_LEN and SENSOR_VALUE_LEN is 0, please use generic_sensor_read directly!");\r
+ return -1;\r
+}\r
+/* sensor register read */\r
+int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_reg)\r
+{\r
+ int err,cnt = 0,i,bytes;\r
+ u8 buf_reg[3];\r
+ u8 buf_val[3];\r
+ struct i2c_msg msg[2];\r
+ u32 i2c_speed;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ i2c_speed = sensor->info_priv.gI2c_speed;\r
+ \r
+ cnt=0; \r
+ for (i=2; i>=0; i--) {\r
+ if((sensor_reg->reg_mask) & (0xff<<(i*8))) {\r
+ buf_reg[cnt++] = ((sensor_reg->reg)>>(i*8))&0xff;\r
+ }\r
+ }\r
+ \r
+ msg[0].addr = client->addr;\r
+ msg[0].flags = client->flags;\r
+ msg[0].buf = buf_reg;\r
+ msg[0].scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */\r
+ msg[0].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+ msg[0].len = cnt;\r
+\r
+ cnt=0;\r
+ for (i=2; i>=0; i--) {\r
+ if((sensor_reg->val_mask) & (0xff<<(i*8))) {\r
+ cnt++;\r
+ }\r
+ }\r
+ memset(buf_val,0x00,sizeof(buf_val));\r
+ \r
+ msg[1].addr = client->addr;\r
+ msg[1].flags = client->flags|I2C_M_RD;\r
+ msg[1].buf = buf_val;\r
+ msg[1].len = cnt;\r
+ msg[1].scl_rate = i2c_speed; /* ddl@rock-chips.com : 100kHz */\r
+ msg[1].read_type = 2; /* fpga i2c:0==I2C_NO_STOP : direct use number not enum for don't want include spi_fpga.h */\r
+\r
+ cnt = 1;\r
+ err = -EAGAIN;\r
+ while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */\r
+ err = i2c_transfer(client->adapter, msg, 2);\r
+ if (err >= 0) { \r
+ sensor_reg->val=0;\r
+ bytes = 0x00;\r
+ for (i=2; i>=0; i--) {\r
+ if((sensor_reg->val_mask) & (0xff<<(i*8))) {\r
+ sensor_reg->val |= (buf_val[bytes++]<<(i*8));\r
+ }\r
+ }\r
+ err = 0;\r
+ goto read_end;\r
+ } else {\r
+ SENSOR_TR("read reg(0x%x val:0x%x) failed, try to read again!",sensor_reg->reg, sensor_reg->val);\r
+ udelay(10);\r
+ }\r
+ }\r
+read_end:\r
+ return err;\r
+}\r
+\r
+/* write a array of registers */\r
+ int generic_sensor_write_array(struct i2c_client *client, struct rk_sensor_reg *regarray)\r
+{\r
+ int err = 0, cnt;\r
+ int i = 0;\r
+ bool streamchk;\r
+#if CONFIG_SENSOR_I2C_RDWRCHK\r
+ struct rk_sensor_reg check_reg;\r
+#endif\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ if (regarray[0].reg == SEQCMD_STREAMCHK) {\r
+ streamchk = true;\r
+ i = 1;\r
+ } else {\r
+ streamchk = false;\r
+ i = 0;\r
+ }\r
+\r
+ cnt = 0;\r
+ while ((regarray[i].reg != SEQCMD_END) && (regarray[i].reg != SEQCMD_INTERPOLATION))\r
+ {\r
+ if (streamchk) {\r
+ if (sensor->info_priv.stream == false) {\r
+ err = -1;\r
+ SENSOR_DG("sensor is stream off, write array terminated!");\r
+ break;\r
+ }\r
+ }\r
+ \r
+ if((sensor->info_priv.gReg_mask != 0) /*&& (regarray[i].reg_mask != 0)*/)\r
+ regarray[i].reg_mask = sensor->info_priv.gReg_mask;\r
+ if((sensor->info_priv.gVal_mask != 0) /* && (regarray[i].val_mask != 0)*/)\r
+ regarray[i].val_mask = sensor->info_priv.gVal_mask;\r
+ err = generic_sensor_write(client, &(regarray[i])); \r
+ if (err < 0)\r
+ {\r
+ if (cnt-- > 0) {\r
+ SENSOR_TR("write failed current reg:0x%x, Write array again !",regarray[i].reg);\r
+ i = 0;\r
+ continue;\r
+ } else {\r
+ SENSOR_TR("write array failed!");\r
+ err = -EPERM;\r
+ goto sensor_write_array_end;\r
+ }\r
+ } else {\r
+ #if CONFIG_SENSOR_I2C_RDWRCHK\r
+ check_reg.reg_mask = regarray[i].reg_mask;\r
+ check_reg.val_mask = regarray[i].val_mask;\r
+ check_reg.reg = regarray[i].reg;\r
+ check_reg.val =0;\r
+ generic_sensor_read(client, &check_reg);\r
+ if (check_reg.val!= regarray[i].val)\r
+ SENSOR_TR("Reg:0x%x write(0x%x, 0x%x) fail", regarray[i].reg, regarray[i].val, check_reg.val );\r
+ #endif\r
+ }\r
+\r
+ i++;\r
+ }\r
+\r
+\r
+sensor_write_array_end:\r
+ return err;\r
+}\r
+#if CONFIG_SENSOR_I2C_RDWRCHK\r
+int generic_sensor_readchk_array(struct i2c_client *client, struct rk_sensor_reg *regarray)\r
+{\r
+ int cnt;\r
+ int i = 0;\r
+ struct rk_sensor_reg check_reg;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ cnt = 0;\r
+ while (regarray[i].reg != SEQCMD_END)\r
+ {\r
+ check_reg.reg_mask = regarray[i].reg_mask;\r
+ check_reg.val_mask = regarray[i].val_mask;\r
+ check_reg.reg = regarray[i].reg;\r
+ check_reg.val =0;\r
+ generic_sensor_read(client, &check_reg);\r
+ if (check_reg.val!= regarray[i].val)\r
+ SENSOR_TR("Reg:0x%x write(0x%x, 0x%x) fail", regarray[i].reg, regarray[i].val, check_reg.val );\r
+\r
+ i++;\r
+ }\r
+ return 0;\r
+}\r
+#endif\r
+\r
+int generic_sensor_get_max_min_res(struct rk_sensor_sequence* res_array,int num,struct rk_sensor_seq_info * max_real_res,\r
+ struct rk_sensor_seq_info * max_res,struct rk_sensor_seq_info *min_res){\r
+ int array_index = 0,err = 0;\r
+ \r
+ max_real_res->w = max_res->w = 0;\r
+ max_real_res->h = max_res->h =0;\r
+ min_res->w = min_res->h = 10000;\r
+ if(!res_array || num <=0){\r
+ printk("resolution array not valid");\r
+ err = -1;\r
+ goto get_end;\r
+ }\r
+ \r
+ //serch min_res\r
+ while(array_index <num) {\r
+ if(res_array->data && res_array->data[0].reg != SEQCMD_END){\r
+ if(res_array->gSeq_info.w < min_res->w ||res_array->gSeq_info.h < min_res->h){\r
+ memcpy(min_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info));\r
+ }\r
+ if((res_array->gSeq_info.w > max_real_res->w ||res_array->gSeq_info.h > max_real_res->h) \r
+ && (res_array->data[0].reg != SEQCMD_INTERPOLATION)){\r
+ memcpy(max_real_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info));\r
+ }\r
+ if((res_array->gSeq_info.w > max_res->w ||res_array->gSeq_info.h > max_res->h) \r
+ && (res_array->data[0].reg == SEQCMD_INTERPOLATION)){\r
+ memcpy(max_res,&(res_array->gSeq_info),sizeof(struct rk_sensor_seq_info));\r
+ }\r
+ } \r
+ \r
+ array_index++;\r
+ res_array++;\r
+ \r
+ }\r
+ if((max_res->w < max_real_res->w) || (max_res->h < max_real_res->h)){\r
+ max_res->w = max_real_res->w;\r
+ max_res->h = max_real_res->h;\r
+ }\r
+ printk("min_w = %d,min_h = %d ,max_real_w = %d,max_real_h = %d,max_w = %d,max_h =%d\n",\r
+ min_res->w,min_res->h,max_real_res->w,max_real_res->h,max_res->w,max_res->h);\r
+ err = 0;\r
+get_end:\r
+ return err;\r
+}\r
+\r
+\r
+// return value: -1 means erro; others means res_array array index\r
+//se_w & set_h have been set to between MAX and MIN\r
+static int sensor_try_fmt(struct i2c_client *client,unsigned int *set_w,unsigned int *set_h){\r
+ int array_index = 0;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct rk_sensor_sequence* res_array = sensor->info_priv.sensor_series;\r
+ int num = sensor->info_priv.num_series;\r
+ int tmp_w = 10000,tmp_h = 10000,tmp_index = -1;\r
+ int resolution_diff_min=10000*10000,resolution_diff;\r
+\r
+ while(array_index < num) { \r
+ if ((res_array->data) && (res_array->data[0].reg != SEQCMD_END)) {\r
+ \r
+ if(res_array->property == SEQUENCE_INIT) {\r
+ tmp_index = array_index;\r
+ array_index++;\r
+ res_array++;\r
+ continue;\r
+ }\r
+\r
+ resolution_diff = abs(res_array->gSeq_info.w*res_array->gSeq_info.h - (*set_w)*(*set_h));\r
+ if (resolution_diff<resolution_diff_min) {\r
+ tmp_w = res_array->gSeq_info.w;\r
+ tmp_h = res_array->gSeq_info.h;\r
+ tmp_index = array_index;\r
+\r
+ resolution_diff_min = resolution_diff;\r
+ }\r
+ \r
+ }\r
+ array_index++;\r
+ res_array++;\r
+ }\r
+ *set_w = tmp_w;\r
+ *set_h = tmp_h;\r
+ //only has the init array\r
+ if((tmp_w == 10000) && (tmp_index != -1)){ \r
+ SENSOR_TR("have not other series meet the requirement except init_serie,array_index = %d",tmp_index);\r
+ *set_w = sensor->info_priv.sensor_series[tmp_index].gSeq_info.w;\r
+ *set_h = sensor->info_priv.sensor_series[tmp_index].gSeq_info.h;\r
+ goto try_end;\r
+ }\r
+ if((*set_w > sensor->info_priv.max_real_res.w) || (*set_h > sensor->info_priv.max_real_res.h)){\r
+ SENSOR_DG("it is a interpolation resolution!(%dx%d:%dx%d)",sensor->info_priv.max_real_res.w\r
+ ,sensor->info_priv.max_real_res.h,*set_w,*set_h);\r
+ *set_w = sensor->info_priv.max_real_res.w;\r
+ *set_h = sensor->info_priv.max_real_res.h;\r
+ //find the max_real_res index\r
+ res_array = sensor->info_priv.sensor_series;\r
+ array_index = 0;\r
+ tmp_index = -1;\r
+ while(array_index < num){\r
+ 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)){\r
+ if((res_array->property != SEQUENCE_INIT)){\r
+ tmp_index = array_index;\r
+ break;\r
+ }else{\r
+ tmp_index = array_index;\r
+ }\r
+ }\r
+ array_index++;\r
+ res_array++ ;\r
+ }\r
+ \r
+ }\r
+try_end:\r
+ return tmp_index;\r
+}\r
+int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ const struct rk_sensor_datafmt *fmt;\r
+ int ret = 0;\r
+ unsigned int set_w,set_h,ori_w,ori_h;\r
+ \r
+ ori_w = mf->width;\r
+ ori_h = mf->height;\r
+ \r
+ fmt = generic_sensor_find_datafmt(mf->code, sensor->info_priv.datafmt,\r
+ sensor->info_priv.num_datafmt);\r
+ if (fmt == NULL) {\r
+ fmt = &(sensor->info_priv.curfmt);\r
+ mf->code = fmt->code;\r
+ }\r
+ /* ddl@rock-chips.com : It is query max resolution only. */\r
+ if (mf->reserved[6] == 0xfefe5a5a) {\r
+ mf->height = sensor->info_priv.max_res.h ;\r
+ mf->width = sensor->info_priv.max_res.w;\r
+ ret = 0;\r
+ SENSOR_DG("Query resolution: %dx%d",mf->width, mf->height);\r
+ goto generic_sensor_try_fmt_end;\r
+ }\r
+ //use this to filter unsupported resolutions\r
+ if (sensor->sensor_cb.sensor_try_fmt_cb_th){\r
+ ret = sensor->sensor_cb.sensor_try_fmt_cb_th(client, mf);\r
+ if(ret < 0)\r
+ goto generic_sensor_try_fmt_end;\r
+ }\r
+ if (mf->height > sensor->info_priv.max_res.h)\r
+ mf->height = sensor->info_priv.max_res.h;\r
+ else if (mf->height < sensor->info_priv.min_res.h)\r
+ mf->height = sensor->info_priv.min_res.h;\r
+\r
+ if (mf->width > sensor->info_priv.max_res.w)\r
+ mf->width = sensor->info_priv.max_res.w;\r
+ else if (mf->width < sensor->info_priv.min_res.w)\r
+ mf->width = sensor->info_priv.min_res.w;\r
+ set_w = mf->width;\r
+ set_h = mf->height; \r
+ ret = sensor_try_fmt(client,&set_w,&set_h);\r
+ mf->width = set_w;\r
+ mf->height = set_h;\r
+ mf->colorspace = fmt->colorspace;\r
+ SENSOR_DG("%dx%d is the closest for %dx%d",ori_w,ori_h,set_w,set_h);\r
+generic_sensor_try_fmt_end:\r
+ return ret;\r
+}\r
+\r
+int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival){\r
+ int err = 0,index_tmp;\r
+ unsigned int set_w,set_h;\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ if (fival->height > sensor->info_priv.max_res.h|| fival->width > sensor->info_priv.max_res.w){\r
+ SENSOR_TR("this resolution(%dx%d) isn't support!",fival->width,fival->height);\r
+ err = -1;\r
+ goto enum_frameintervals_end;\r
+ }\r
+ set_w = fival->width;\r
+ set_h = fival->height;\r
+ index_tmp = sensor_try_fmt(client,&set_w,&set_h);\r
+ fival->discrete.denominator = sensor->info_priv.sensor_series[index_tmp].gSeq_info.fps;\r
+ fival->discrete.numerator = 1000;\r
+ fival->reserved[1] = (set_w<<16)|set_h;\r
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
+\r
+ SENSOR_DG("%dx%d(real:%dx%d) framerate: %d",fival->width,fival->height,set_w,set_h,fival->discrete.denominator);\r
+enum_frameintervals_end:\r
+ return err;\r
+}\r
+\r
+static enum hrtimer_restart generic_flash_off_func(struct hrtimer *timer){\r
+ struct rk_flash_timer *fps_timer = container_of(timer, struct rk_flash_timer, timer);\r
+\r
+ generic_sensor_ioctrl(fps_timer->icd,Sensor_Flash,0);\r
+ return 0;\r
+}\r
+/* Find a data format by a pixel code in an array */\r
+static const struct rk_sensor_datafmt *generic_sensor_find_datafmt(\r
+ enum v4l2_mbus_pixelcode code, const struct rk_sensor_datafmt *fmt,\r
+ int n)\r
+{\r
+ int i;\r
+ for (i = 0; i < n; i++)\r
+ if (fmt[i].code == code)\r
+ return fmt + i;\r
+\r
+ return NULL;\r
+}\r
+\r
+int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series) {\r
+ int ret = 0;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+\r
+ if (sensor->sensor_cb.sensor_softreset_cb)\r
+ sensor->sensor_cb.sensor_softreset_cb(client,series);\r
+ \r
+ /* soft reset */\r
+ ret = generic_sensor_write_array(client,series);\r
+ if (ret != 0) {\r
+ SENSOR_TR("soft reset failed\n");\r
+ ret = -ENODEV;\r
+ }\r
+ msleep(1);\r
+ return ret;\r
+ \r
+}\r
+int generic_sensor_check_id(struct i2c_client *client, struct rk_sensor_reg *series)\r
+{\r
+ int ret,pid = 0,i;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ if (sensor->sensor_cb.sensor_check_id_cb)\r
+ pid = sensor->sensor_cb.sensor_check_id_cb(client,series);\r
+\r
+ /* check if it is an sensor sensor */\r
+ while (series->reg != SEQCMD_END) {\r
+\r
+ pid <<= 8;\r
+ \r
+ if (sensor->info_priv.gReg_mask != 0x00) \r
+ series->reg_mask = sensor->info_priv.gReg_mask;\r
+ if (sensor->info_priv.gVal_mask != 0x00)\r
+ series->val_mask = sensor->info_priv.gVal_mask;\r
+ \r
+ ret = generic_sensor_read(client, series);\r
+ if (ret != 0) {\r
+ SENSOR_TR("read chip id failed");\r
+ ret = -ENODEV;\r
+ goto check_end;\r
+ }\r
+\r
+ pid |= series->val;\r
+ series++;\r
+ }\r
+ \r
+ SENSOR_DG("pid = 0x%x", pid);\r
+\r
+ for (i=0; i<sensor->info_priv.chip_id_num; i++) {\r
+ if (pid == sensor->info_priv.chip_id[i]) {\r
+ sensor->model = sensor->info_priv.chip_ident; \r
+ break;\r
+ }\r
+ }\r
+ \r
+ if (sensor->model != sensor->info_priv.chip_ident) {\r
+ SENSOR_TR("error: mismatched pid = 0x%x\n", pid);\r
+ ret = -ENODEV;\r
+ goto check_end;\r
+ } else {\r
+ ret = 0;\r
+ }\r
+ \r
+check_end:\r
+ return ret;\r
+}\r
+\r
+int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on)\r
+{\r
+ struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+ struct rk29camera_platform_data *pdata = icl->priv_usr;\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ int ret = 0;\r
+\r
+ SENSOR_DG("%s cmd(%d) on(%d)\n",__FUNCTION__,cmd,on);\r
+ switch (cmd)\r
+ {\r
+ case Sensor_Power:\r
+ {\r
+ if (icl->power) {\r
+ ret = icl->power(icd->pdev, on);\r
+ } else {\r
+ SENSOR_TR("haven't power callback");\r
+ ret = -EINVAL;\r
+ }\r
+ break;\r
+ }\r
+ case Sensor_PowerDown:\r
+ {\r
+ if (icl->powerdown) {\r
+ ret = icl->powerdown(icd->pdev, on);\r
+ } else {\r
+ SENSOR_TR("haven't power down callback");\r
+ ret = -EINVAL;\r
+ }\r
+ break;\r
+ }\r
+ case Sensor_Flash:\r
+ {\r
+ if (pdata && pdata->sensor_ioctrl) {\r
+ pdata->sensor_ioctrl(icd->pdev,Cam_Flash, on);\r
+ if(on==Flash_On){\r
+ //flash off after 1.5 secs\r
+ hrtimer_cancel(&(sensor->flash_off_timer.timer));\r
+ hrtimer_start(&(sensor->flash_off_timer.timer),ktime_set(0, 1500*1000*1000),HRTIMER_MODE_REL);\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ SENSOR_TR("%s cmd(%d) is unknown!",__FUNCTION__,cmd);\r
+ break;\r
+ }\r
+ }\r
+ \r
+ return ret;\r
+}\r
+\r
+int generic_sensor_init(struct v4l2_subdev *sd, u32 val)\r
+{\r
+ int ret = 0;\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ int array_index = 0;\r
+ int num = sensor->info_priv.num_series; \r
+ struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+ struct rk29camera_platform_data *pdata = icl->priv_usr;\r
+ struct rkcamera_platform_data *sensor_device=NULL,*new_camera;\r
+\r
+ new_camera = pdata->register_dev_new;\r
+ while (strstr(new_camera->dev_name,"end")==NULL) {\r
+ if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) {\r
+ sensor_device = new_camera;\r
+ break;\r
+ }\r
+ new_camera++;\r
+ }\r
+ \r
+ /* ddl@rock-chips.com : i2c speed is config in new_camera_device_ex macro */\r
+ if (sensor_device) {\r
+ sensor->info_priv.gI2c_speed = sensor_device->i2c_rate;\r
+ sensor->info_priv.mirror = sensor_device->mirror;\r
+ }\r
+ \r
+ if (((sensor_device!=NULL) && Sensor_HasBeen_PwrOff(sensor_device->pwdn_info)) \r
+ || (sensor_device == NULL)) { \r
+ \r
+ //softreset callback\r
+ ret = generic_sensor_softreset(client,sensor->info_priv.sensor_SfRstSeqe);\r
+ if(ret != 0){\r
+ SENSOR_TR("soft reset failed!");\r
+ goto sensor_INIT_ERR;\r
+ }\r
+ \r
+ while(array_index < num){\r
+ if(sensor->info_priv.sensor_series[array_index].property == SEQUENCE_INIT)\r
+ break;\r
+ array_index++;\r
+ }\r
+ if(generic_sensor_write_array(client, sensor->info_priv.sensor_series[array_index].data)!=0){\r
+ SENSOR_TR("write init array failed!");\r
+ ret = -1;\r
+ goto sensor_INIT_ERR;\r
+ }\r
+ if (sensor_device!=NULL) {\r
+ sensor_device->pwdn_info &= 0xfe;\r
+ if (sensor->sensor_cb.sensor_mirror_cb)\r
+ sensor->sensor_cb.sensor_mirror_cb(client, sensor->info_priv.mirror&0x01);\r
+ if (sensor->sensor_cb.sensor_flip_cb)\r
+ sensor->sensor_cb.sensor_flip_cb(client, sensor->info_priv.mirror&0x02);\r
+ }\r
+ sensor->info_priv.winseqe_cur_addr = sensor->info_priv.sensor_series + array_index;\r
+\r
+ //set focus status ,init focus\r
+ sensor->sensor_focus.focus_state = FocusState_Inval;\r
+ sensor->sensor_focus.focus_mode = WqCmd_af_invalid;\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_invalid; \r
+ \r
+ }\r
+ \r
+ if (sensor->sensor_cb.sensor_activate_cb)\r
+ sensor->sensor_cb.sensor_activate_cb(client);\r
+ \r
+\r
+ if (sensor->flash_off_timer.timer.function==NULL)\r
+ sensor->flash_off_timer.timer.function = generic_flash_off_func;\r
+ \r
+ sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK;\r
+ \r
+ return 0;\r
+sensor_INIT_ERR:\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ if(sensor->sensor_cb.sensor_deactivate_cb)\r
+ sensor->sensor_cb.sensor_deactivate_cb(client);\r
+ return ret;\r
+}\r
+ int generic_sensor_set_bus_param(struct soc_camera_device *icd,\r
+ unsigned long flags)\r
+{\r
+\r
+ return 0;\r
+}\r
+\r
+unsigned long generic_sensor_query_bus_param(struct soc_camera_device *icd)\r
+{\r
+ struct soc_camera_link *icl = to_soc_camera_link(icd);\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ unsigned long flags = sensor->info_priv.bus_parameter;\r
+\r
+ return soc_camera_apply_sensor_flags(icl, flags);\r
+}\r
+int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ mf->width = icd->user_width;\r
+ mf->height = icd->user_height;\r
+ mf->code = sensor->info_priv.curfmt.code;\r
+ mf->colorspace = sensor->info_priv.curfmt.colorspace;\r
+ mf->field = V4L2_FIELD_NONE;\r
+\r
+ return 0;\r
+}\r
+int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ const struct rk_sensor_datafmt *fmt;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct rk_sensor_sequence *winseqe_set_addr=NULL;\r
+ bool is_capture=(mf->reserved[7]==0xfefe5a5a)?true:false;\r
+ int ret=0;\r
+\r
+ fmt =generic_sensor_find_datafmt(mf->code, sensor->info_priv.datafmt,\r
+ sensor->info_priv.num_datafmt);\r
+ if (!fmt) {\r
+ ret = -EINVAL;\r
+ goto sensor_s_fmt_end;\r
+ }\r
+ \r
+ // get the proper series and write the array\r
+ ret =generic_sensor_try_fmt(sd, mf);\r
+ winseqe_set_addr = sensor->info_priv.sensor_series+ret;\r
+\r
+ ret = 0; \r
+ if(sensor->info_priv.winseqe_cur_addr->data != winseqe_set_addr->data){\r
+\r
+ if (sensor->sensor_cb.sensor_s_fmt_cb_th)\r
+ ret |= sensor->sensor_cb.sensor_s_fmt_cb_th(client, mf, is_capture);\r
+ \r
+ ret |= generic_sensor_write_array(client, winseqe_set_addr->data);\r
+ if (ret != 0) {\r
+ SENSOR_TR("set format capability failed");\r
+ goto sensor_s_fmt_end;\r
+ }\r
+\r
+ if (sensor->sensor_cb.sensor_s_fmt_cb_bh)\r
+ ret |= sensor->sensor_cb.sensor_s_fmt_cb_bh(client, mf, is_capture);\r
+ sensor->info_priv.winseqe_cur_addr = winseqe_set_addr;\r
+ SENSOR_DG("Sensor output is changed to %dx%d",winseqe_set_addr->gSeq_info.w,winseqe_set_addr->gSeq_info.h);\r
+ } else {\r
+ SENSOR_DG("Sensor output is still %dx%d",winseqe_set_addr->gSeq_info.w,winseqe_set_addr->gSeq_info.h);\r
+ }\r
+ \r
+//video or capture special process\r
+sensor_s_fmt_end:\r
+ return ret;\r
+}\r
+ int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)\r
+ return -EINVAL;\r
+\r
+ if (id->match.addr != client->addr)\r
+ return -ENODEV;\r
+\r
+ id->ident = sensor->info_priv.chip_ident; /* ddl@rock-chips.com : Return OV2655 identifier */\r
+ id->revision = 0;\r
+\r
+ return 0;\r
+}\r
+int generic_sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)\r
+{ \r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ \r
+ if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) {\r
+ if (value == 3) { /* ddl@rock-chips.com: torch */\r
+ generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */\r
+ } else {\r
+ generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+ }\r
+ SENSOR_DG("%s : %x",__FUNCTION__, value);\r
+ return 0;\r
+ }\r
+\r
+ SENSOR_TR("%s valure = %d is invalidate",__FUNCTION__,value);\r
+ return -EINVAL;\r
+}\r
+int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); \r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ int value = ext_ctrl->value;\r
+\r
+ if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
+ printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
+ ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
+ return -EINVAL;\r
+ }\r
+\r
+ if (value == 3) { /* ddl@rock-chips.com: torch */\r
+ generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */\r
+ } else {\r
+ generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off);\r
+ }\r
+ SENSOR_DG("%s : %x",__FUNCTION__, value);\r
+ return 0;\r
+}\r
+ \r
+int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct sensor_v4l2ctrl_info_s *ctrl_info;\r
+ int ret = 0;\r
+\r
+ ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id);\r
+ if (!ctrl_info) {\r
+ SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id);\r
+ ret = -EINVAL;\r
+ } else {\r
+ ctrl->value = ctrl_info->cur_value;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct sensor_v4l2ctrl_info_s *ctrl_info;\r
+ struct v4l2_ext_control ext_ctrl;\r
+ int ret = 0;\r
+\r
+ ctrl_info = sensor_find_ctrl(sensor->ctrls,ctrl->id);\r
+ if (!ctrl_info) {\r
+ SENSOR_TR("v4l2_control id(0x%x) is invalidate",ctrl->id);\r
+ ret = -EINVAL;\r
+ } else {\r
+\r
+ ext_ctrl.id = ctrl->id;\r
+ ext_ctrl.value = ctrl->value;\r
+ \r
+ if (ctrl_info->cb) {\r
+ ret = (ctrl_info->cb)(icd,ctrl_info, &ext_ctrl);\r
+ } else {\r
+ SENSOR_TR("v4l2_control id(0x%x) callback isn't exist",ctrl->id);\r
+ ret = -EINVAL;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct sensor_v4l2ctrl_info_s *ctrl_info;\r
+ int ret = 0;\r
+\r
+ ctrl_info = sensor_find_ctrl(sensor->ctrls,ext_ctrl->id);\r
+ if (!ctrl_info) {\r
+ SENSOR_TR("v4l2_control id(0x%x) is invalidate",ext_ctrl->id);\r
+ ret = -EINVAL;\r
+ } else {\r
+ ext_ctrl->value = ctrl_info->cur_value;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct sensor_v4l2ctrl_info_s *ctrl_info;\r
+ int ret = 0;\r
+ \r
+ ctrl_info = sensor_find_ctrl(sensor->ctrls,ext_ctrl->id);\r
+ if (!ctrl_info) {\r
+ SENSOR_TR("v4l2_ext_control id(0x%x) is invalidate",ext_ctrl->id);\r
+ ret = -EINVAL;\r
+ } else { \r
+ if (ctrl_info->cb) {\r
+ ret = (ctrl_info->cb)(icd,ctrl_info, ext_ctrl);\r
+ } else {\r
+ SENSOR_TR("v4l2_ext_control id(0x%x) callback isn't exist",ext_ctrl->id);\r
+ ret = -EINVAL;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+ int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+ {\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ //struct generic_sensor *sensor = to_generic_sensor(client);\r
+ int i, error_cnt=0, error_idx=-1;\r
+ \r
+ for (i=0; i<ext_ctrl->count; i++) {\r
+ if (generic_sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+ error_cnt++;\r
+ error_idx = i;\r
+ }\r
+ }\r
+ \r
+ if (error_cnt > 1)\r
+ error_idx = ext_ctrl->count;\r
+ \r
+ if (error_idx != -1) {\r
+ ext_ctrl->error_idx = error_idx;\r
+ return -EINVAL;\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ int i, error_cnt=0, error_idx=-1;\r
+\r
+\r
+ for (i=0; i<ext_ctrl->count; i++) {\r
+ \r
+ if (generic_sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {\r
+ error_cnt++;\r
+ error_idx = i;\r
+ }\r
+ }\r
+\r
+ if (error_cnt > 1)\r
+ error_idx = ext_ctrl->count;\r
+\r
+ if (error_idx != -1) {\r
+ ext_ctrl->error_idx = error_idx;\r
+ return -EINVAL;\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+ \r
+ \r
+long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)\r
+{\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ int ret = 0;\r
+ int i;\r
+ bool flash_attach=false;\r
+ struct rkcamera_platform_data *new_camera;\r
+\r
+ SENSOR_DG("%s cmd: 0x%x ",__FUNCTION__,cmd);\r
+ switch (cmd)\r
+ {\r
+ case RK29_CAM_SUBDEV_DEACTIVATE:\r
+ {\r
+ if(sensor->sensor_cb.sensor_deactivate_cb)\r
+ sensor->sensor_cb.sensor_deactivate_cb(client);\r
+ break;\r
+ }\r
+\r
+ case RK29_CAM_SUBDEV_IOREQUEST:\r
+ {\r
+ sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; \r
+ if (sensor->sensor_io_request != NULL) { \r
+ sensor->sensor_gpio_res = NULL;\r
+ for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {\r
+ if (sensor->sensor_io_request->gpio_res[i].dev_name && \r
+ (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {\r
+ sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];\r
+ }\r
+ } \r
+ } else {\r
+ SENSOR_TR("RK29_CAM_SUBDEV_IOREQUEST fail");\r
+ ret = -EINVAL;\r
+ goto sensor_ioctl_end;\r
+ }\r
+ /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control \r
+ for this project */\r
+ if (sensor->sensor_gpio_res) { \r
+ if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) {\r
+ flash_attach = false;\r
+ } else { \r
+ flash_attach = true;\r
+ }\r
+ }\r
+\r
+ new_camera = sensor->sensor_io_request->register_dev_new;\r
+ while (strstr(new_camera->dev_name,"end")==NULL) {\r
+ if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) {\r
+ if (new_camera->flash){\r
+ flash_attach = true;\r
+ } else { \r
+ flash_attach = false;\r
+ }\r
+ break;\r
+ }\r
+ new_camera++;\r
+ }\r
+\r
+ if (flash_attach==false) {\r
+ for (i = 0; i < icd->ops->num_controls; i++) {\r
+ if (V4L2_CID_FLASH == icd->ops->controls[i].id) {\r
+ sensor->sensor_controls[i].id |= 0x80000000; \r
+ }\r
+ }\r
+ } else {\r
+ for (i = 0; i < icd->ops->num_controls; i++) {\r
+ if(V4L2_CID_FLASH == (icd->ops->controls[i].id&0x7fffffff)){\r
+ sensor->sensor_controls[i].id &= 0x7fffffff;\r
+ } \r
+ }\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ SENSOR_TR("%s cmd(0x%x) is unknown !\n",__FUNCTION__,cmd);\r
+ break;\r
+ }\r
+ }\r
+sensor_ioctl_end:\r
+ return ret;\r
+}\r
+ \r
+int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,\r
+ enum v4l2_mbus_pixelcode *code)\r
+{\r
+\r
+ struct i2c_client *client = v4l2_get_subdevdata(sd);\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ if (index >= sensor->info_priv.num_datafmt)\r
+ return -EINVAL;\r
+\r
+ *code = sensor->info_priv.datafmt[index].code;\r
+ return 0;\r
+} \r
+ static void sensor_af_workqueue(struct work_struct *work)\r
+{\r
+ struct rk_sensor_focus_work *sensor_work = container_of(work, struct rk_sensor_focus_work, dwork.work);\r
+ struct i2c_client *client = sensor_work->client;\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ //struct rk_sensor_focus_cmd_info cmdinfo;\r
+ int zone_tm_pos[4];\r
+ int ret = 0;\r
+ \r
+ SENSOR_DG("%s Enter, cmd:0x%x",__FUNCTION__,sensor_work->cmd);\r
+ \r
+ switch (sensor_work->cmd) \r
+ {\r
+ case WqCmd_af_init:\r
+ {\r
+ if (sensor->sensor_focus.focus_state == FocusState_Inval) { \r
+ if(sensor->sensor_focus.focus_cb.sensor_focus_init_cb !=NULL) {\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_focus_init_cb)(client);\r
+ }\r
+ if (ret < 0) {\r
+ SENSOR_TR("WqCmd_af_init is failed in sensor_af_workqueue!");\r
+ } else {\r
+ if(sensor->sensor_focus.focus_delay != WqCmd_af_invalid) {\r
+ generic_sensor_af_workqueue_set(client->dev.platform_data,sensor->sensor_focus.focus_delay,0,false);\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_invalid;\r
+ }\r
+ sensor->sensor_focus.focus_state = FocusState_Inited;\r
+ sensor_work->result = WqRet_success;\r
+ }\r
+ } else {\r
+ sensor_work->result = WqRet_success;\r
+ SENSOR_DG("sensor af have been inited, WqCmd_af_init is ignore!");\r
+ }\r
+ break;\r
+ }\r
+ case WqCmd_af_single:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_single_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_single_cb)(client);\r
+ }\r
+ if (ret < 0) {\r
+ SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!",SENSOR_NAME_STRING());\r
+ sensor_work->result = WqRet_fail;\r
+ } else {\r
+ sensor_work->result = WqRet_success;\r
+ }\r
+ break;\r
+ }\r
+ case WqCmd_af_near_pos:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_near_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_near_cb)(client);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else{ \r
+ sensor_work->result = WqRet_success;\r
+ }\r
+ break;\r
+ }\r
+ case WqCmd_af_far_pos:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_far_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_far_cb)(client);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else \r
+ sensor_work->result = WqRet_success;\r
+ break;\r
+ }\r
+ case WqCmd_af_special_pos:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_specialpos_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_specialpos_cb)(client,sensor_work->var);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else \r
+ sensor_work->result = WqRet_success;\r
+ break;\r
+ }\r
+ case WqCmd_af_continues:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_const_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_const_cb)(client);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else \r
+ sensor_work->result = WqRet_success;\r
+ break;\r
+ }\r
+ case WqCmd_af_update_zone:\r
+ {\r
+ mutex_lock(&sensor->sensor_focus.focus_lock);\r
+ zone_tm_pos[0] = sensor->sensor_focus.focus_zone.lx;\r
+ zone_tm_pos[1] = sensor->sensor_focus.focus_zone.ty;\r
+ zone_tm_pos[2] = sensor->sensor_focus.focus_zone.rx;\r
+ zone_tm_pos[3] = sensor->sensor_focus.focus_zone.dy;\r
+ mutex_unlock(&sensor->sensor_focus.focus_lock);\r
+ \r
+ if(sensor->sensor_focus.focus_cb.sensor_af_zoneupdate_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_zoneupdate_cb)(client,zone_tm_pos);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else \r
+ sensor_work->result = WqRet_success;\r
+ break;\r
+ }\r
+ case WqCmd_af_close:\r
+ {\r
+ if(sensor->sensor_focus.focus_cb.sensor_af_close_cb!=NULL){\r
+ ret = (sensor->sensor_focus.focus_cb.sensor_af_close_cb)(client);\r
+ }\r
+ if (ret < 0)\r
+ sensor_work->result = WqRet_fail;\r
+ else \r
+ sensor_work->result = WqRet_success;\r
+ break;\r
+ }\r
+ default:\r
+ SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING());\r
+ break;\r
+ }\r
+ \r
+set_end: \r
+ if (sensor_work->wait == false) {\r
+ kfree((void*)sensor_work);\r
+ } else {\r
+ wake_up(&sensor_work->done); \r
+ }\r
+ return;\r
+}\r
+\r
+ int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ struct rk_sensor_focus_work *wk;\r
+ int ret=0;\r
+\r
+ if (sensor->sensor_focus.sensor_wq == NULL) { \r
+ ret = -EINVAL;\r
+ goto sensor_af_workqueue_set_end;\r
+ }\r
+\r
+ wk = kzalloc(sizeof(struct rk_sensor_focus_work), GFP_KERNEL);\r
+ if (wk) {\r
+ wk->client = client;\r
+ INIT_DELAYED_WORK(&wk->dwork, sensor_af_workqueue);\r
+ wk->cmd = cmd;\r
+ wk->result = WqRet_inval;\r
+ wk->wait = wait;\r
+ wk->var = var;\r
+ init_waitqueue_head(&wk->done);\r
+\r
+ SENSOR_DG("generic_sensor_af_workqueue_set: cmd: %d",cmd);\r
+ \r
+ /* ddl@rock-chips.com: \r
+ * video_lock is been locked in v4l2_ioctl function, but auto focus may slow,\r
+ * As a result any other ioctl calls will proceed very, very slowly since each call\r
+ * will have to wait for the AF to finish. Camera preview is pause,because VIDIOC_QBUF \r
+ * and VIDIOC_DQBUF is sched. so unlock video_lock here.\r
+ */\r
+ if (wait == true) {\r
+ queue_delayed_work(sensor->sensor_focus.sensor_wq,&(wk->dwork),0);\r
+ mutex_unlock(&icd->video_lock); \r
+ if (wait_event_timeout(wk->done, (wk->result != WqRet_inval), msecs_to_jiffies(5000)) == 0) {\r
+ SENSOR_TR("af cmd(%d) is timeout!",cmd); \r
+ }\r
+ flush_workqueue(sensor->sensor_focus.sensor_wq);\r
+ ret = wk->result;\r
+ kfree((void*)wk);\r
+ mutex_lock(&icd->video_lock); \r
+ } else {\r
+ queue_delayed_work(sensor->sensor_focus.sensor_wq,&(wk->dwork),msecs_to_jiffies(10));\r
+ }\r
+ } else {\r
+ SENSOR_TR("af cmd(%d) ingore,because struct sensor_work malloc failed!",cmd);\r
+ ret = -1;\r
+ }\r
+sensor_af_workqueue_set_end:\r
+ return ret;\r
+} \r
+\r
+\r
+int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable)\r
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+ SENSOR_DG("s_stream: %d %d",enable,sensor->sensor_focus.focus_state);\r
+ if (enable == 1) {\r
+ sensor->info_priv.stream = true;\r
+ if (sensor->sensor_focus.sensor_wq) {\r
+ if (sensor->sensor_focus.focus_state == FocusState_Inval) {\r
+ generic_sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false); \r
+ }\r
+ }\r
+ } else if (enable == 0) {
+ sensor->info_priv.stream = false;\r
+ if (sensor->sensor_focus.sensor_wq)\r
+ flush_workqueue(sensor->sensor_focus.sensor_wq);\r
+ \r
+ }\r
+ return 0;\r
+} \r
+\r
--- /dev/null
+#ifndef __ASM_ARCH_GENERIC_SENSOR_RK_H_\r
+#include <linux/videodev2.h>\r
+#include <linux/slab.h>\r
+#include <linux/i2c.h>\r
+#include <linux/stat.h>\r
+#include <linux/log2.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/delay.h>\r
+#include <linux/circ_buf.h>\r
+#include <linux/miscdevice.h>\r
+#include <media/v4l2-common.h>\r
+#include <media/v4l2-chip-ident.h>\r
+#include <media/soc_camera.h>\r
+#include <linux/vmalloc.h>\r
+#include <plat/rk_camera.h>\r
+\r
+/* Camera Sensor driver */\r
+\r
+#define MIN(x,y) ((x<y) ? x: y)\r
+#define MAX(x,y) ((x>y) ? x: y)\r
+\r
+#define SENSOR_TR(format, ...) printk(KERN_ERR "%s(%d): " format"\n", SENSOR_NAME_STRING(),__LINE__, ## __VA_ARGS__)\r
+#define SENSOR_DG(format, ...) dprintk(1, "%s(%d): "format"\n", SENSOR_NAME_STRING(),__LINE__,## __VA_ARGS__)\r
+\r
+//to generic sensor\r
+//a represents a i2c_client type point\r
+#define to_generic_sensor(a) (container_of(i2c_get_clientdata(a), struct generic_sensor, subdev))\r
+\r
+//to specific sensor\r
+//a represents a generic_sensor type point\r
+#define to_specific_sensor(a) (container_of(a, struct specific_sensor, common_sensor))\r
+\r
+#define SENSOR_INIT_IS_ERR (0x00<<28)\r
+#define SENSOR_INIT_IS_OK (0x01<<28)\r
+\r
+#define SEQCMD_STREAMCHK 0xFA000000\r
+#define SEQCMD_INVALIDATE 0xFB000000\r
+#define SEQCMD_INTERPOLATION 0xFC000000\r
+#define SEQCMD_WAIT_MS 0xFD000000\r
+#define SEQCMD_WAIT_US 0xFE000000\r
+#define SEQCMD_END 0xFF000000\r
+\r
+#define SensorReg0Val0(a,b) {SEQCMD_INVALIDATE,0,0,0}\r
+#define SensorReg1Val1(a,b) {a,b,0xff,0xff}\r
+#define SensorReg2Val1(a,b) {a,b,0xffff,0xff}\r
+#define SensorReg2Val2(a,b) {a,b,0xffff,0xffff}\r
+\r
+#define SensorStreamChk {SEQCMD_STREAMCHK,0,0,0}\r
+#define SensorWaitMs(a) {SEQCMD_WAIT_MS,a,0x00,0x00}\r
+#define SensorWaitUs(a) {SEQCMD_WAIT_US,a,0x00,0x00}\r
+#define SensorEnd {SEQCMD_END,0x00,0x00,0x00}\r
+\r
+#define CFG_WhiteBalance (1<<0)\r
+#define CFG_Brightness (1<<1)\r
+#define CFG_Contrast (1<<2)\r
+#define CFG_Saturation (1<<3)\r
+#define CFG_Effect (1<<4)\r
+#define CFG_Scene (1<<5)\r
+#define CFG_DigitalZoom (1<<6)\r
+#define CFG_Focus (1<<7)\r
+#define CFG_FocusContinues (1<<8)\r
+#define CFG_FocusZone (1<<9)\r
+#define CFG_FocusRelative (1<<10)\r
+#define CFG_FocusAbsolute (1<<11)\r
+#define CFG_FACE_DETECT (1<<12)\r
+#define CFG_Exposure (1<<13)\r
+#define CFG_Flash (1<<14)\r
+#define CFG_Mirror (1<<15)\r
+#define CFG_Flip (1<<16)\r
+\r
+#define CFG_FunChk(a,b) ((a&b)==b) \r
+#define CFG_FunDis(a,b) (a &= (~b))\r
+\r
+enum rk_sensor_sequence_property {\r
+ SEQUENCE_INIT =1,\r
+ SEQUENCE_PREVIEW,\r
+ SEQUENCE_CAPTURE\r
+};\r
+\r
+struct rk_sensor_reg {\r
+ unsigned int reg;\r
+ unsigned int val;\r
+ unsigned int reg_mask;\r
+ unsigned int val_mask;\r
+};\r
+\r
+struct rk_sensor_seq_info {\r
+ unsigned short w;\r
+ unsigned short h;\r
+ unsigned short fps;\r
+};\r
+struct rk_sensor_sequence {\r
+ struct rk_sensor_seq_info gSeq_info;\r
+ enum rk_sensor_sequence_property property;\r
+ struct rk_sensor_reg *data;\r
+};\r
+\r
+/* only one fixed colorspace per pixelcode */\r
+struct rk_sensor_datafmt {\r
+ enum v4l2_mbus_pixelcode code;\r
+ enum v4l2_colorspace colorspace;\r
+};\r
+\r
+\r
+//focus work\r
+enum rk_sensor_focus_wq_cmd\r
+{\r
+ WqCmd_af_invalid = -1,\r
+ WqCmd_af_init =1,\r
+ WqCmd_af_single,\r
+ WqCmd_af_continues,\r
+ WqCmd_af_update_zone,\r
+ WqCmd_af_close,\r
+ WqCmd_af_special_pos,\r
+ WqCmd_af_near_pos,\r
+ WqCmd_af_far_pos\r
+ \r
+};\r
+enum rk_sensor_focus_sensor_wq_result\r
+{\r
+ WqRet_success = 0,\r
+ WqRet_fail = -1,\r
+ WqRet_inval = -2\r
+};\r
+\r
+enum rk_sensor_focus_state\r
+{\r
+ FocusState_Inval,\r
+ FocusState_Inited\r
+};\r
+\r
+struct rk_sensor_focus_work\r
+{\r
+ struct i2c_client *client;\r
+ struct delayed_work dwork;\r
+ enum rk_sensor_focus_wq_cmd cmd;\r
+ wait_queue_head_t done;\r
+ enum rk_sensor_focus_sensor_wq_result result;\r
+ bool wait;\r
+ int var; \r
+};\r
+\r
+//focus structs\r
+struct rk_sensor_focus_cb{\r
+ int (*sensor_focus_init_cb)(struct i2c_client *client); \r
+ int (*sensor_af_single_cb)(struct i2c_client *client);\r
+ int (*sensor_af_const_cb)(struct i2c_client *client);\r
+ int (*sensor_af_zoneupdate_cb)(struct i2c_client *client, int *zone_tm_pos);\r
+ int (*sensor_af_close_cb)(struct i2c_client *client);\r
+ int (*sensor_af_near_cb)(struct i2c_client *client);\r
+ int (*sensor_af_far_cb)(struct i2c_client *client);\r
+ int (*sensor_af_specialpos_cb)(struct i2c_client *client,int pos); \r
+ //\r
+};\r
+//zone from hal is [-1000,-1000,1000,1000],must map to sensor's zone.\r
+struct rk_sensor_focus_zone{\r
+ int lx;\r
+ int ty;\r
+ int rx;\r
+ int dy;\r
+};\r
+struct rk_sensor_focus_op_s{\r
+ struct rk_sensor_focus_cb focus_cb;\r
+ struct workqueue_struct *sensor_wq;\r
+ struct mutex focus_lock;\r
+ unsigned int focus_state;\r
+ unsigned int focus_mode; //show the focus mode\r
+ struct rk_sensor_focus_zone focus_zone;\r
+ enum rk_sensor_focus_wq_cmd focus_delay;\r
+};\r
+\r
+\r
+typedef struct rk_sensor_priv_s\r
+{\r
+ int mirror;\r
+ bool snap2preview;\r
+ bool video2preview;\r
+ struct rk_sensor_sequence* winseqe_cur_addr;\r
+ struct rk_sensor_datafmt* datafmt;\r
+ int num_datafmt;\r
+ struct rk_sensor_datafmt curfmt;\r
+ unsigned int funmodule_state;\r
+ //\r
+ struct rk_sensor_sequence* sensor_series;\r
+ int num_series; \r
+\r
+ struct rk_sensor_reg* sensor_SfRstSeqe;\r
+ struct rk_sensor_reg* sensor_CkIdSeqe;\r
+ \r
+ struct rk_sensor_seq_info max_res;//maybe interploted\r
+ struct rk_sensor_seq_info max_real_res;\r
+ struct rk_sensor_seq_info min_res;\r
+ unsigned long bus_parameter;\r
+ unsigned int *chip_id;\r
+ unsigned int chip_id_num;\r
+ int chip_ident;\r
+ unsigned int gReg_mask;\r
+ unsigned int gVal_mask;\r
+ unsigned int gI2c_speed;\r
+\r
+ bool stream;\r
+ \r
+} rk_sensor_info_priv_t;\r
+\r
+struct sensor_v4l2ctrl_info_s {\r
+ struct v4l2_queryctrl *qctrl;\r
+ int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl);\r
+ struct rk_sensor_reg **sensor_Seqe;\r
+ int cur_value;\r
+ int num_ctrls;\r
+};\r
+\r
+struct sensor_v4l2ctrl_usr_s {\r
+ struct v4l2_queryctrl qctrl;\r
+ int (*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl);\r
+ struct rk_sensor_reg **sensor_Seqe;\r
+};\r
+\r
+struct sensor_ops_cb_s{\r
+ int (*sensor_softreset_cb)(struct i2c_client *client,struct rk_sensor_reg *series);\r
+ int (*sensor_check_id_cb)(struct i2c_client *client,struct rk_sensor_reg *series);\r
+ int (*sensor_activate_cb)(struct i2c_client *client);\r
+ int (*sensor_deactivate_cb)(struct i2c_client *client);\r
+ int (*sensor_mirror_cb)(struct i2c_client *client, int mirror);\r
+ int (*sensor_flip_cb)(struct i2c_client *client, int flip);\r
+ int (*sensor_face_detect_cb)(struct i2c_client *client, int on);\r
+\r
+ int (*sensor_s_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture);\r
+ int (*sensor_s_fmt_cb_bh)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture);\r
+ int (*sensor_try_fmt_cb_th)(struct i2c_client *client,struct v4l2_mbus_framefmt *mf);\r
+};\r
+//flash off in fixed time to prevent from too hot , zyc\r
+struct rk_flash_timer{\r
+ struct soc_camera_device *icd;\r
+ struct hrtimer timer;\r
+};\r
+\r
+struct generic_sensor\r
+{\r
+ char dev_name[32];\r
+ struct v4l2_subdev subdev;\r
+ struct i2c_client *client;\r
+ rk_sensor_info_priv_t info_priv;\r
+ int model; /* V4L2_IDENT_OV* codes from v4l2-chip-ident.h */\r
+ \r
+ bool is_need_tasklock;\r
+ atomic_t tasklock_cnt;\r
+ struct soc_camera_ops *sensor_ops; \r
+ struct v4l2_queryctrl* sensor_controls; \r
+ struct sensor_v4l2ctrl_info_s *ctrls;\r
+ struct rk_flash_timer flash_off_timer;\r
+ struct sensor_ops_cb_s sensor_cb;\r
+ struct rk_sensor_focus_op_s sensor_focus;\r
+ struct rk29camera_platform_data *sensor_io_request;\r
+ struct rk29camera_gpio_res *sensor_gpio_res;\r
+ \r
+};\r
+\r
+extern int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series);\r
+extern int generic_sensor_check_id(struct i2c_client *client, struct rk_sensor_reg *series);\r
+extern int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val);\r
+extern int sensor_write_reg2val2(struct i2c_client *client, u16 reg,u16 val);\r
+extern int sensor_write_reg1val1(struct i2c_client *client, u8 reg,u8 val);\r
+extern int sensor_write_reg1val2(struct i2c_client *client, u8 reg,u16 val);\r
+extern int sensor_read_reg1val1(struct i2c_client *client, u8 reg,u8* val);\r
+extern int sensor_read_reg2val1(struct i2c_client *client, u16 reg,u8* val);\r
+extern int sensor_read_reg1val2(struct i2c_client *client, u8 reg,u16* val);\r
+extern int sensor_read_reg2val2(struct i2c_client *client, u16 reg,u16* val);\r
+extern int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_reg);\r
+extern int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_reg);\r
+extern int generic_sensor_write_array(struct i2c_client *client, struct rk_sensor_reg *regarray);\r
+extern int generic_sensor_get_max_min_res(struct rk_sensor_sequence* res_array,int num,struct rk_sensor_seq_info * max_real_res\r
+ ,struct rk_sensor_seq_info * max_res,struct rk_sensor_seq_info *min_res);\r
+extern int generic_sensor_init(struct v4l2_subdev *sd, u32 val);\r
+extern int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);\r
+extern int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);\r
+extern int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on);\r
+extern unsigned long generic_sensor_query_bus_param(struct soc_camera_device *icd);\r
+extern int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);\r
+extern int generic_sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);\r
+extern int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+extern int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);\r
+extern int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl);\r
+extern int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl);\r
+extern int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
+extern int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);\r
+extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);\r
+extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);\r
+extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,enum v4l2_mbus_pixelcode *code);\r
+extern int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);\r
+extern int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id);\r
+extern int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl);\r
+extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait);\r
+extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable);\r
+extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size);\r
+\r
+static inline int sensor_get_full_width_height(int full_resolution, unsigned short *w, unsigned short *h)\r
+{\r
+ switch (full_resolution) \r
+ {\r
+ case 0x30000:\r
+ {\r
+ *w = 640;\r
+ *h = 480;\r
+ break;\r
+ } \r
+\r
+ case 0x100000:\r
+ {\r
+ *w = 1024;\r
+ *h = 768;\r
+ break;\r
+ } \r
+ \r
+ case 0x130000:\r
+ {\r
+ *w = 1280;\r
+ *h = 1024;\r
+ break;\r
+ }\r
+\r
+ case 0x200000:\r
+ {\r
+ *w = 1600;\r
+ *h = 1200;\r
+ break;\r
+ }\r
+\r
+ case 0x300000:\r
+ {\r
+ *w = 2048;\r
+ *h = 1536;\r
+ break;\r
+ }\r
+\r
+ case 0x500000:\r
+ {\r
+ *w = 2592;\r
+ *h = 1944;\r
+ break;\r
+ }\r
+\r
+ case 0x800000:\r
+ {\r
+ *w = 3264;\r
+ *h = 2448;\r
+ break;\r
+ }\r
+ \r
+ default:\r
+ return -1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+static inline int sensor_video_probe(struct soc_camera_device *icd,\r
+ struct i2c_client *client)\r
+{\r
+ int ret;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ /* We must have a parent by now. And it cannot be a wrong one.\r
+ * So this entire test is completely redundant. */\r
+ if (!icd->dev.parent ||\r
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {\r
+ ret = -ENODEV;\r
+ goto sensor_video_probe_end;\r
+ }\r
+\r
+ generic_sensor_softreset(client,sensor->info_priv.sensor_SfRstSeqe);\r
+ ret = generic_sensor_check_id(client,sensor->info_priv.sensor_CkIdSeqe);\r
+\r
+sensor_video_probe_end: \r
+ return ret;\r
+}\r
+\r
+static inline int sensor_regarray_check(struct rk_sensor_reg *data, int reg_num)\r
+{\r
+ struct rk_sensor_reg *data_ptr;\r
+\r
+ data_ptr = data+reg_num-1;\r
+ if (data_ptr->reg == SEQCMD_END) {\r
+ return 0;\r
+ } else { \r
+ printk(KERN_ERR "%s(%d): data[%d].reg = 0x%x\n",__FUNCTION__,__LINE__,reg_num-1,data_ptr->reg);\r
+ return -1;\r
+ }\r
+ \r
+}\r
+\r
+static inline void sensor_v4l2ctrl_info_init (struct sensor_v4l2ctrl_info_s *ptr,\r
+ unsigned int id,\r
+ enum v4l2_ctrl_type type,\r
+ char *name,\r
+ int min,\r
+ int max,\r
+ int step,\r
+ int default_val,\r
+ int(*cb)(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl),\r
+ struct rk_sensor_reg ** sensor_seqe\r
+ )\r
+{\r
+ ptr->qctrl->id = id;\r
+ ptr->qctrl->type = type;\r
+ strcat(ptr->qctrl->name,name);\r
+ ptr->qctrl->minimum = min;\r
+ ptr->qctrl->maximum = max;\r
+ ptr->qctrl->step = step;\r
+ ptr->qctrl->default_value = default_val;\r
+ ptr->cur_value = default_val;\r
+ ptr->cb = cb;\r
+ ptr->sensor_Seqe = sensor_seqe;\r
+ return;\r
+}\r
+\r
+static inline struct sensor_v4l2ctrl_info_s* sensor_find_ctrl(\r
+ struct sensor_v4l2ctrl_info_s *ops, int id)\r
+{\r
+ int i;\r
+\r
+ for (i = 0; i < ops[i].num_ctrls; i++)\r
+ if (ops[i].qctrl->id == id)\r
+ return &ops[i];\r
+\r
+ return NULL;\r
+}\r
+\r
+static inline void v4l2_querymenu_init (struct v4l2_querymenu *ptr,\r
+ unsigned int id,\r
+ unsigned int index,\r
+ char *name,\r
+ unsigned int reserved)\r
+{\r
+ ptr->id = id;\r
+ ptr->index = index;\r
+ strcat(ptr->name,name);\r
+ ptr->reserved = reserved;\r
+\r
+ return;\r
+}\r
+\r
+static inline int sensor_v4l2ctrl_replace_cb(struct generic_sensor *sensor, int id, void *cb)\r
+{\r
+ int i,num;\r
+ struct sensor_v4l2ctrl_info_s* ctrls;\r
+\r
+ ctrls = sensor->ctrls;\r
+ num = ctrls->num_ctrls;\r
+ for (i=0; i<num; i++,ctrls++) {\r
+ if (ctrls->qctrl->id == id) {\r
+ ctrls->cb = cb;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (i>=num) {\r
+ printk(KERN_ERR "%s(%d): v4l2_control id(0x%x) isn't exist\n",__FUNCTION__,__LINE__,id);\r
+ } else {\r
+ return 0;\r
+ }\r
+}\r
+\r
+static inline int sensor_v4l2ctrl_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); \r
+ int value = ext_ctrl->value;\r
+ int index;\r
+\r
+ if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
+ printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
+ ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
+ return -EINVAL;\r
+ }\r
+\r
+ index = value - ctrl_info->qctrl->minimum;\r
+ if (ctrl_info->sensor_Seqe && (ctrl_info->sensor_Seqe[index] != NULL)) {\r
+ if (generic_sensor_write_array(client, ctrl_info->sensor_Seqe[index]) != 0) {\r
+ printk(KERN_ERR "%s(%d): sensor write array sensor_Seqe failed\n",__FUNCTION__,__LINE__);\r
+ return -EINVAL;\r
+ }\r
+\r
+ ctrl_info->cur_value = value;\r
+ return 0;\r
+ } else {\r
+ printk(KERN_ERR "%s(%d): ctrl_info(id=0x%x)'s sensor_Seqe is invalidate\n",__FUNCTION__,__LINE__,ctrl_info->qctrl->id);\r
+ return -EINVAL;\r
+ }\r
+}\r
+static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); \r
+ int value = ext_ctrl->value;\r
+ int ret = 0;\r
+ struct generic_sensor* sensor = to_generic_sensor(client);\r
+ \r
+ if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
+ printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
+ ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
+ return -EINVAL;\r
+ }\r
+ \r
+ if(sensor->sensor_focus.focus_state == FocusState_Inval){\r
+ printk(KERN_ERR "%s(%d): focus have not been init success yet\n",__FUNCTION__,__LINE__);\r
+ //set focus delay\r
+ \r
+ switch (ext_ctrl->id)\r
+ {\r
+ case V4L2_CID_FOCUS_ABSOLUTE:\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_special_pos;\r
+ break;\r
+ case V4L2_CID_FOCUS_RELATIVE:\r
+ if (ext_ctrl->value == ctrl_info->qctrl->minimum)\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_near_pos;\r
+ else\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_far_pos;\r
+ break;\r
+ \r
+ case V4L2_CID_FOCUS_AUTO:\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_single;\r
+ break;\r
+ case V4L2_CID_FOCUS_CONTINUOUS:\r
+ sensor->sensor_focus.focus_delay = WqCmd_af_continues;\r
+ break;\r
+ default:\r
+ printk(KERN_ERR "%s(%d):not support this focus mode",__FUNCTION__,__LINE__ );\r
+ }\r
+ return -EINVAL;\r
+ }\r
+ switch (ext_ctrl->id)\r
+ {\r
+ case V4L2_CID_FOCUS_ABSOLUTE:\r
+ {\r
+ if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){\r
+ //need do something?\r
+\r
+ }\r
+ if (ctrl_info->cur_value != value) {\r
+ if (ext_ctrl->value == ctrl_info->qctrl->minimum)\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_near_pos, value, true);\r
+ else if(ext_ctrl->value == ctrl_info->qctrl->maximum)\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_far_pos, value, true);\r
+ else\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true);\r
+ if(ret == 0){\r
+ ctrl_info->cur_value = value;\r
+ } else {\r
+ ret = -EINVAL;\r
+ printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value);\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case V4L2_CID_FOCUS_RELATIVE:\r
+ {\r
+ if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){\r
+ //need do something?\r
+ \r
+ }\r
+ if (ctrl_info->cur_value != value) {\r
+ if (ext_ctrl->value == ctrl_info->qctrl->minimum)\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_near_pos, value, true);\r
+ else if(ext_ctrl->value == ctrl_info->qctrl->maximum)\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_far_pos, value, true);\r
+ if(ret == 0){\r
+ ctrl_info->cur_value = value;\r
+ } else {\r
+ ret = -EINVAL;\r
+ printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value);\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ case V4L2_CID_FOCUS_AUTO:\r
+ {\r
+ mutex_lock(&sensor->sensor_focus.focus_lock);\r
+ //get focuszone\r
+ sensor->sensor_focus.focus_zone.lx = ext_ctrl->rect[0];\r
+ sensor->sensor_focus.focus_zone.ty = ext_ctrl->rect[1];\r
+ sensor->sensor_focus.focus_zone.rx = ext_ctrl->rect[2];\r
+ sensor->sensor_focus.focus_zone.dy = ext_ctrl->rect[3];\r
+ mutex_unlock(&sensor->sensor_focus.focus_lock);\r
+ \r
+ if(sensor->sensor_focus.focus_mode ==V4L2_CID_FOCUS_CONTINUOUS){\r
+ //need do something?\r
+ //generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true);\r
+ }\r
+ if((value==1) || (sensor->sensor_focus.focus_mode==V4L2_CID_FOCUS_AUTO)){\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_update_zone, value, true);\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_single, value, true);\r
+ sensor->sensor_focus.focus_mode = V4L2_CID_FOCUS_AUTO;\r
+ }else if(value == 0){\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true);\r
+ }\r
+ if(ret != 0){\r
+ ret = -EINVAL;\r
+ printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value);\r
+ }\r
+ break;\r
+ \r
+ }\r
+ case V4L2_CID_FOCUS_CONTINUOUS:\r
+ {\r
+ if((value==1) && (sensor->sensor_focus.focus_mode!=V4L2_CID_FOCUS_CONTINUOUS)){\r
+ //have to close focus firstly?\r
+ //generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true);\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_continues, value, true);\r
+\r
+ sensor->sensor_focus.focus_mode = V4L2_CID_FOCUS_CONTINUOUS;\r
+ }else if(value ==0){\r
+ ret = generic_sensor_af_workqueue_set(icd, WqCmd_af_close, value, true);\r
+ }\r
+ if(ret != 0){\r
+ ret = -EINVAL;\r
+ printk(KERN_ERR"\n %s valure = %d is invalidate.. \n",__FUNCTION__,value);\r
+ }\r
+ break;\r
+ }\r
+ \r
+ }\r
+ return ret;\r
+\r
+}\r
+static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); \r
+ int value = ext_ctrl->value;\r
+ int ret = 0;\r
+ struct generic_sensor* sensor = to_generic_sensor(client);\r
+ if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
+ printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
+ ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
+ return -EINVAL;\r
+ }\r
+ if(ctrl_info->cur_value != value){\r
+ if(sensor->sensor_cb.sensor_face_detect_cb)\r
+ ret = (sensor->sensor_cb.sensor_face_detect_cb)(client,value);\r
+ if(ret ==0)\r
+ ctrl_info->cur_value = value;\r
+ }\r
+ return ret;\r
+}\r
+#define new_user_v4l2ctrl(ctl_id,ctl_type,ctl_name,ctl_min,ctl_max,ctl_step,default_val,callback,seqe)\\r
+{\\r
+ .qctrl = {\\r
+ .id = ctl_id,\\r
+ .type = ctl_type,\\r
+ .name = ctl_name,\\r
+ .minimum = ctl_min,\\r
+ .maximum = ctl_max,\\r
+ .step = ctl_step,\\r
+ .default_value = default_val,\\r
+ },\\r
+ .cb = callback,\\r
+ .sensor_Seqe = seqe,\\r
+}\r
+ \r
+\r
+#define new_usr_v4l2menu(menu_id,menu_idx,menu_name,menu_rev)\\r
+ {\\r
+ .id = menu_id,\\r
+ .index = menu_idx,\\r
+ .name = menu_name,\\r
+ .reserved = menu_rev,\\r
+ }\r
+\r
+#define sensor_init_parameters_default_code() static void sensor_init_parameters(struct specific_sensor* spsensor,struct soc_camera_device *icd)\\r
+{ \\r
+ int num,i; \\r
+ struct rk_sensor_sequence *sensor_series; \\r
+ struct v4l2_queryctrl *controls, *control; \\r
+ struct sensor_v4l2ctrl_info_s *ctrls; \\r
+ struct v4l2_querymenu *menus,*menu; \\r
+ struct soc_camera_link *icl = to_soc_camera_link(icd); \\r
+ struct rk29camera_platform_data *pdata = icl->priv_usr; \\r
+ struct rkcamera_platform_data *sensor_device=NULL,*new_camera; \\r
+ struct rk_sensor_reg *reg_data; \\r
+ int config_flash = 0;\\r
+ int sensor_config;\\r
+ \\r
+ sensor_config = SensorConfiguration;\\r
+ new_camera = pdata->register_dev_new; \\r
+ while (strstr(new_camera->dev_name,"end")==NULL) { \\r
+ if (strcmp(dev_name(icd->pdev), new_camera->dev_name) == 0) { \\r
+ sensor_device = new_camera; \\r
+ break; \\r
+ } \\r
+ new_camera++; \\r
+ } \\r
+ \\r
+ if(sensor_device && sensor_device->flash)\\r
+ config_flash = 1;\\r
+ spsensor->common_sensor.info_priv.gReg_mask = 0x00; \\r
+ spsensor->common_sensor.info_priv.gVal_mask = 0x00; \\r
+ for (i=0; i<SENSOR_REGISTER_LEN; i++) \\r
+ spsensor->common_sensor.info_priv.gReg_mask |= (0xff<<(i*8)); \\r
+ for (i=0; i<SENSOR_VALUE_LEN; i++) \\r
+ spsensor->common_sensor.info_priv.gVal_mask |= (0xff<<(i*8)); \\r
+ spsensor->common_sensor.info_priv.gI2c_speed = 100000; \\r
+ if (sensor_regarray_check(sensor_softreset_data, sizeof(sensor_softreset_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ spsensor->common_sensor.info_priv.sensor_SfRstSeqe = sensor_softreset_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_softreset_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_softreset_data"); \\r
+ BUG(); \\r
+ } \\r
+ if (sensor_regarray_check(sensor_check_id_data, sizeof(sensor_check_id_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ spsensor->common_sensor.info_priv.sensor_CkIdSeqe= sensor_check_id_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_check_id_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_check_id_data"); \\r
+ BUG(); \\r
+ } \\r
+ spsensor->common_sensor.sensor_cb.sensor_activate_cb = sensor_activate_cb; \\r
+ spsensor->common_sensor.sensor_cb.sensor_deactivate_cb = sensor_deactivate_cb; \\r
+ spsensor->common_sensor.sensor_cb.sensor_mirror_cb = sensor_mirror_cb; \\r
+ spsensor->common_sensor.sensor_cb.sensor_flip_cb = sensor_flip_cb; \\r
+ spsensor->common_sensor.sensor_cb.sensor_s_fmt_cb_th = sensor_s_fmt_cb_th; \\r
+ spsensor->common_sensor.sensor_cb.sensor_s_fmt_cb_bh = sensor_s_fmt_cb_bh; \\r
+ spsensor->common_sensor.sensor_cb.sensor_try_fmt_cb_th = sensor_try_fmt_cb_th;\\r
+ spsensor->common_sensor.sensor_cb.sensor_softreset_cb = sensor_softrest_usr_cb;\\r
+ spsensor->common_sensor.sensor_cb.sensor_check_id_cb = sensor_check_id_usr_cb;\\r
+ if (CFG_FunChk(sensor_config,CFG_FACE_DETECT)) \\r
+ spsensor->common_sensor.sensor_cb.sensor_face_detect_cb = sensor_face_detect_usr_cb; \\r
+ else \\r
+ spsensor->common_sensor.sensor_cb.sensor_face_detect_cb = NULL; \\r
+ \\r
+ num = 4; \\r
+ if (sensor_720p[0].reg != SEQCMD_END) { \\r
+ num++; \\r
+ } \\r
+ if (sensor_1080p[0].reg != SEQCMD_END) { \\r
+ num++; \\r
+ } \\r
+ \\r
+ if (sensor_device && (sensor_device->resolution > CONS(SENSOR_NAME,_FULL_RESOLUTION))) \\r
+ num++; \\r
+ \\r
+ sensor_series = (struct rk_sensor_sequence*)kzalloc(sizeof(struct rk_sensor_sequence)*num,GFP_KERNEL); \\r
+ if (sensor_series == NULL) { \\r
+ SENSOR_TR("malloc sensor_series failed! n"); \\r
+ BUG(); \\r
+ } else { \\r
+ spsensor->common_sensor.info_priv.sensor_series = sensor_series; \\r
+ spsensor->common_sensor.info_priv.num_series = num; \\r
+ \\r
+ sensor_series->gSeq_info.w = SENSOR_PREVIEW_W; \\r
+ sensor_series->gSeq_info.h = SENSOR_PREVIEW_H; \\r
+ sensor_series->gSeq_info.fps = SENSOR_PREVIEW_FPS; \\r
+ sensor_series->property = SEQUENCE_INIT; \\r
+ if (sensor_regarray_check(sensor_init_data, sizeof(sensor_init_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_init_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_init_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_int_data"); \\r
+ BUG(); \\r
+ } \\r
+ \\r
+ sensor_series++; \\r
+ sensor_series->gSeq_info.w = SENSOR_PREVIEW_W; \\r
+ sensor_series->gSeq_info.h = SENSOR_PREVIEW_H; \\r
+ sensor_series->gSeq_info.fps = SENSOR_PREVIEW_FPS; \\r
+ sensor_series->property = SEQUENCE_PREVIEW; \\r
+ if (sensor_regarray_check(sensor_preview_data, sizeof(sensor_preview_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_preview_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_preview_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_preview_data"); \\r
+ BUG(); \\r
+ } \\r
+ \\r
+ sensor_series++; \\r
+ if (sensor_get_full_width_height(CONS(SENSOR_NAME,_FULL_RESOLUTION),&sensor_series->gSeq_info.w,&sensor_series->gSeq_info.h) == 0) { \\r
+ sensor_series->gSeq_info.fps = SENSOR_FULLRES_L_FPS; \\r
+ sensor_series->property = SEQUENCE_CAPTURE; \\r
+ if (sensor_regarray_check(sensor_fullres_lowfps_data, sizeof(sensor_fullres_lowfps_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_fullres_lowfps_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_fullres_lowfps_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_fullres_lowfps_data"); \\r
+ BUG(); \\r
+ } \\r
+ } else { \\r
+ SENSOR_TR("generic_sensor_get_width_height failed!"); \\r
+ BUG(); \\r
+ } \\r
+ \\r
+ sensor_series++; \\r
+ sensor_series->gSeq_info.w = (sensor_series-1)->gSeq_info.w; \\r
+ sensor_series->gSeq_info.h = (sensor_series-1)->gSeq_info.h; \\r
+ sensor_series->gSeq_info.fps = SENSOR_FULLRES_H_FPS; \\r
+ sensor_series->property = SEQUENCE_PREVIEW; \\r
+ if (sensor_regarray_check(sensor_fullres_highfps_data, sizeof(sensor_fullres_highfps_data)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_fullres_highfps_data; \\r
+ } else { \\r
+ SENSOR_TR("sensor_fullres_highfps_data haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_fullres_highfps_data"); \\r
+ BUG(); \\r
+ } \\r
+ \\r
+ if (sensor_device && (sensor_device->resolution > CONS(SENSOR_NAME,_FULL_RESOLUTION))) { \\r
+ sensor_series++; \\r
+ if (sensor_get_full_width_height(sensor_device->resolution,&sensor_series->gSeq_info.w,&sensor_series->gSeq_info.h) == 0) { \\r
+ sensor_series->gSeq_info.fps = SENSOR_FULLRES_L_FPS; \\r
+ sensor_series->property = SEQUENCE_CAPTURE; \\r
+ reg_data = kzalloc(sizeof(struct rk_sensor_reg)*2,GFP_KERNEL); \\r
+ if (reg_data == NULL) { \\r
+ SENSOR_TR("kzalloc interpolate reg_data failed"); \\r
+ } else { \\r
+ sensor_series->data = reg_data; \\r
+ reg_data->reg = SEQCMD_INTERPOLATION; \\r
+ reg_data++; \\r
+ reg_data->reg = SEQCMD_END; \\r
+ } \\r
+ } else { \\r
+ SENSOR_TR("generic_sensor_get_width_height failed!"); \\r
+ BUG(); \\r
+ } \\r
+ } \\r
+ \\r
+ if (sensor_720p[0].reg != SEQCMD_END) { \\r
+ sensor_series++; \\r
+ sensor_series->gSeq_info.w = 1280; \\r
+ sensor_series->gSeq_info.h = 720; \\r
+ sensor_series->gSeq_info.fps = SENSOR_720P_FPS; \\r
+ sensor_series->property = SEQUENCE_PREVIEW; \\r
+ if (sensor_regarray_check(sensor_720p, sizeof(sensor_720p)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_720p; \\r
+ } else { \\r
+ SENSOR_TR("sensor_720p haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_720p"); \\r
+ BUG(); \\r
+ } \\r
+ } \\r
+ \\r
+ if (sensor_1080p[0].reg != SEQCMD_END) { \\r
+ sensor_series++; \\r
+ sensor_series->gSeq_info.w = 1920; \\r
+ sensor_series->gSeq_info.h = 1080; \\r
+ sensor_series->gSeq_info.fps = SENSOR_1080P_FPS; \\r
+ sensor_series->property = SEQUENCE_PREVIEW; \\r
+ if (sensor_regarray_check(sensor_1080p, sizeof(sensor_1080p)/sizeof(struct rk_sensor_reg))==0) { \\r
+ sensor_series->data = sensor_1080p; \\r
+ } else { \\r
+ SENSOR_TR("sensor_1080p haven't SensorEnd flag! Please fill SensorEnd in the last of sensor_1080p"); \\r
+ BUG(); \\r
+ } \\r
+ } \\r
+ } \\r
+ \\r
+ if (CFG_FunChk(sensor_config,CFG_Focus)) { \\r
+ spsensor->common_sensor.sensor_focus.sensor_wq = create_workqueue(SENSOR_NAME_STRING(_af_workqueue)); \\r
+ if (spsensor->common_sensor.sensor_focus.sensor_wq == NULL) {\\r
+ SENSOR_TR("%s create fail, so auto focus is disable!", SENSOR_NAME_STRING(_af_workqueue));\\r
+ CFG_FunDis(sensor_config,CFG_Focus);\\r
+ CFG_FunDis(sensor_config,CFG_FocusContinues);\\r
+ CFG_FunDis(sensor_config,CFG_FocusZone);\\r
+ CFG_FunDis(sensor_config,CFG_FocusRelative);\\r
+ CFG_FunDis(sensor_config,CFG_FocusAbsolute);\\r
+ }\\r
+ } else {\\r
+ spsensor->common_sensor.sensor_focus.sensor_wq = NULL;\\r
+ CFG_FunDis(sensor_config,CFG_FocusContinues);\\r
+ CFG_FunDis(sensor_config,CFG_FocusZone);\\r
+ CFG_FunDis(sensor_config,CFG_FocusRelative);\\r
+ CFG_FunDis(sensor_config,CFG_FocusAbsolute);\\r
+ }\\r
+\\r
+ spsensor->common_sensor.info_priv.bus_parameter = SENSOR_BUS_PARAM; \\r
+ spsensor->common_sensor.info_priv.chip_ident = SENSOR_V4L2_IDENT; \\r
+ spsensor->common_sensor.info_priv.chip_id = SensorChipID;\\r
+ spsensor->common_sensor.info_priv.chip_id_num = sizeof(SensorChipID)/sizeof(SensorChipID[0]);\\r
+\\r
+ generic_sensor_get_max_min_res(spsensor->common_sensor.info_priv.sensor_series , \\r
+ spsensor->common_sensor.info_priv.num_series, \\r
+ &(spsensor->common_sensor.info_priv.max_real_res), \\r
+ &(spsensor->common_sensor.info_priv.max_res), \\r
+ &(spsensor->common_sensor.info_priv.min_res)); \\r
+ \\r
+ num = 0;\\r
+ for (i=0; i<32; i++)\\r
+ if (SensorConfiguration & (1<<i))\\r
+ num++;\\r
+ num += sizeof(sensor_controls)/sizeof(struct sensor_v4l2ctrl_usr_s); \\r
+ controls = (struct v4l2_queryctrl*)kzalloc(sizeof(struct v4l2_queryctrl)*num,GFP_KERNEL); \\r
+ if (controls == NULL) { \\r
+ SENSOR_TR("kzalloc struct v4l2_queryctrl(%d) failed",num); \\r
+ BUG(); \\r
+ } \\r
+ spsensor->common_sensor.sensor_controls = controls; \\r
+ sensor_ops.controls = controls; \\r
+ sensor_ops.num_controls = num; \\r
+ \\r
+ ctrls = (struct sensor_v4l2ctrl_info_s*)kzalloc(sizeof(struct sensor_v4l2ctrl_info_s)*num,GFP_KERNEL); \\r
+ if (ctrls == NULL) { \\r
+ SENSOR_TR("kzalloc struct sensor_v4l2ctrl_info_s(%d) failed",num); \\r
+ BUG(); \\r
+ } \\r
+ spsensor->common_sensor.ctrls = ctrls; \\r
+ for (i=0; i<num; i++) { \\r
+ ctrls->qctrl = controls; \\r
+ ctrls->num_ctrls = num; \\r
+ ctrls++; \\r
+ controls++; \\r
+ } \\r
+ controls = spsensor->common_sensor.sensor_controls; \\r
+ ctrls = spsensor->common_sensor.ctrls; \\r
+ \\r
+ num = 0; \\r
+ 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); \\r
+ num += sizeof(sensor_menus)/sizeof(struct v4l2_querymenu); \\r
+ menus = (struct v4l2_querymenu*)kzalloc(sizeof(struct v4l2_querymenu)*num,GFP_KERNEL); \\r
+ if (menus == NULL) { \\r
+ SENSOR_TR("kzalloc struct v4l2_querymenu(%d) failed",num); \\r
+ BUG(); \\r
+ } \\r
+ sensor_ops.menus = menus; \\r
+ sensor_ops.num_menus = num; \\r
+ \\r
+ sensor_ops.suspend = sensor_suspend; \\r
+ sensor_ops.resume = sensor_resume; \\r
+ sensor_ops.set_bus_param = generic_sensor_set_bus_param; \\r
+ sensor_ops.query_bus_param = generic_sensor_query_bus_param; \\r
+ \\r
+ if (CFG_FunChk(sensor_config,CFG_WhiteBalance)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU, \\r
+ "White Balance Control",0,4,1,0,sensor_v4l2ctrl_default_cb,sensor_WhiteBalanceSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ \\r
+ v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,0,"auto",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0); \\r
+ menus++; \\r
+ } \\r
+ \\r
+ if (CFG_FunChk(sensor_config,CFG_Brightness)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Brightness Control",-3,2,1,0,sensor_v4l2ctrl_default_cb,sensor_BrightnessSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Effect)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU, \\r
+ "Effect Control",0,5,1,0,sensor_v4l2ctrl_default_cb,sensor_EffectSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,0,"none",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,1,"mono",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,2,"negative",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,3,"sepia",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,4,"posterize",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_EFFECT,5,"aqua",0); \\r
+ menus++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Exposure)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Exposure Control",0,6,1,0,sensor_v4l2ctrl_default_cb,sensor_ExposureSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Saturation)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_SATURATION,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Saturation Control",0,2,1,0,sensor_v4l2ctrl_default_cb,sensor_SaturationSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Contrast)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Contrast Control",-3,3,1,0,sensor_v4l2ctrl_default_cb,sensor_ContrastSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Mirror)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_HFLIP,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "Mirror Control",0,1,1,0,sensor_v4l2ctrl_mirror_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Flip)) { \\r
+ ctrls->qctrl = controls; \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_VFLIP,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "Flip Control",0,1,1,0,sensor_v4l2ctrl_flip_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Scene)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU, \\r
+ "Scene Control",0,1,1,0,sensor_v4l2ctrl_default_cb,sensor_SceneSeqe); \\r
+ controls++; \\r
+ ctrls++; \\r
+ \\r
+ v4l2_querymenu_init(menus,V4L2_CID_SCENE,0,"auto",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_SCENE,1,"night",0); \\r
+ menus++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_Focus)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_AUTO,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "Focus Control",0,2,1,0,sensor_focus_default_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ \\r
+ if (CFG_FunChk(sensor_config,CFG_FocusRelative)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_RELATIVE,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Focus Control",-1,1,1,0,sensor_focus_default_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ \\r
+ if (CFG_FunChk(sensor_config,CFG_FocusAbsolute)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_ABSOLUTE,V4L2_CTRL_TYPE_INTEGER, \\r
+ "Focus Control",0,255,1,125,sensor_focus_default_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_FocusZone)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUSZONE,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "Focus Control",0,1,1,0,NULL,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_FocusContinues)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FOCUS_CONTINUOUS,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "Focus Control",0,1,1,0,sensor_focus_default_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (CFG_FunChk(sensor_config,CFG_FACE_DETECT)) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FACEDETECT,V4L2_CTRL_TYPE_BOOLEAN, \\r
+ "FaceDEt Control",0,1,1,0,sensor_face_detect_default_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ } \\r
+ if (config_flash) { \\r
+ sensor_v4l2ctrl_info_init(ctrls,V4L2_CID_FLASH,V4L2_CTRL_TYPE_MENU, \\r
+ "Flash Control",0,3,1,0,sensor_v4l2ctrl_flash_cb,NULL); \\r
+ controls++; \\r
+ ctrls++; \\r
+ \\r
+ v4l2_querymenu_init(menus,V4L2_CID_FLASH,0,"off",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_FLASH,1,"auto",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_FLASH,2,"on",0); \\r
+ menus++; \\r
+ v4l2_querymenu_init(menus,V4L2_CID_FLASH,3,"torch",0); \\r
+ menus++; \\r
+ } \\r
+ \\r
+ for (i=0; i<(sizeof(sensor_controls)/sizeof(struct sensor_v4l2ctrl_usr_s)); i++) { \\r
+ \\r
+ control = spsensor->common_sensor.sensor_controls; \\r
+ while (control < controls) \\r
+ { \\r
+ if (control->id == sensor_controls[i].qctrl.id) { \\r
+ control->id = 0xffffffff; \\r
+ } \\r
+ control++; \\r
+ } \\r
+ \\r
+ memcpy(controls, &sensor_controls[i].qctrl,sizeof(struct v4l2_queryctrl)); \\r
+ controls++; \\r
+ \\r
+ ctrls->sensor_Seqe = sensor_controls[i].sensor_Seqe; \\r
+ ctrls->cur_value = sensor_controls[i].qctrl.default_value; \\r
+ ctrls->cb = sensor_controls[i].cb; \\r
+ ctrls++; \\r
+ } \\r
+ \\r
+ for (i=0; i<(sizeof(sensor_menus)/sizeof(struct v4l2_querymenu)); i++) { \\r
+ num = sensor_ops.num_menus - sizeof(sensor_menus)/sizeof(struct v4l2_querymenu); \\r
+ menu = sensor_ops.menus; \\r
+ while (num--) { \\r
+ if (menu->id == sensor_menus[i].id) { \\r
+ menu->id = 0xffffffff; \\r
+ } \\r
+ menu++; \\r
+ } \\r
+ \\r
+ memcpy(menus, &sensor_menus[i],sizeof(struct v4l2_querymenu)); \\r
+ menus++; \\r
+ } \\r
+ \\r
+ spsensor->common_sensor.info_priv.datafmt = sensor_colour_fmts; \\r
+ spsensor->common_sensor.info_priv.num_datafmt = ARRAY_SIZE(sensor_colour_fmts); \\r
+ spsensor->common_sensor.sensor_ops = &sensor_ops; \\r
+ icd->ops = &sensor_ops; \\r
+ spsensor->common_sensor.info_priv.curfmt= sensor_colour_fmts[0]; \\r
+ \\r
+ if (config_flash) { \\r
+ hrtimer_init(&(spsensor->common_sensor.flash_off_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); \\r
+ spsensor->common_sensor.flash_off_timer.icd = icd; \\r
+ } \\r
+ if(CFG_FunChk(sensor_config,CFG_Focus)) { \\r
+ mutex_init(&spsensor->common_sensor.sensor_focus.focus_lock); \\r
+ spsensor->common_sensor.sensor_focus.focus_mode = WqCmd_af_invalid; \\r
+ spsensor->common_sensor.sensor_focus.focus_state = FocusState_Inval;\\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_focus_init_cb = sensor_focus_init_usr_cb; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_single_cb = sensor_focus_af_single_usr_cb; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_near_cb = sensor_focus_af_near_usr_cb; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_far_cb = sensor_focus_af_far_usr_cb; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_specialpos_cb = sensor_focus_af_specialpos_usr_cb; \\r
+ if(CFG_FunChk(sensor_config,CFG_FocusContinues))\\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_const_cb = sensor_focus_af_const_usr_cb; \\r
+ if(CFG_FunChk(sensor_config,CFG_FocusZone)) \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_zoneupdate_cb = sensor_focus_af_zoneupdate_usr_cb; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_close_cb = sensor_focus_af_close_usr_cb; \\r
+ }else{ \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_focus_init_cb = NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_single_cb = NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_near_cb = NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_far_cb =NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_specialpos_cb =NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_const_cb =NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_zoneupdate_cb =NULL; \\r
+ spsensor->common_sensor.sensor_focus.focus_cb.sensor_af_close_cb =NULL; \\r
+ } \\r
+ \\r
+ memcpy(spsensor->common_sensor.dev_name,dev_name(icd->pdev), sizeof(spsensor->common_sensor.dev_name)-1); \\r
+ sensor_init_parameters_user(spsensor,icd); \\r
+}\r
+\r
+\r
+#define sensor_v4l2_struct_initialization() static struct v4l2_subdev_core_ops sensor_subdev_core_ops = {\\r
+ .init = generic_sensor_init,\\r
+ .g_ctrl = generic_sensor_g_control,\\r
+ .s_ctrl = generic_sensor_s_control,\\r
+ .g_ext_ctrls = generic_sensor_g_ext_controls,\\r
+ .s_ext_ctrls = generic_sensor_s_ext_controls,\\r
+ .g_chip_ident = generic_sensor_g_chip_ident,\\r
+ .ioctl = generic_sensor_ioctl,\\r
+};\\r
+\\r
+static struct v4l2_subdev_video_ops sensor_subdev_video_ops = {\\r
+ .s_mbus_fmt = generic_sensor_s_fmt,\\r
+ .g_mbus_fmt = generic_sensor_g_fmt,\\r
+ .try_mbus_fmt = generic_sensor_try_fmt,\\r
+ .enum_mbus_fmt = generic_sensor_enum_fmt,\\r
+ .enum_frameintervals = generic_sensor_enum_frameintervals,\\r
+ .s_stream = generic_sensor_s_stream,\\r
+};\\r
+static struct v4l2_subdev_ops sensor_subdev_ops = {\\r
+ .core = &sensor_subdev_core_ops,\\r
+ .video = &sensor_subdev_video_ops,\\r
+};\\r
+\\r
+static const struct i2c_device_id sensor_id[] = {\\r
+ {SENSOR_NAME_STRING(), 0 },\\r
+ {"\0",0}\\r
+};\\r
+\\r
+MODULE_DEVICE_TABLE(i2c, sensor_id);\r
+\r
+\r
+#define sensor_probe_default_code() static int sensor_probe(struct i2c_client *client,\\r
+ const struct i2c_device_id *did)\\r
+{\\r
+ struct specific_sensor *spsensor=NULL;\\r
+ struct soc_camera_device *icd = client->dev.platform_data;\\r
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);\\r
+ struct soc_camera_link *icl;\\r
+ int ret=0;\\r
+\\r
+ if (!icd) {\\r
+ dev_err(&client->dev, "%s: missing soc-camera data!\n",SENSOR_NAME_STRING());\\r
+ ret = -EINVAL;\\r
+ goto sensor_probe_end;\\r
+ }\\r
+\\r
+ icl = to_soc_camera_link(icd);\\r
+ if (!icl) {\\r
+ SENSOR_TR("driver needs platform data! But it is failed\n");\\r
+ ret = -EINVAL;\\r
+ goto sensor_probe_end;\\r
+ }\\r
+\\r
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {\\r
+ SENSOR_TR("I2C-Adapter doesn't support I2C_FUNC_I2C\n");\\r
+ ret = -EIO;\\r
+ goto sensor_probe_end;\\r
+ }\\r
+\\r
+ spsensor = kzalloc(sizeof(struct specific_sensor), GFP_KERNEL);\\r
+ if (!spsensor) {\\r
+ ret = -ENOMEM;\\r
+ SENSOR_TR("kzalloc failed\n");\\r
+ goto sensor_probe_end;\\r
+ }\\r
+\\r
+ v4l2_i2c_subdev_init(&spsensor->common_sensor.subdev, client, &sensor_subdev_ops);\\r
+ sensor_init_parameters(spsensor,icd);\\r
+\\r
+ ret = sensor_video_probe(icd, client);\\r
+\\r
+sensor_probe_end:\\r
+ if (ret != 0) {\\r
+ if (icd->ops) {\\r
+ if (icd->ops->controls) {\\r
+ kfree(icd->ops->controls);\\r
+ icd->ops->controls = NULL;\\r
+ }\\r
+ if (icd->ops->menus) {\\r
+ kfree(icd->ops->menus);\\r
+ icd->ops->menus = NULL;\\r
+ }\\r
+ icd->ops = NULL;\\r
+ }\\r
+ i2c_set_clientdata(client, NULL);\\r
+ client->driver = NULL;\\r
+ if (spsensor) {\\r
+ kfree(spsensor);\\r
+ }\\r
+ spsensor = NULL;\\r
+ }\\r
+ return ret;\\r
+}\r
+\r
+#define sensor_remove_default_code() static int sensor_remove(struct i2c_client *client)\\r
+{\\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\\r
+ struct soc_camera_device *icd = client->dev.platform_data;\\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\\r
+ int sensor_config;\\r
+\\r
+ sensor_config = SensorConfiguration;\\r
+ if(CFG_FunChk(sensor_config,CFG_Focus)){ \\r
+ if (sensor->sensor_focus.sensor_wq) {\\r
+ destroy_workqueue(sensor->sensor_focus.sensor_wq);\\r
+ sensor->sensor_focus.sensor_wq = NULL;\\r
+ }\\r
+ }\\r
+ if (icd->ops) {\\r
+ if (icd->ops->controls) {\\r
+ kfree(icd->ops->controls);\\r
+ icd->ops->controls = NULL;\\r
+ }\\r
+ if (icd->ops->menus) {\\r
+ kfree(icd->ops->menus);\\r
+ icd->ops->menus = NULL;\\r
+ }\\r
+ icd->ops = NULL;\\r
+ }\\r
+ i2c_set_clientdata(client, NULL);\\r
+ client->driver = NULL;\\r
+ if (spsensor) {\\r
+ kfree(spsensor);\\r
+ }\\r
+ spsensor = NULL;\\r
+ return 0;\\r
+}\r
+\r
+\r
+#define sensor_driver_default_module_code() static struct i2c_driver sensor_i2c_driver = {\\r
+ .driver = {\\r
+ .name = SENSOR_NAME_STRING(),\\r
+ },\\r
+ .probe = sensor_probe,\\r
+ .remove = sensor_remove,\\r
+ .id_table = sensor_id,\\r
+};\\r
+\\r
+static int __init sensor_mod_init(void)\\r
+{\\r
+ return i2c_add_driver(&sensor_i2c_driver);\\r
+}\\r
+\\r
+static void __exit sensor_mod_exit(void)\\r
+{\\r
+ i2c_del_driver(&sensor_i2c_driver);\\r
+}\\r
+\\r
+device_initcall_sync(sensor_mod_init);\\r
+module_exit(sensor_mod_exit);\\r
+\\r
+MODULE_DESCRIPTION(SENSOR_NAME_STRING(sensor driver));\\r
+MODULE_AUTHOR("<ddl@rock-chips.com,zyc@rock-chips.com>");\\r
+MODULE_LICENSE("GPL");\r
+#endif\r
+#include "generic_sensor.h"\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-
-static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
-
-#define dprintk(level, fmt, arg...) do { \
- if (debug >= level) \
- printk(KERN_WARNING fmt , ## arg); } while (0)
-
-#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char value;
- int ret,pid = 0;
- struct sensor *sensor = to_sensor(client);
-
- /* We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant. */
- if (!icd->dev.parent ||
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
- return -ENODEV;
-
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
- ret = -ENODEV;
- goto sensor_video_probe_err;
- }
-
- /* soft reset */
- /* ret = sensor_write(client, 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_GT2005\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_GT2005\r
+#define SENSOR_ID 0x5138\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 640\r
+#define SENSOR_PREVIEW_H 480\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+ u16 shutter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x0101 , 0x00},\r
+ {0x0103 , 0x00}, \r
+ {0x0105 , 0x00},\r
+ {0x0106 , 0xF0},\r
+ {0x0107 , 0x00},\r
+ {0x0108 , 0x1C},\r
+ {0x0109 , 0x01},\r
+ {0x010A , 0x00},\r
+ {0x010B , 0x00},\r
+ {0x010C , 0x00},\r
+ {0x010D , 0x08},\r
+ {0x010E , 0x00},\r
+ {0x010F , 0x08},\r
+ {0x0110 , 0x06},\r
+ {0x0111 , 0x40},\r
+ {0x0112 , 0x04},\r
+ {0x0113 , 0xB0},\r
+ {0x0114 , 0x00},\r
+ {0x0115 , 0x00},\r
+ //{0x0116 , 0x02},\r
+ //{0x0117 , 0x00},\r
+ // {0x0118 , 0x67},\r
+ //{0x0119 , 0x02},\r
+ //{0x011A , 0x04},\r
+ //{0x011B , 0x01},\r
+ {0x011C , 0x00},//0x01 2011 11 04\r
+ {0x011D , 0x02},\r
+ {0x011E , 0x00},\r
+ {0x011F , 0x00},\r
+ {0x0120 , 0x1C},\r
+ {0x0121 , 0x00},\r
+ {0x0122 , 0x04},\r
+ {0x0123 , 0x00},\r
+ {0x0124 , 0x00},\r
+ {0x0125 , 0x00},\r
+ {0x0126 , 0x00},\r
+ {0x0127 , 0x00},\r
+ {0x0128 , 0x00},\r
+ {0x0200 , 0x00},\r
+ {0x0201 , 0x08}, //0x00\r
+ {0x0202 , 0x40},\r
+ {0x0203 , 0x00},\r
+ {0x0204 , 0x78},\r
+ {0x0205 , 0x1F},\r
+ {0x0206 , 0x0B},\r
+ {0x0207 , 0x20},\r
+ {0x0208 , 0x00},\r
+ {0x0209 , 0x2A},\r
+ {0x020A , 0x01},\r
+ {0x020B , 0x48},\r
+ {0x020C , 0x64},\r
+ {0x020D , 0xC8},\r
+ {0x020E , 0xBC},\r
+ {0x020F , 0x08},\r
+ {0x0210 , 0xD6},\r
+ {0x0211 , 0x00},\r
+ {0x0212 , 0x20},\r
+ {0x0213 , 0x81},\r
+ {0x0214 , 0x15},\r
+ {0x0215 , 0x00},\r
+ {0x0216 , 0x00},\r
+ {0x0217 , 0x00},\r
+ {0x0218 , 0x46},\r
+ {0x0219 , 0x30},\r
+ {0x021A , 0x03},\r
+ {0x021B , 0x28},\r
+ {0x021C , 0x02},\r
+ {0x021D , 0x60},\r
+ {0x021E , 0x00},\r
+ {0x021F , 0x00},\r
+ {0x0220 , 0x10},\r
+ {0x0221 , 0x10},\r
+ {0x0222 , 0x10},\r
+ {0x0223 , 0x10},\r
+ {0x0224 , 0x1F},\r
+ {0x0225 , 0x1E},\r
+ {0x0226 , 0x18},\r
+ {0x0227 , 0x1D},\r
+ {0x0228 , 0x1F},\r
+ {0x0229 , 0x1F},\r
+ {0x022A , 0x01},\r
+ {0x022B , 0x04},\r
+ {0x022C , 0x05},\r
+ {0x022D , 0x05},\r
+ {0x022E , 0x04},\r
+ {0x022F , 0x03},\r
+ {0x0230 , 0x02},\r
+ {0x0231 , 0x1F},\r
+ {0x0232 , 0x1A},\r
+ {0x0233 , 0x19},\r
+ {0x0234 , 0x19},\r
+ {0x0235 , 0x1B},\r
+ {0x0236 , 0x1F},\r
+ {0x0237 , 0x04},\r
+ {0x0238 , 0xEE},\r
+ {0x0239 , 0xFF},\r
+ {0x023A , 0x00},\r
+ {0x023B , 0x00},\r
+ {0x023C , 0x00},\r
+ {0x023D , 0x00},\r
+ {0x023E , 0x00},\r
+ {0x023F , 0x00},\r
+ {0x0240 , 0x00},\r
+ {0x0241 , 0x00},\r
+ {0x0242 , 0x00},\r
+ {0x0243 , 0x21},\r
+ {0x0244 , 0x42},\r
+ {0x0245 , 0x53},\r
+ {0x0246 , 0x54},\r
+ {0x0247 , 0x54},\r
+ {0x0248 , 0x54},\r
+ {0x0249 , 0x33},\r
+ {0x024A , 0x11},\r
+ {0x024B , 0x00},\r
+ {0x024C , 0x00},\r
+ {0x024D , 0xFF},\r
+ {0x024E , 0xEE},\r
+ {0x024F , 0xDD},\r
+ {0x0250 , 0x00},\r
+ {0x0251 , 0x00},\r
+ {0x0252 , 0x00},\r
+ {0x0253 , 0x00},\r
+ {0x0254 , 0x00},\r
+ {0x0255 , 0x00},\r
+ {0x0256 , 0x00},\r
+ {0x0257 , 0x00},\r
+ {0x0258 , 0x00},\r
+ {0x0259 , 0x00},\r
+ {0x025A , 0x00},\r
+ {0x025B , 0x00},\r
+ {0x025C , 0x00},\r
+ {0x025D , 0x00},\r
+ {0x025E , 0x00},\r
+ {0x025F , 0x00},\r
+ {0x0260 , 0x00},\r
+ {0x0261 , 0x00},\r
+ {0x0262 , 0x00},\r
+ {0x0263 , 0x00},\r
+ {0x0264 , 0x00},\r
+ {0x0265 , 0x00},\r
+ {0x0266 , 0x00},\r
+ {0x0267 , 0x00},\r
+ {0x0268 , 0x8F},\r
+ {0x0269 , 0xA3},\r
+ {0x026A , 0xB4},\r
+ {0x026B , 0x90},\r
+ {0x026C , 0x00},\r
+ {0x026D , 0xD0},\r
+ {0x026E , 0x60},\r
+ {0x026F , 0xA0},\r
+ {0x0270 , 0x40},\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x80},\r
+ {0x0302 , 0x22},\r
+ {0x0303 , 0x06},\r
+ {0x0304 , 0x03},\r
+ {0x0305 , 0x83},\r
+ {0x0306 , 0x00},\r
+ {0x0307 , 0x22},\r
+ {0x0308 , 0x00},\r
+ {0x0309 , 0x55},\r
+ {0x030A , 0x55},\r
+ {0x030B , 0x55},\r
+ {0x030C , 0x54},\r
+ {0x030D , 0x1F},\r
+ {0x030E , 0x13},\r
+ {0x030F , 0x10},\r
+ {0x0310 , 0x04},\r
+ {0x0311 , 0xFF},\r
+ {0x0312 , 0x98},\r
+ {0x0313 , 0x28},\r
+ {0x0314 , 0x66},\r
+ {0x0315 , 0x16},\r
+ {0x0316 , 0x26},\r
+ {0x0317 , 0x02},\r
+ {0x0318 , 0x08},\r
+ {0x0319 , 0x0C},\r
+ {0x031A , 0x81},\r
+ {0x031B , 0x00},\r
+ {0x031C , 0x3D},\r
+ {0x031D , 0x00},\r
+ {0x031E , 0xF9},\r
+ {0x031F , 0x00},\r
+ {0x0320 , 0x24},\r
+ {0x0321 , 0x14},\r
+ {0x0322 , 0x1A},\r
+ {0x0323 , 0x24},\r
+ {0x0324 , 0x08},\r
+ {0x0325 , 0xF0},\r
+ {0x0326 , 0x30}, \r
+ {0x0327 , 0x17},\r
+ {0x0328 , 0x11},\r
+ {0x0329 , 0x22},\r
+ {0x032A , 0x2F},\r
+ {0x032B , 0x21},\r
+ {0x032C , 0xDA},\r
+ {0x032D , 0x10},\r
+ {0x032E , 0xEA},\r
+ {0x032F , 0x18},\r
+ {0x0330 , 0x29},\r
+ {0x0331 , 0x25},\r
+ {0x0332 , 0x12},\r
+ {0x0333 , 0x0F},\r
+ {0x0334 , 0xE0},\r
+ {0x0335 , 0x13},\r
+ {0x0336 , 0xFF},\r
+ {0x0337 , 0x20},\r
+ {0x0338 , 0x46},\r
+ {0x0339 , 0x04},\r
+ {0x033A , 0x04},\r
+ {0x033B , 0xFF},\r
+ {0x033C , 0x01},\r
+ {0x033D , 0x00},\r
+ {0x033E , 0x03},\r
+ {0x033F , 0x28},\r
+ {0x0340 , 0x02},\r
+ {0x0341 , 0x60},\r
+ {0x0342 , 0xAC},\r
+ {0x0343 , 0x97},\r
+ {0x0344 , 0x7F},\r
+ {0x0400 , 0xE8},\r
+ {0x0401 , 0x40},\r
+ {0x0402 , 0x00},\r
+ {0x0403 , 0x00},\r
+ {0x0404 , 0xF8},\r
+ {0x0405 , 0x03},\r
+ {0x0406 , 0x03},\r
+ {0x0407 , 0x85},\r
+ {0x0408 , 0x44},\r
+ {0x0409 , 0x1F},\r
+ {0x040A , 0x40},\r
+ {0x040B , 0x33},\r
+ {0x040C , 0xA0},\r
+ {0x040D , 0x00},\r
+ {0x040E , 0x00},\r
+ {0x040F , 0x00},\r
+ {0x0410 , 0x0D},\r
+ {0x0411 , 0x0D},\r
+ {0x0412 , 0x0C},\r
+ {0x0413 , 0x04},\r
+ {0x0414 , 0x00},\r
+ {0x0415 , 0x00},\r
+ {0x0416 , 0x07},\r
+ {0x0417 , 0x09},\r
+ {0x0418 , 0x16},\r
+ {0x0419 , 0x14},\r
+ {0x041A , 0x11},\r
+ {0x041B , 0x14},\r
+ {0x041C , 0x07},\r
+ {0x041D , 0x07},\r
+ {0x041E , 0x06},\r
+ {0x041F , 0x02},\r
+ {0x0420 , 0x42},\r
+ {0x0421 , 0x42},\r
+ {0x0422 , 0x47},\r
+ {0x0423 , 0x39},\r
+ {0x0424 , 0x3E},\r
+ {0x0425 , 0x4D},\r
+ {0x0426 , 0x46},\r
+ {0x0427 , 0x3A},\r
+ {0x0428 , 0x21},\r
+ {0x0429 , 0x21},\r
+ {0x042A , 0x26},\r
+ {0x042B , 0x1C},\r
+ {0x042C , 0x25},\r
+ {0x042D , 0x25},\r
+ {0x042E , 0x28},\r
+ {0x042F , 0x20},\r
+ {0x0430 , 0x3E},\r
+ {0x0431 , 0x3E},\r
+ {0x0432 , 0x33},\r
+ {0x0433 , 0x2E},\r
+ {0x0434 , 0x54},\r
+ {0x0435 , 0x53},\r
+ {0x0436 , 0x3C},\r
+ {0x0437 , 0x51},\r
+ {0x0438 , 0x2B},\r
+ {0x0439 , 0x2B},\r
+ {0x043A , 0x38},\r
+ {0x043B , 0x22},\r
+ {0x043C , 0x3B},\r
+ {0x043D , 0x3B},\r
+ {0x043E , 0x31},\r
+ {0x043F , 0x37},\r
+ {0x0440 , 0x00},\r
+ {0x0441 , 0x4B},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x31},\r
+ {0x0445 , 0x00},\r
+ {0x0446 , 0x00},\r
+ {0x0447 , 0x00},\r
+ {0x0448 , 0x00},\r
+ {0x0449 , 0x00},\r
+ {0x044A , 0x00},\r
+ {0x044D , 0xE0},\r
+ {0x044E , 0x05},\r
+ {0x044F , 0x07},\r
+ {0x0450 , 0x00},\r
+ {0x0451 , 0x00},\r
+ {0x0452 , 0x00},\r
+ {0x0453 , 0x00},\r
+ {0x0454 , 0x00},\r
+ {0x0455 , 0x00},\r
+ {0x0456 , 0x00},\r
+ {0x0457 , 0x00},\r
+ {0x0458 , 0x00},\r
+ {0x0459 , 0x00},\r
+ {0x045A , 0x00},\r
+ {0x045B , 0x00},\r
+ {0x045C , 0x00},\r
+ {0x045D , 0x00},\r
+ {0x045E , 0x00},\r
+ {0x045F , 0x00},\r
+ {0x0460 , 0x80},\r
+ {0x0461 , 0x10},\r
+ {0x0462 , 0x10},\r
+ {0x0463 , 0x10},\r
+ {0x0464 , 0x08},\r
+ {0x0465 , 0x08},\r
+ {0x0466 , 0x11},\r
+ {0x0467 , 0x09},\r
+ {0x0468 , 0x23},\r
+ {0x0469 , 0x2A},\r
+ {0x046A , 0x2A},\r
+ {0x046B , 0x47},\r
+ {0x046C , 0x52},\r
+ {0x046D , 0x42},\r
+ {0x046E , 0x36},\r
+ {0x046F , 0x46},\r
+ {0x0470 , 0x3A},\r
+ {0x0471 , 0x32},\r
+ {0x0472 , 0x32},\r
+ {0x0473 , 0x38},\r
+ {0x0474 , 0x3D},\r
+ {0x0475 , 0x2F},\r
+ {0x0476 , 0x29},\r
+ {0x0477 , 0x48},\r
+ {0x0600 , 0x00},\r
+ {0x0601 , 0x24},\r
+ {0x0602 , 0x45},\r
+ {0x0603 , 0x0E},\r
+ {0x0604 , 0x14},\r
+ {0x0605 , 0x2F},\r
+ {0x0606 , 0x01},\r
+ {0x0607 , 0x0E},\r
+ {0x0608 , 0x0E},\r
+ {0x0609 , 0x37},\r
+ {0x060A , 0x18},\r
+ {0x060B , 0xA0},\r
+ {0x060C , 0x20},\r
+ {0x060D , 0x07},\r
+ {0x060E , 0x47},\r
+ {0x060F , 0x90},\r
+ {0x0610 , 0x06},\r
+ {0x0611 , 0x0C},\r
+ {0x0612 , 0x28},\r
+ {0x0613 , 0x13},\r
+ {0x0614 , 0x0B},\r
+ {0x0615 , 0x10},\r
+ {0x0616 , 0x14},\r
+ {0x0617 , 0x19},\r
+ {0x0618 , 0x52},\r
+ {0x0619 , 0xA0},\r
+ {0x061A , 0x11},\r
+ {0x061B , 0x33},\r
+ {0x061C , 0x56},\r
+ {0x061D , 0x20},\r
+ {0x061E , 0x28},\r
+ {0x061F , 0x2B},\r
+ {0x0620 , 0x22},\r
+ {0x0621 , 0x11},\r
+ {0x0622 , 0x75},\r
+ {0x0623 , 0x49},\r
+ {0x0624 , 0x6E},\r
+ {0x0625 , 0x80},\r
+ {0x0626 , 0x02},\r
+ {0x0627 , 0x0C},\r
+ {0x0628 , 0x51},\r
+ {0x0629 , 0x25},\r
+ {0x062A , 0x01},\r
+ {0x062B , 0x3D},\r
+ {0x062C , 0x04},\r
+ {0x062D , 0x01},\r
+ {0x062E , 0x0C},\r
+ {0x062F , 0x2C},\r
+ {0x0630 , 0x0D},\r
+ {0x0631 , 0x14},\r
+ {0x0632 , 0x12},\r
+ {0x0633 , 0x34},\r
+ {0x0634 , 0x00},\r
+ {0x0635 , 0x00},\r
+ {0x0636 , 0x00},\r
+ {0x0637 , 0xB1},\r
+ {0x0638 , 0x22},\r
+ {0x0639 , 0x32},\r
+ {0x063A , 0x0E},\r
+ {0x063B , 0x18},\r
+ {0x063C , 0x88},\r
+ {0x0640 , 0xB2},\r
+ {0x0641 , 0xC0},\r
+ {0x0642 , 0x01},\r
+ {0x0643 , 0x26},\r
+ {0x0644 , 0x13},\r
+ {0x0645 , 0x88},\r
+ {0x0646 , 0x64},\r
+ {0x0647 , 0x00},\r
+ {0x0681 , 0x1B},\r
+ {0x0682 , 0xA0},\r
+ {0x0683 , 0x28},\r
+ {0x0684 , 0x00},\r
+ {0x0685 , 0xB0},\r
+ {0x0686 , 0x6F},\r
+ {0x0687 , 0x33},\r
+ {0x0688 , 0x1F},\r
+ {0x0689 , 0x44},\r
+ {0x068A , 0xA8},\r
+ {0x068B , 0x44},\r
+ {0x068C , 0x08},\r
+ {0x068D , 0x08},\r
+ {0x068E , 0x00},\r
+ {0x068F , 0x00},\r
+ {0x0690 , 0x01},\r
+ {0x0691 , 0x00},\r
+ {0x0692 , 0x01},\r
+ {0x0693 , 0x00},\r
+ {0x0694 , 0x00},\r
+ {0x0695 , 0x00},\r
+ {0x0696 , 0x00},\r
+ {0x0697 , 0x00},\r
+ {0x0698 , 0x2A},\r
+ {0x0699 , 0x80},\r
+ {0x069A , 0x1F},\r
+ {0x069B , 0x00},\r
+ {0x069C , 0x02},\r
+ {0x069D , 0xF5},\r
+ {0x069E , 0x03},\r
+ {0x069F , 0x6D},\r
+ {0x06A0 , 0x0C},\r
+ {0x06A1 , 0xB8},\r
+ {0x06A2 , 0x0D},\r
+ {0x06A3 , 0x74},\r
+ {0x06A4 , 0x00},\r
+ {0x06A5 , 0x2F},\r
+ {0x06A6 , 0x00},\r
+ {0x06A7 , 0x2F},\r
+ {0x0F00 , 0x00},\r
+ {0x0F01 , 0x00},\r
+ {0x0100 , 0x01},\r
+ {0x0102 , 0x02},\r
+ {0x0104 , 0x03},\r
+ \r
+ \r
+ ///////////////////////////\r
+ {0x020B , 0x48},\r
+ {0x020C , 0x64},\r
+ {0x040A , 0x40},\r
+ {0x040B , 0x33},\r
+ {0x0109 , 0x00},\r
+ {0x010A , 0x04},\r
+ {0x010B , 0x03},\r
+ \r
+ {0x0110, 0x03},\r
+ {0x0111, 0x20},\r
+ {0x0112, 0x02},\r
+ {0x0113, 0x58},\r
+ \r
+ {0x0116 , 0x02},\r
+ {0x0118 , 0x56},//56 0x40\r
+ {0x0119 , 0x02},\r
+ {0x011a , 0x04},\r
+ {0x011B , 0x01},\r
+ {0x0313 , 0x36},//36\r
+ {0x0314 , 0xff},//ff\r
+ {0x0315 , 0x16},\r
+ /*\r
+ {0x020B , 0x48},\r
+ {0x020C , 0x64},\r
+ {0x040A , 0x40},\r
+ {0x040B , 0x33},\r
+ {0x0109 , 0x00},\r
+ {0x010A , 0x04},\r
+ {0x010B , 0x03},\r
+ {0x010c , 0x00},\r
+ {0x010d , 0xa8},\r
+ {0x010e , 0x00},\r
+ {0x010f , 0x60},\r
+ {0x010a , 0x04},\r
+ \r
+ {0x0110 , 0x02},\r
+ {0x0111 , 0x80},\r
+ {0x0112 , 0x01},\r
+ {0x0113 , 0xe0},\r
+ \r
+ {0x0116 , 0x02},\r
+ {0x0118 , 0x40},\r
+ {0x0119 , 0x01},\r
+ {0x011a , 0x04},\r
+ {0x011B , 0x00},\r
+ {0x0313 , 0x35},\r
+ {0x0314 , 0x36},\r
+ {0x0315 , 0x16}, */\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ //Binning&Resoultion\r
+ {0x0109 , 0x01},//Fixed the number of lines by VCOUNT setting\r
+ {0x010A , 0x00},\r
+ {0x010B , 0x00},\r
+ \r
+ {0x0110 , 0x06},\r
+ {0x0111 , 0x40},\r
+ {0x0112 , 0x04},\r
+ {0x0113 , 0xB0}, // 1600*1200 SETTING\r
+ SensorEnd\r
+\r
+};\r
+\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x0109 , 0x00},\r
+ {0x010A , 0x04},\r
+ {0x010B , 0x03},\r
+ \r
+ {0x0110 , 0x02},\r
+ {0x0111 , 0x80},\r
+ {0x0112 , 0x01},\r
+ {0x0113 , 0xe0},\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x0000,0),\r
+ SensorRegVal(0x0001,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x031a , 0x81},\r
+ {0x0320 , 0x24},\r
+ {0x0321 , 0x14},\r
+ {0x0322 , 0x1a},\r
+ {0x0323 , 0x24},\r
+ {0x0441 , 0x4B},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x31},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x0320 , 0x02},\r
+ {0x0321 , 0x02},\r
+ {0x0322 , 0x02},\r
+ {0x0323 , 0x02},\r
+ {0x0441 , 0x80},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x0D}, \r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x0320 , 0x02},\r
+ {0x0321 , 0x02},\r
+ {0x0322 , 0x02},\r
+ {0x0323 , 0x02},\r
+ {0x0441 , 0x60},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x14},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x0320 , 0x02},\r
+ {0x0321 , 0x02},\r
+ {0x0322 , 0x02},\r
+ {0x0323 , 0x02},\r
+ {0x0441 , 0x50},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x30},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x0320 , 0x02},\r
+ {0x0321 , 0x02},\r
+ {0x0322 , 0x02},\r
+ {0x0323 , 0x02},\r
+ {0x0441 , 0x0B},\r
+ {0x0442 , 0x00},\r
+ {0x0443 , 0x00},\r
+ {0x0444 , 0x5E},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x70},\r
+ \r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x80},\r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x90},\r
+ \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0xa0},\r
+ \r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0xb0},\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x0115,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x0115,0x06},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x0115,0x0a},\r
+ {0x026e,0x60},\r
+ {0x026f,0xa0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x0115,0x09}, //bit[6] negative\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x0115,0x0a},\r
+ {0x026e,0xfb},\r
+ {0x026f,0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x0115,0x0a},\r
+ {0x026e,0x20},\r
+ {0x026f,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ //-3\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x50},\r
+ {0x0201 , 0xa0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ //-2\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x60},\r
+ {0x0201 , 0xb0},\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ //-0.3EV\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x70},\r
+ {0x0201 , 0xd0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ //default\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x80},\r
+ {0x0201 , 0x10},//0c\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ // 1\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0x90},\r
+ {0x0201 , 0x30},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ // 2\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0xa0},\r
+ {0x0201 , 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ // 3\r
+ {0x0300 , 0x81},\r
+ {0x0301 , 0xb0},\r
+ {0x0201 , 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ {0x0202 , 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ {0x0202 , 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ {0x0202 , 0x60},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ //Contrast -3\r
+ {0x0200 , 0xe8},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ //Contrast -2\r
+ {0x0200 , 0xf0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ // Contrast -1\r
+ {0x0200 , 0xf8},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ //Contrast 0\r
+ {0x0200 , 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ //Contrast +1\r
+ {0x0200 , 0x10},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ //Contrast +2\r
+ {0x0200 , 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ //Contrast +3\r
+ {0x0200 , 0x30},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0x0312, 0x08},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ //30fps ~ 5fps night mode for 60/50Hz light environment, 24Mhz clock input,36Mzh pclk\r
+ \r
+ \r
+ {0x0312, 0x98},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x0101, &val);\r
+ if (err == 0) {\r
+ if((val & 0x1) == 0){\r
+ err = sensor_write(client, 0x0101, (val |0x1));\r
+ }\r
+ else \r
+ err = sensor_write(client, 0x0101, (val & 0xfe));\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x0101, &val);\r
+ if (err == 0) {\r
+ if((val & 0x2) == 0){\r
+ err = sensor_write(client, 0x0101, (val |0x2));\r
+ }\r
+ else {\r
+ err = sensor_write(client, 0x0101, (val & 0xfc));\r
+ }\r
+ }\r
+ } else {\r
+ //do nothing\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+
+static int debug;
+module_param(debug, int, S_IRUGO|S_IWUSR);
+
+#define dprintk(level, fmt, arg...) do { \
+ if (debug >= level) \
+ printk(KERN_WARNING fmt , ## arg); } while (0)
+
+#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
+#define SENSOR_DG(format, ...) dprintk(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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char value;
+ int ret,pid = 0;
+ struct sensor *sensor = to_sensor(client);
+
+ /* We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant. */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+ return -ENODEV;
+
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+ ret = -ENODEV;
+ goto sensor_video_probe_err;
+ }
+
+ /* soft reset */
+ /* ret = sensor_write(client, 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+/*
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug > level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_HM2057\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_HM2057\r
+#define SENSOR_ID 0x2056\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect);\r
+static unsigned int SensorChipID[] = {SENSOR_ID,0x2057};\r
+\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+#define SENSOR_PLL_ENABLE 1\r
+//ͬÑùµÄÖ¡ÂÊ bypass PLLµÄÆØ¹âʱ¼äÊÇEnalble PLLµÄ2±¶\r
+//Enable PLL: 0x0025=0x00 \r
+//bypass PLL: 0x0025=0x80\r
+\r
+\r
+#define SENSOR_FAST_MODE 1\r
+//¿ìËÙģʽ£¬Ö¡ÂÊÔ½¿ì£¬Ôëµã»áÔ½´ó£¬ÇåÎú¶È»áÔ½²î\r
+//ËٶȺÍÇåÎú¶ÈÁ½Õß²»ÄܼæµÃ\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ \r
+\r
+};\r
+\r
+/*\r
+* Local define\r
+*/\r
+\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] = {\r
+{0x0022,0x00},\r
+{0x0004,0x10},\r
+{0x0006,0x00},\r
+{0x000D,0x11},\r
+{0x000E,0x11},\r
+{0x000F,0x10},//00\r
+{0x0011,0x02},\r
+{0x0012,0x1C},\r
+{0x0013,0x01},\r
+{0x0015,0x02},\r
+{0x0016,0x80},\r
+{0x0018,0x00},\r
+{0x001D,0x40},\r
+{0x0020,0x40},\r
+\r
+#if SENSOR_PLL_ENABLE\r
+ {0x0025,0x00},\r
+#else\r
+ {0x0025,0x80},\r
+#endif\r
+\r
+{0x0026,0x87},\r
+{0x0027,0x10},//0x30},\r
+{0x0040,0x20},\r
+{0x0053,0x0A},\r
+{0x0044,0x06},\r
+{0x0046,0xD8},\r
+{0x004A,0x0A},\r
+{0x004B,0x72},\r
+{0x0075,0x01},\r
+{0x002A,0x1F},\r
+{0x0070,0x5F},\r
+{0x0071,0xFF},\r
+{0x0072,0x55},\r
+{0x0073,0x50},\r
+{0x0080,0xC8},\r
+{0x0082,0xA2},\r
+{0x0083,0xF0},\r
+{0x0085,0x11},//0x12 <lpz 2012.10.24>HMAX Ô³§½¨Òé ADC POWER ÒÔǰÊÇ75%µÄÏÖÔÚÒªÉ趨³É100%\r
+{0x0086,0x02},\r
+{0x0087,0x80},\r
+{0x0088,0x6C},\r
+{0x0089,0x2E},\r
+{0x008A,0x7D},\r
+{0x008D,0x20},\r
+{0x0090,0x00},\r
+{0x0091,0x10},\r
+{0x0092,0x11},\r
+{0x0093,0x12},\r
+{0x0094,0x16},\r
+{0x0095,0x08},\r
+{0x0096,0x00},\r
+{0x0097,0x10},\r
+{0x0098,0x11},\r
+{0x0099,0x12},\r
+{0x009A,0x06},\r
+{0x009B,0x34},\r
+{0x00A0,0x00},\r
+{0x00A1,0x04},\r
+{0x011F,0xF7},\r
+{0x0120,0x36},\r
+{0x0121,0x83},\r
+{0x0122,0x7B},\r
+{0x0123,0xC2},\r
+{0x0124,0xDE},\r
+{0x0125,0xDF},\r
+{0x0126,0x70},\r
+{0x0128,0x1F},\r
+{0x0132,0x10},\r
+{0x0131,0xBD},\r
+{0x0140,0x14},\r
+{0x0141,0x0A},\r
+{0x0142,0x14},\r
+{0x0143,0x0A},\r
+{0x0144,0x04},\r
+{0x0145,0x00},\r
+{0x0146,0x20},\r
+{0x0147,0x0A},\r
+{0x0148,0x10},\r
+{0x0149,0x0C},\r
+{0x014A,0x80},\r
+{0x014B,0x80},\r
+{0x014C,0x2E},\r
+{0x014D,0x2E},\r
+{0x014E,0x05},\r
+{0x014F,0x05},\r
+{0x0150,0x0D},\r
+{0x0155,0x00},\r
+{0x0156,0x10},\r
+{0x0157,0x0A},\r
+{0x0158,0x0A},\r
+{0x0159,0x0A},\r
+{0x015A,0x05},\r
+{0x015B,0x05},\r
+{0x015C,0x05},\r
+{0x015D,0x05},\r
+{0x015E,0x08},\r
+{0x015F,0xFF},\r
+{0x0160,0x50},\r
+{0x0161,0x20},\r
+{0x0162,0x14},\r
+{0x0163,0x0A},\r
+{0x0164,0x10},\r
+{0x0165,0x0A},\r
+{0x0166,0x0A},\r
+{0x018C,0x24},\r
+{0x018D,0x04},\r
+{0x018E,0x00},\r
+{0x018F,0x11},\r
+{0x0190,0x80},\r
+{0x0191,0x47},\r
+{0x0192,0x48},\r
+{0x0193,0x64},\r
+{0x0194,0x32},\r
+{0x0195,0xc8},\r
+{0x0196,0x96},\r
+{0x0197,0x64},\r
+{0x0198,0x32},\r
+{0x0199,0x14},\r
+{0x019A,0x20},\r
+{0x019B,0x14},\r
+{0x01B0,0x55},\r
+{0x01B1,0x0C},\r
+{0x01B2,0x0A},\r
+{0x01B3,0x10},\r
+{0x01B4,0x0E},\r
+{0x01BA,0x10},\r
+{0x01BB,0x04},\r
+{0x01D8,0x40},\r
+{0x01DE,0x60},\r
+{0x01E4,0x10},\r
+{0x01E5,0x10},\r
+{0x01F2,0x0C},\r
+{0x01F3,0x14},\r
+{0x01F8,0x04},\r
+{0x01F9,0x0C},\r
+{0x01FE,0x02},\r
+{0x01FF,0x04},\r
+{0x0220,0x00},\r
+{0x0221,0xB0},\r
+{0x0222,0x00},\r
+{0x0223,0x80},\r
+{0x0224,0x8E},\r
+{0x0225,0x00},\r
+{0x0226,0x88},\r
+{0x022A,0x88},\r
+{0x022B,0x00},\r
+{0x022C,0x8C},\r
+{0x022D,0x13},\r
+{0x022E,0x0B},\r
+{0x022F,0x13},\r
+{0x0230,0x0B},\r
+{0x0233,0x13},\r
+{0x0234,0x0B},\r
+{0x0235,0x28},\r
+{0x0236,0x03},\r
+{0x0237,0x28},\r
+{0x0238,0x03},\r
+{0x023B,0x28},\r
+{0x023C,0x03},\r
+{0x023D,0x5C},\r
+{0x023E,0x02},\r
+{0x023F,0x5C},\r
+{0x0240,0x02},\r
+{0x0243,0x5C},\r
+{0x0244,0x02},\r
+{0x0251,0x0E},\r
+{0x0252,0x00},\r
+{0x0280,0x0A},\r
+{0x0282,0x14},\r
+{0x0284,0x2A},\r
+{0x0286,0x50},\r
+{0x0288,0x60},\r
+{0x028A,0x6D},\r
+{0x028C,0x79},\r
+{0x028E,0x82},\r
+{0x0290,0x8A},\r
+{0x0292,0x91},\r
+{0x0294,0x9C},\r
+{0x0296,0xA7},\r
+{0x0298,0xBA},\r
+{0x029A,0xCD},\r
+{0x029C,0xE0},\r
+{0x029E,0x2D},\r
+{0x02A0,0x06},\r
+{0x02E0,0x04},\r
+{0x02C0,0x8F},\r
+{0x02C1,0x01},\r
+{0x02C2,0x8F},\r
+{0x02C3,0x07},\r
+{0x02C4,0xE3},\r
+{0x02C5,0x07},\r
+{0x02C6,0xC1},\r
+{0x02C7,0x07},\r
+{0x02C8,0x70},\r
+{0x02C9,0x01},\r
+{0x02CA,0xD0},\r
+{0x02CB,0x07},\r
+{0x02CC,0xF7},\r
+{0x02CD,0x07},\r
+{0x02CE,0x5A},\r
+{0x02CF,0x07},\r
+{0x02D0,0xB0},\r
+{0x02D1,0x01},\r
+{0x0302,0x00},\r
+{0x0303,0x00},\r
+{0x0304,0x00},\r
+{0x02F0,0x80},\r
+{0x02F1,0x07},\r
+{0x02F2,0x8E},\r
+{0x02F3,0x00},\r
+{0x02F4,0xF2},\r
+{0x02F5,0x07},\r
+{0x02F6,0xCC},\r
+{0x02F7,0x07},\r
+{0x02F8,0x16},\r
+{0x02F9,0x00},\r
+{0x02FA,0x1E},\r
+{0x02FB,0x00},\r
+{0x02FC,0x9D},\r
+{0x02FD,0x07},\r
+{0x02FE,0xA6},\r
+{0x02FF,0x07},\r
+{0x0300,0xBD},\r
+{0x0301,0x00},\r
+{0x0305,0x00},\r
+{0x0306,0x00},\r
+{0x0307,0x00},\r
+{0x032D,0x00},\r
+{0x032E,0x01},\r
+{0x032F,0x00},\r
+{0x0330,0x01},\r
+{0x0331,0x00},\r
+{0x0332,0x01},\r
+{0x0333,0x82},\r
+{0x0334,0x00},\r
+{0x0335,0x84},\r
+{0x0336,0x00},\r
+{0x0337,0x01},\r
+{0x0338,0x00},\r
+{0x0339,0x01},\r
+{0x033A,0x00},\r
+{0x033B,0x01},\r
+{0x033E,0x04},\r
+{0x033F,0x86},\r
+{0x0340,0x30},\r
+{0x0341,0x44},\r
+{0x0342,0x4A},\r
+{0x0343,0x42},\r
+{0x0344,0x74},\r
+{0x0345,0x4F},\r
+{0x0346,0x67},\r
+{0x0347,0x5C},\r
+{0x0348,0x59},\r
+{0x0349,0x67},\r
+{0x034A,0x4D},\r
+{0x034B,0x6E},\r
+{0x034C,0x44},\r
+{0x0350,0x80},\r
+{0x0351,0x80},\r
+{0x0352,0x18},\r
+{0x0353,0x18},\r
+{0x0354,0x6E},\r
+{0x0355,0x4A},\r
+{0x0356,0x73},\r
+{0x0357,0xC0},\r
+{0x0358,0x06},\r
+{0x035A,0x06},\r
+{0x035B,0xA0},\r
+{0x035C,0x73},\r
+{0x035D,0x50},\r
+{0x035E,0xC0},\r
+{0x035F,0xA0},\r
+{0x0360,0x02},\r
+{0x0361,0x18},\r
+{0x0362,0x80},\r
+{0x0363,0x6C},\r
+{0x0364,0x00},\r
+{0x0365,0xF0},\r
+{0x0366,0x20},\r
+{0x0367,0x0C},\r
+{0x0369,0x00},\r
+{0x036A,0x10},\r
+{0x036B,0x10},\r
+{0x036E,0x20},\r
+{0x036F,0x00},\r
+{0x0370,0x10},\r
+{0x0371,0x18},\r
+{0x0372,0x0C},\r
+{0x0373,0x38},\r
+{0x0374,0x3A},\r
+{0x0375,0x13},\r
+{0x0376,0x22},\r
+{0x0380,0xFF},\r
+{0x0381,0x4c},\r
+{0x0382,0x3c},\r
+{0x038A,0x40},\r
+{0x038B,0x08},\r
+{0x038C,0xC1},\r
+{0x038E,0x44},\r
+\r
+#if SENSOR_PLL_ENABLE\r
+ //10 fps\r
+ {0x038F,0x07},\r
+ {0x0390,0x5c},\r
+#else\r
+ #if SENSOR_FAST_MODE\r
+ //10 fps\r
+ {0x038F,0x03},\r
+ {0x0390,0xae},\r
+ #else \r
+ //7.5 fps\r
+ {0x038F,0x04}, //09\r
+ {0x0390,0xE8}, //18\r
+ #endif\r
+#endif\r
+\r
+{0x0391,0x05},\r
+{0x0393,0x80},\r
+{0x0395,0x21},\r
+{0x0398,0x02},\r
+{0x0399,0x84},\r
+{0x039A,0x03},\r
+{0x039B,0x25},\r
+{0x039C,0x03},\r
+{0x039D,0xC6},\r
+{0x039E,0x05},\r
+{0x039F,0x08},\r
+{0x03A0,0x06},\r
+{0x03A1,0x4A},\r
+{0x03A2,0x07},\r
+{0x03A3,0x8C},\r
+{0x03A4,0x0A},\r
+{0x03A5,0x10},\r
+{0x03A6,0x0C},\r
+{0x03A7,0x0E},\r
+{0x03A8,0x10},\r
+{0x03A9,0x18},\r
+{0x03AA,0x20},\r
+{0x03AB,0x28},\r
+{0x03AC,0x1E},\r
+{0x03AD,0x1A},\r
+{0x03AE,0x13},\r
+{0x03AF,0x0C},\r
+{0x03B0,0x0B},\r
+{0x03B1,0x09},\r
+{0x03B3,0x10},\r
+{0x03B4,0x00},\r
+{0x03B5,0x10},\r
+{0x03B6,0x00},\r
+{0x03B7,0xEA},\r
+{0x03B8,0x00},\r
+{0x03B9,0x3A},\r
+{0x03BA,0x01},\r
+{0x03BB,0x9F},\r
+{0x03BC,0xCF},\r
+{0x03BD,0xE7},\r
+{0x03BE,0xF3},\r
+{0x03BF,0x01},\r
+{0x03D0,0xF8},\r
+{0x03E0,0x04},\r
+{0x03E1,0x01},\r
+{0x03E2,0x04},\r
+{0x03E4,0x10},\r
+{0x03E5,0x12},\r
+{0x03E6,0x00},\r
+{0x03E8,0x21},\r
+{0x03E9,0x23},\r
+{0x03EA,0x01},\r
+{0x03EC,0x21},\r
+{0x03ED,0x23},\r
+{0x03EE,0x01},\r
+{0x03F0,0x20},\r
+{0x03F1,0x22},\r
+{0x03F2,0x00},\r
+{0x0420,0x84},\r
+{0x0421,0x00},\r
+{0x0422,0x00},\r
+{0x0423,0x83},\r
+{0x0430,0x08},\r
+{0x0431,0x28},\r
+{0x0432,0x10},\r
+{0x0433,0x08},\r
+{0x0435,0x0C},\r
+{0x0450,0xFF},\r
+{0x0451,0xE8},\r
+{0x0452,0xC4},\r
+{0x0453,0x88},\r
+{0x0454,0x00},\r
+{0x0458,0x70},\r
+{0x0459,0x03},\r
+{0x045A,0x00},\r
+{0x045B,0x30},\r
+{0x045C,0x00},\r
+{0x045D,0x70},\r
+{0x0466,0x14},\r
+{0x047A,0x00},\r
+{0x047B,0x00},\r
+{0x0480,0x58},\r
+{0x0481,0x06},\r
+{0x0482,0x0C},\r
+{0x04B0,0x50},\r
+{0x04B6,0x30},\r
+{0x04B9,0x10},\r
+{0x04B3,0x10},\r
+{0x04B1,0x8E},\r
+{0x04B4,0x20},\r
+{0x0540,0x00},\r
+{0x0541,0x60},//9D\r
+{0x0542,0x00},\r
+{0x0543,0x73},//BC\r
+{0x0580,0x01},\r
+{0x0581,0x0F},\r
+{0x0582,0x04},\r
+{0x0594,0x00},\r
+{0x0595,0x04},\r
+{0x05A9,0x03},\r
+{0x05AA,0x40},\r
+{0x05AB,0x80},\r
+{0x05AC,0x0A},\r
+{0x05AD,0x10},\r
+{0x05AE,0x0C},\r
+{0x05AF,0x0C},\r
+{0x05B0,0x03},\r
+{0x05B1,0x03},\r
+{0x05B2,0x1C},\r
+{0x05B3,0x02},\r
+{0x05B4,0x00},\r
+{0x05B5,0x0C},\r
+{0x05B8,0x80},\r
+{0x05B9,0x32},\r
+{0x05BA,0x00},\r
+{0x05BB,0x80},\r
+{0x05BC,0x03},\r
+{0x05BD,0x00},\r
+{0x05BF,0x05},\r
+{0x05C0,0x10},\r
+{0x05C3,0x00},\r
+{0x05C4,0x0C},\r
+{0x05C5,0x20},\r
+{0x05C7,0x01},\r
+{0x05C8,0x14},\r
+{0x05C9,0x54},\r
+{0x05CA,0x14},\r
+{0x05CB,0xE0},\r
+{0x05CC,0x20},\r
+{0x05CD,0x00},\r
+{0x05CE,0x08},\r
+{0x05CF,0x60},\r
+{0x05D0,0x10},\r
+{0x05D1,0x05},\r
+{0x05D2,0x03},\r
+{0x05D4,0x00},\r
+{0x05D5,0x05},\r
+{0x05D6,0x05},\r
+{0x05D7,0x05},\r
+{0x05D8,0x08},\r
+{0x05DC,0x0C},\r
+{0x05D9,0x00},\r
+{0x05DB,0x00},\r
+{0x05DD,0x0F},\r
+{0x05DE,0x00},\r
+{0x05DF,0x0A},\r
+{0x05E0,0xA0},\r
+{0x05E1,0x00},\r
+{0x05E2,0xA0},\r
+{0x05E3,0x00},\r
+{0x05E4,0x05},\r
+{0x05E5,0x00},\r
+{0x05E6,0x24},\r
+{0x05E7,0x03},\r
+{0x05E8,0x07},\r
+{0x05E9,0x00},\r
+{0x05EA,0x5E},\r
+{0x05EB,0x02},\r
+{0x0660,0x04},\r
+{0x0661,0x16},\r
+{0x0662,0x04},\r
+{0x0663,0x28},\r
+{0x0664,0x04},\r
+{0x0665,0x18},\r
+{0x0666,0x04},\r
+{0x0667,0x21},\r
+{0x0668,0x04},\r
+{0x0669,0x0C},\r
+{0x066A,0x04},\r
+{0x066B,0x25},\r
+{0x066C,0x00},\r
+{0x066D,0x12},\r
+{0x066E,0x00},\r
+{0x066F,0x80},\r
+{0x0670,0x00},\r
+{0x0671,0x0A},\r
+{0x0672,0x04},\r
+{0x0673,0x1D},\r
+{0x0674,0x04},\r
+{0x0675,0x1D},\r
+{0x0676,0x00},\r
+{0x0677,0x7E},\r
+{0x0678,0x01},\r
+{0x0679,0x47},\r
+{0x067A,0x00},\r
+{0x067B,0x73},\r
+{0x067C,0x04},\r
+{0x067D,0x14},\r
+{0x067E,0x04},\r
+{0x067F,0x28},\r
+{0x0680,0x00},\r
+{0x0681,0x22},\r
+{0x0682,0x00},\r
+{0x0683,0xA5},\r
+{0x0684,0x00},\r
+{0x0685,0x1E},\r
+{0x0686,0x04},\r
+{0x0687,0x1D},\r
+{0x0688,0x04},\r
+{0x0689,0x19},\r
+{0x068A,0x04},\r
+{0x068B,0x21},\r
+{0x068C,0x04},\r
+{0x068D,0x0A},\r
+{0x068E,0x04},\r
+{0x068F,0x25},\r
+{0x0690,0x04},\r
+{0x0691,0x15},\r
+{0x0698,0x20},\r
+{0x0699,0x20},\r
+{0x069A,0x01},\r
+{0x069C,0x22},\r
+{0x069D,0x10},\r
+{0x069E,0x10},\r
+{0x069F,0x08},\r
+{0x0000,0x01},\r
+{0x0100,0x01},\r
+{0x0101,0x01},\r
+{0x0005,0x01},\r
+\r
+SensorEnd\r
+\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+{0x0380,0xFE},\r
+{0x000D,0x00},\r
+{0x000E,0x00},\r
+{0x011F,0x88},\r
+{0x0125,0xDF},\r
+{0x0126,0x70},\r
+{0x0131,0xAC},\r
+{0x0366,0x20},\r
+{0x0433,0x40},\r
+{0x0435,0x50},\r
+{0x05E4,0x0A},\r
+{0x05E5,0x00},\r
+{0x05E6,0x49},\r
+{0x05E7,0x06},\r
+{0x05E8,0x0A},\r
+{0x05E9,0x00},\r
+{0x05EA,0xB9},\r
+{0x05EB,0x04},\r
+{0x0000,0x01},\r
+{0x0100,0x01},\r
+{0x0101,0x01},\r
+{0x0005,0x01},\r
+\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+/*¼ÏñÍêºóÔÚ·µ»Øµ½Ô¤ÀÀ£¬Ô¤ÀÀʱÓÐË®²¨ÎƵÄbugÐÞ¸Ä<2012.11.22>*/\r
+ {0x0380,0xFF},\r
+{0x0006,0x00},\r
+{0x000D,0x11},\r
+{0x000E,0x11},\r
+//{0x0012,0x1C},\r
+//{0x0013,0x01},\r
+//{{0x0027,0x18},\r
+{0x002A,0x1F},\r
+//{0x0071,0xFF},\r
+{0x0082,0xA2},\r
+{0x011F,0x80},\r
+{0x0125,0xDF},\r
+{0x0126,0x70},\r
+{0x0131,0xAD},\r
+{0x0144,0x04},\r
+{0x0190,0x80},\r
+{0x0192,0x48},\r
+//{0x0541,0x9D},// 0541ºÍ0543ÊDZíʾflicker step \r
+//{0x0543,0xBC},\r
+{0x05E0,0xA0},\r
+{0x05E1,0x00},\r
+{0x05E2,0xA0},\r
+{0x05E3,0x00},\r
+{0x05E4,0x05},\r
+{0x05E5,0x00},\r
+{0x05E6,0x24},\r
+{0x05E7,0x03},\r
+{0x05E8,0x08},\r
+{0x05E9,0x00},\r
+{0x05EA,0x5F},\r
+{0x05EB,0x02},\r
+{0x0000,0x01},\r
+{0x0100,0x01},\r
+{0x0101,0x01},\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x0001,0),\r
+ SensorRegVal(0x0002,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{ \r
+ {0x0380, 0xFF}, //AWB auto\r
+ {0x0000, 0x01},\r
+ {0x0100, 0x01},\r
+ {0x0101, 0x01},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x0380, 0xFD},\r
+ {0x032D, 0x70},\r
+ {0x032E, 0x01},\r
+ {0x032F, 0x00},\r
+ {0x0330, 0x01},\r
+ {0x0331, 0x08},\r
+ {0x0332, 0x01},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ {0x0380, 0xFD},\r
+ {0x032D, 0x60},\r
+ {0x032E, 0x01},\r
+ {0x032F, 0x00},\r
+ {0x0330, 0x01},\r
+ {0x0331, 0x20},\r
+ {0x0332, 0x01},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ {0x0380, 0xFD},\r
+ {0x032D, 0x50},\r
+ {0x032E, 0x01},\r
+ {0x032F, 0x00},\r
+ {0x0330, 0x01},\r
+ {0x0331, 0x30},\r
+ {0x0332, 0x01},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ {0x0380, 0xFD},\r
+ {0x032D, 0x10},\r
+ {0x032E, 0x01},\r
+ {0x032F, 0x00},\r
+ {0x0330, 0x01},\r
+ {0x0331, 0xA0},\r
+ {0x0332, 0x01},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x0488, 0x10},\r
+ {0x0486, 0x00},\r
+ {0x0487, 0xFF},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x0488, 0x12},\r
+ {0x0486, 0x00},\r
+ {0x0487, 0xFF},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x0488, 0x11},\r
+ {0x0486, 0x40},\r
+ {0x0487, 0x90},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ {0x0488, 0x12},\r
+ {0x0486, 0x00},\r
+ {0x0487, 0xFF},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ {0x0488, 0x11},\r
+ {0x0486, 0xB0},\r
+ {0x0487, 0x80},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ {0x0488, 0x11},\r
+ {0x0486, 0x60},\r
+ {0x0487, 0x60},\r
+ {0x0101, 0xFF},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+\r
+ SENSOR_DG("%s",__FUNCTION__); \r
+\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ //struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+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)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ \r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ \r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos) {\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
+
+#include "generic_sensor.h"
/*
- * Driver for OV5642 CMOS Image Sensor from OmniVision
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/hardirq.h>
-#include <linux/miscdevice.h>
-#include <asm/io.h>
-
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#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);
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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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},
//[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(i<sum)
- {
- buf[i] = tmpval->val >> 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(i<sum)
- {
- buf[i] = tmpval->val;
- 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = 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; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
+sensor_remove_default_code();
+sensor_driver_default_module_code();
--- /dev/null
+/*
+ * Driver for OV5642 CMOS Image Sensor from OmniVision
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/hardirq.h>
+#include <linux/miscdevice.h>
+#include <asm/io.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+#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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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(i<sum)
+ {
+ buf[i] = tmpval->val >> 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(i<sum)
+ {
+ buf[i] = tmpval->val;
+ 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = 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; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+/*\r
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug =1;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+//define sensor_i2c_slave_id 0x54\r
+#define SENSOR_NAME RK29_CAM_SENSOR_NT99160\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99160\r
+#define SENSOR_ID 0x1600\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\\r
+ SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 5000 // 5fps\r
+#define SENSOR_FULLRES_M_FPS 10000 // 5fps\r
+#define SENSOR_FULLRES_H_FPS 15000 // 15-20fps\r
+#define SENSOR_720P_FPS 5000\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+\r
+static unsigned int SensorConfiguration = 0;\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x3100, 0x03},\r
+ {0x3101, 0x80},\r
+ {0x3102, 0x09},\r
+ {0x3104, 0x03},\r
+ {0x3105, 0x03},\r
+ {0x3106, 0x05},\r
+ {0x3107, 0x40},\r
+ {0x3108, 0x00},\r
+ {0x3109, 0x82},\r
+ {0x310A, 0x04},\r
+ {0x310B, 0x00},\r
+ {0x310C, 0x00},\r
+ {0x3111, 0x56},\r
+ {0x3113, 0x66},\r
+ {0x3118, 0xA7},\r
+ {0x3119, 0xA7},\r
+ {0x311A, 0xA7},\r
+ {0x311B, 0x1F}, \r
+ {0x303f, 0x0e},\r
+ {0x3041, 0x04},\r
+ {0x3051, 0xf4},\r
+ {0x320A, 0x5A},\r
+ {0x3250, 0x80}, \r
+ {0x3251, 0x01},\r
+ {0x3252, 0x38},\r
+ {0x3253, 0xA8},\r
+ {0x3254, 0x01},\r
+ {0x3255, 0x00},\r
+ {0x3256, 0x8C},\r
+ {0x3257, 0x70},\r
+ {0x329B, 0x00},\r
+ {0x32A1, 0x00},\r
+ {0x32A2, 0xd8},\r
+ {0x32A3, 0x01},\r
+ {0x32A4, 0x5d},\r
+ {0x32A5, 0x01},\r
+ {0x32A6, 0x0c},\r
+ {0x32A7, 0x01},\r
+ {0x32A8, 0xa8}, \r
+ {0x3210, 0x32}, \r
+ {0x3211, 0x2a},\r
+ {0x3212, 0x30},\r
+ {0x3213, 0x32},\r
+ {0x3214, 0x2e},\r
+ {0x3215, 0x2e},\r
+ {0x3216, 0x2e},\r
+ {0x3217, 0x2e},\r
+ {0x3218, 0x2c},\r
+ {0x3219, 0x2e},\r
+ {0x321A, 0x2a},\r
+ {0x321B, 0x2a},\r
+ {0x321C, 0x2e},\r
+ {0x321D, 0x2e},\r
+ {0x321E, 0x28},\r
+ {0x321F, 0x2c}, \r
+ {0x3220, 0x01},\r
+ {0x3221, 0x48},\r
+ {0x3222, 0x01},\r
+ {0x3223, 0x48},\r
+ {0x3224, 0x01},\r
+ {0x3225, 0x48},\r
+ {0x3226, 0x01},\r
+ {0x3227, 0x48},\r
+ {0x3228, 0x00},\r
+ {0x3229, 0xa4},\r
+ {0x322A, 0x00},\r
+ {0x322B, 0xa4},\r
+ {0x322C, 0x00},\r
+ {0x322D, 0xa4},\r
+ {0x322E, 0x00},\r
+ {0x322F, 0xa4},\r
+ {0x3243, 0xc2}, \r
+ {0x3270, 0x10},\r
+ {0x3271, 0x1B},\r
+ {0x3272, 0x26},\r
+ {0x3273, 0x3E},\r
+ {0x3274, 0x4F},\r
+ {0x3275, 0x5E},\r
+ {0x3276, 0x78},\r
+ {0x3277, 0x8F},\r
+ {0x3278, 0xA3},\r
+ {0x3279, 0xB4},\r
+ {0x327A, 0xD2},\r
+ {0x327B, 0xE3},\r
+ {0x327C, 0xF0},\r
+ {0x327D, 0xF7},\r
+ {0x327E, 0xFF}, \r
+ {0x32F6, 0x0C},\r
+ {0x33c2, 0xF0},\r
+ {0x3302, 0x00},\r
+ {0x3303, 0x3E},\r
+ {0x3304, 0x00},\r
+ {0x3305, 0xC2},\r
+ {0x3306, 0x00},\r
+ {0x3307, 0x00},\r
+ {0x3308, 0x07},\r
+ {0x3309, 0xC4},\r
+ {0x330A, 0x06},\r
+ {0x330B, 0xED},\r
+ {0x330C, 0x01},\r
+ {0x330D, 0x4F},\r
+ {0x330E, 0x01},\r
+ {0x330F, 0x41},\r
+ {0x3310, 0x06},\r
+ {0x3311, 0xDD},\r
+ {0x3312, 0x07},\r
+ {0x3313, 0xE3}, \r
+ {0x3326, 0x14},\r
+ {0x3327, 0x04},\r
+ {0x3328, 0x04},\r
+ {0x3329, 0x02},\r
+ {0x332A, 0x02},\r
+ {0x332B, 0x1D},\r
+ {0x332C, 0x1D},\r
+ {0x332D, 0x04},\r
+ {0x332E, 0x1E},\r
+ {0x332F, 0x1F}, \r
+ {0x3331, 0x0a},\r
+ {0x3332, 0x40},\r
+ {0x33C9, 0xD8},\r
+ {0x33C0, 0x01},\r
+ {0x333F, 0x07},\r
+ {0x3360, 0x10},\r
+ {0x3361, 0x18},\r
+ {0x3362, 0x1f},\r
+ {0x3363, 0xb3}, \r
+ {0x3368, 0xb0},\r
+ {0x3369, 0xa0},\r
+ {0x336A, 0x90},\r
+ {0x336B, 0x80},\r
+ {0x336C, 0x00},\r
+ {0x3363, 0xB3},\r
+ {0x3364, 0x00},\r
+ {0x3365, 0x10},\r
+ {0x3366, 0x06}, \r
+ {0x336d, 0x18},\r
+ {0x336e, 0x18},\r
+ {0x336f, 0x10},\r
+ {0x3370, 0x10}, \r
+ {0x3371, 0x3F},\r
+ {0x3372, 0x3F},\r
+ {0x3373, 0x3F},\r
+ {0x3374, 0x3F},\r
+ {0x3375, 0x20},\r
+ {0x3376, 0x20},\r
+ {0x3377, 0x28},\r
+ {0x3378, 0x30}, \r
+ {0x32f6, 0x0C},\r
+ {0x33A0, 0xE0},\r
+ {0x33A1, 0x20},\r
+ {0x33A2, 0x00},\r
+ {0x33A3, 0x40},\r
+ {0x33A4, 0x00},\r
+ {0x32BF, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x84},\r
+ {0x32C1, 0x84},\r
+ {0x32C2, 0x84},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x95},\r
+ {0x32C9, 0x84},\r
+ {0x32CA, 0xA4},\r
+ {0x32CB, 0xA4},\r
+ {0x32CC, 0xA4},\r
+ {0x32CD, 0xA4},\r
+ {0x32DB, 0x72},\r
+ {0x3241, 0x8B},\r
+ {0x32F0, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x07},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x05},\r
+ {0x3007, 0x03},//x_end =1283\r
+ {0x3008, 0x02},\r
+ {0x3009, 0xD3},//y_end =723\r
+ {0x300A, 0x06},\r
+ {0x300B, 0x48},//pixel_num=1608\r
+ {0x300C, 0x0B},\r
+ {0x300D, 0xA9},//line_num=2985\r
+ {0x300E, 0x05},\r
+ {0x300F, 0x00},//x_width = 1280\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},//y_height=720\r
+ {0x32B8, 0x3F},\r
+ {0x32B9, 0x31},\r
+ {0x32BB, 0x87},\r
+ {0x32BC, 0x38},\r
+ {0x32BD, 0x3C},\r
+ {0x32BE, 0x34},\r
+ {0x3201, 0x3F},\r
+ {0x3109, 0x82},\r
+ {0x310B, 0x00},\r
+ {0x3530, 0xC0},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_midfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x74},\r
+ {0x32C1, 0x74},\r
+ {0x32C2, 0x74},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x95},\r
+ {0x32C9, 0x74},\r
+ {0x32CA, 0x94},\r
+ {0x32CB, 0x94},\r
+ {0x32CC, 0x94},\r
+ {0x32CD, 0x94},\r
+ {0x32DB, 0x72},\r
+ {0x3241, 0x83},\r
+ {0x32F0, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x07},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x05},\r
+ {0x3007, 0x03},//x_end = 1283\r
+ {0x3008, 0x02},\r
+ {0x3009, 0xD3},//y_end =723\r
+ {0x300A, 0x06},\r
+ {0x300B, 0x48},//pixel_num = 1608\r
+ {0x300C, 0x05},\r
+ {0x300D, 0xD4},//line_num = 1492\r
+ {0x300E, 0x05},\r
+ {0x300F, 0x00},//x_width = 1280\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},//y_height=720\r
+ {0x32B8, 0x3F},\r
+ {0x32B9, 0x31},\r
+ {0x32BB, 0x87},\r
+ {0x32BC, 0x38},\r
+ {0x32BD, 0x3C},\r
+ {0x32BE, 0x34},\r
+ {0x3201, 0x3F},\r
+ {0x3109, 0x82},\r
+ {0x310B, 0x00},\r
+ {0x3530, 0xC0},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A},\r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x95},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x72},\r
+ {0x3241, 0x7E},\r
+ {0x32F0, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x07},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x05},\r
+ {0x3007, 0x03},//x_end=1283 x_width=1280\r
+ {0x3008, 0x02},\r
+ {0x3009, 0xD3},//y_end=723 y_height=720\r
+ {0x300A, 0x06},\r
+ {0x300B, 0x48},//line_pixel_num =1608\r
+ {0x300C, 0x02},\r
+ {0x300D, 0xEA},//line_num=746\r
+ {0x300E, 0x05},\r
+ {0x300F, 0x00},//x_width = 1280\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},//y_height = 720\r
+ {0x32B8, 0x3F},\r
+ {0x32B9, 0x31},\r
+ {0x32BB, 0x87},\r
+ {0x32BC, 0x38},\r
+ {0x32BD, 0x3C},\r
+ {0x32BE, 0x34},\r
+ {0x3201, 0x3F},\r
+ {0x3109, 0x82},\r
+ {0x310B, 0x00},\r
+ {0x3530, 0xC0},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01}, \r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A},\r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0xBA},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x77},\r
+ {0x3241, 0x80},\r
+ {0x32E0, 0x03},\r
+ {0x32E1, 0x20},\r
+ {0x32E2, 0x02},\r
+ {0x32E3, 0x58},\r
+ {0x32E4, 0x00},\r
+ {0x32E5, 0x33},\r
+ {0x32E6, 0x00},\r
+ {0x32E7, 0x33},\r
+ {0x32E8, 0x01},\r
+ {0x32F0, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x07},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0xA4},//x_start=164\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x04},\r
+ {0x3007, 0x63},//x_end=1123\r
+ {0x3008, 0x02},\r
+ {0x3009, 0xD3},//y_end=723\r
+ {0x300A, 0x05},\r
+ {0x300B, 0x08},//pixel_num=1288\r
+ {0x300C, 0x02},\r
+ {0x300D, 0xE0},//line_num=736\r
+ {0x300E, 0x03},\r
+ {0x300F, 0xC0},//x_width=960\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},//y_height=720\r
+ {0x32B8, 0x3F},\r
+ {0x32B9, 0x31},\r
+ {0x32BB, 0x87},\r
+ {0x32BC, 0x38},\r
+ {0x32BD, 0x3C},\r
+ {0x32BE, 0x34},\r
+ {0x3201, 0x7F},\r
+ {0x3109, 0x82},\r
+ {0x310B, 0x00},\r
+ {0x3530, 0xC0},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ \r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x84},\r
+ {0x32C1, 0x84},\r
+ {0x32C2, 0x84},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x95},\r
+ {0x32C9, 0x84},\r
+ {0x32CA, 0xA4},\r
+ {0x32CB, 0xA4},\r
+ {0x32CC, 0xA4},\r
+ {0x32CD, 0xA4},\r
+ {0x32DB, 0x72},\r
+ {0x3241, 0x8B},\r
+ {0x32F0, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x07},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x05},\r
+ {0x3007, 0x03},//x_end =1283\r
+ {0x3008, 0x02},\r
+ {0x3009, 0xD3},//y_end =723\r
+ {0x300A, 0x06},\r
+ {0x300B, 0x48},//pixel_num=1608\r
+ {0x300C, 0x0B},\r
+ {0x300D, 0xA9},//line_num=2985\r
+ {0x300E, 0x05},\r
+ {0x300F, 0x00},//x_width = 1280\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},//y_height=720\r
+ {0x32B8, 0x3F},\r
+ {0x32B9, 0x31},\r
+ {0x32BB, 0x87},\r
+ {0x32BC, 0x38},\r
+ {0x32BD, 0x3C},\r
+ {0x32BE, 0x34},\r
+ {0x3201, 0x3F},\r
+ {0x3109, 0x82},\r
+ {0x310B, 0x00},\r
+ {0x3530, 0xC0},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x3021,0x61),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x3000,0),\r
+ SensorRegVal(0x3001,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x3201, 0x3F},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x3201, 0x2F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x51},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x00},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{ \r
+ {0x3201, 0x2F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x38},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x68}, \r
+ {0x3060, 0x01}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //INCANDESCENCE \r
+ {0x3201, 0x2F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x30},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xCB},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //FLUORESCENT]\r
+ {0x3201, 0x2F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x70},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xFF},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]=\r
+{\r
+ //TUNGSTEN]\r
+ {0x3201, 0x2F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x00},\r
+ {0x3296, 0x02},\r
+ {0x3297, 0x30},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,sensor_WhiteB_TungstenLamp3,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x32F1, 0x00},\r
+ {0x32F4, 0x80},\r
+ {0x32F5, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{ \r
+ //Grayscale\r
+ {0x32F1, 0x01},\r
+ {0x32F6, 0X08},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ //Sepia\r
+ {0x32F1, 0x02},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Inverse[] =\r
+{\r
+ //Inverse\r
+ {0x32F1, 0x03}, \r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0xF0},\r
+ {0x32F5, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ //Greenish\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0x60},\r
+ {0x32F5, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Solarization[] =\r
+{\r
+ //Solarization\r
+ {0x32F1, 0x04},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish,sensor_Effect_Green,sensor_Effect_Solarization, NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure04[]=\r
+{\r
+ //[EV-4] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Exposure03[]=\r
+{\r
+ //[EV-3] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure02[]=\r
+{\r
+ //[EV-2] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure01[]=\r
+{\r
+ //[EV-1] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x70},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure00[]=\r
+{\r
+ //[EV+0] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure11[]=\r
+{\r
+ //[EV+1] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x90},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure12[]=\r
+{\r
+ //[EV+2] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xA0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure13[]=\r
+{\r
+ //[EV+3] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xB0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure14[]=\r
+{\r
+ //[EV+4] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xC0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+ sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast04[]=\r
+{\r
+ //[Contrast : -4]\r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x40},\r
+ {0x32F2, 0x40},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast03[]=\r
+{\r
+ //[Contrast : -3] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x30},\r
+ {0x32F2, 0x50},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast02[]=\r
+{\r
+ //[Contrast : -2] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x20},\r
+ {0x32F2, 0x60},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Contrast01[]=\r
+{\r
+ //[Contrast : -1] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x10},\r
+ {0x32F2, 0x70},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast00[]=\r
+{\r
+ //[Contrast : 0] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x00},\r
+ {0x32F2, 0x80},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast11[]=\r
+{\r
+ //[Contrast : +1] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xF0},\r
+ {0x32F2, 0x90},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast12[]=\r
+{\r
+ //[Contrast : +2] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xE0},\r
+ {0x32F2, 0xA0},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast13[]=\r
+{\r
+ //[Contrast : +3] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xD0},\r
+ {0x32F2, 0xB0},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast14[]=\r
+{\r
+ //[Contrast : +4] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xC0},\r
+ {0x32F2, 0xC0},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01,\r
+ sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+ //white balance\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0),\r
+\r
+ //speical effect\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,4,"posterize",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",0),\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+ new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
+};\r
+\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+#define NT99160_FULL_PERIOD_PIXEL_NUMS (1608) // default pixel#(w/o dummy pixels) in UXGA mode\r
+#define NT99160_FULL_PERIOD_LINE_NUMS (746) // default line#(w/o dummy lines) in UXGA mode\r
+#define NT99160_PV_PERIOD_PIXEL_NUMS (1288) // default pixel#(w/o dummy pixels) in SVGA mode\r
+#define NT99160_PV_PERIOD_LINE_NUMS (736) // default line#(w/o dummy lines) in SVGA mode\r
+\r
+/* SENSOR EXPOSURE LINE LIMITATION */\r
+#define NT99160_FULL_EXPOSURE_LIMITATION (1492)\r
+#define NT99160_PV_EXPOSURE_LIMITATION (736)\r
+\r
+// SENSOR UXGA SIZE\r
+#define NT99160_IMAGE_SENSOR_FULL_WIDTH (1280)\r
+#define NT99160_IMAGE_SENSOR_FULL_HEIGHT (720)\r
+\r
+#define NT99160_FULL_GRAB_WIDTH (NT99160_IMAGE_SENSOR_FULL_WIDTH - 16)\r
+#define NT99160_FULL_GRAB_HEIGHT (NT99160_IMAGE_SENSOR_FULL_HEIGHT - 12)\r
+\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+\r
+ SENSOR_DG("%s\n",__FUNCTION__);\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */\r
+ \r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+ int ret=0;\r
+ \r
+ SENSOR_DG("Resume");\r
+ //ret = generic_sensor_ioctrl(icd, Sensor_PowerDown, 0);\r
+\r
+ return ret;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x02;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfd;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x01;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfe;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ \r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug =1;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_NT99240\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99240\r
+#define SENSOR_ID 0x2400\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 5000 // 5fps\r
+#define SENSOR_FULLRES_H_FPS 10000 // 10fps\r
+#define SENSOR_720P_FPS 15000\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = 0;\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain_dr;\r
+ unsigned short int preview_gain_ar;\r
+ unsigned short int preview_gain_dgr;\r
+ unsigned short int preview_gain_agr;\r
+ unsigned short int preview_gain_dgb;\r
+ unsigned short int preview_gain_agb;\r
+ unsigned short int preview_gain_db;\r
+ unsigned short int preview_gain_ab;\r
+ unsigned short int preview_gain_dglobal;\r
+ unsigned short int preview_gain_aglobal;\r
+ unsigned short int preview_awb_r;\r
+ unsigned short int preview_awb_b;\r
+ \r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x32F0, 0x01},\r
+ {0x3028, 0x07},\r
+ {0x3029, 0x00},\r
+ {0x302a, 0x04},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x94},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x6D},\r
+ {0x3210, 0x3A},\r
+ {0x3211, 0x3A},\r
+ {0x3212, 0x3A},\r
+ {0x3213, 0x3A},\r
+ {0x3214, 0x2A},\r
+ {0x3215, 0x2A},\r
+ {0x3216, 0x2A},\r
+ {0x3217, 0x2A},\r
+ {0x3218, 0x2A},\r
+ {0x3219, 0x2A},\r
+ {0x321A, 0x2A},\r
+ {0x321B, 0x2A},\r
+ {0x321C, 0x22},\r
+ {0x321D, 0x22},\r
+ {0x321E, 0x22},\r
+ {0x321F, 0x22},\r
+ {0x3230, 0x30},\r
+ {0x3231, 0x00},\r
+ {0x3232, 0xCF},\r
+ {0x3233, 0x00},\r
+ {0x3234, 0x05},\r
+ {0x3302, 0x00},\r
+ {0x3303, 0x5F},\r
+ {0x3304, 0x00},\r
+ {0x3305, 0x7E},\r
+ {0x3306, 0x00},\r
+ {0x3307, 0x22},\r
+ {0x3308, 0x07},\r
+ {0x3309, 0xC3},\r
+ {0x330A, 0x07},\r
+ {0x330B, 0x33},\r
+ {0x330C, 0x01},\r
+ {0x330D, 0x0A},\r
+ {0x330E, 0x00},\r
+ {0x330F, 0xD3},\r
+ {0x3310, 0x07},\r
+ {0x3311, 0x3B},\r
+ {0x3312, 0x07},\r
+ {0x3313, 0xF2},\r
+ {0x3024, 0x00},\r
+ {0x303E, 0x04},\r
+ {0x303F, 0x02},\r
+ {0x3040, 0xFF},\r
+ {0x3041, 0x02},\r
+ {0x3051, 0xE0},\r
+ {0x3052, 0x10},\r
+ {0x305f, 0x22},\r
+ {0x32b0, 0x00},\r
+ {0x32b1, 0x90},\r
+ {0x32BB, 0x0b},\r
+ {0x32bd, 0x08},\r
+ {0x32be, 0x06},\r
+ {0x32bf, 0x4a},\r
+ {0x32c0, 0x20},\r
+ {0x32C3, 0x06},\r
+ {0x32c5, 0x28},\r
+ {0x32cd, 0x02},\r
+ {0x32d3, 0x12},\r
+ {0x3118, 0xF2},\r
+ {0x3119, 0xF2},\r
+ {0x311A, 0x13},\r
+ {0x3106, 0x03},\r
+ {0x3108, 0x00},\r
+ {0x3112, 0xF1},\r
+ {0x3113, 0x55},\r
+ {0x3114, 0x05},\r
+ {0x3012, 0x03},\r
+ {0x3013, 0xC0},\r
+ {0x3326, 0x02},\r
+ {0x3327, 0x04},\r
+ {0x3328, 0x04},\r
+ {0x3329, 0x02},\r
+ {0x332A, 0x02},\r
+ {0x332B, 0x1D},\r
+ {0x332C, 0x1D},\r
+ {0x332D, 0x04},\r
+ {0x332E, 0x1E},\r
+ {0x332F, 0x1F},\r
+ {0x32f6, 0x0B},\r
+ {0x3343, 0xE0},\r
+ {0x333B, 0x10},\r
+ {0x333C, 0x14},\r
+ {0x333D, 0x30},\r
+ {0x333E, 0x30},\r
+ {0x333F, 0x88},\r
+ {0x3340, 0x84},\r
+ {0x3341, 0x50},\r
+ {0x3342, 0x50},\r
+ {0x3344, 0x20},\r
+ {0x3345, 0x28},\r
+ {0x3346, 0x3F},\r
+ {0x3347, 0x3F},\r
+ {0x3348, 0xF0},\r
+ {0x3349, 0x40},\r
+ {0x334A, 0x40},\r
+ {0x334B, 0x20},\r
+ {0x334C, 0x20},\r
+ {0x334D, 0x00},\r
+ {0x32f6, 0x0B},\r
+ {0x32f9, 0x63},\r
+ {0x32fA, 0x36},\r
+ {0x3338, 0x18},\r
+ {0x3339, 0xC6},\r
+ {0x333A, 0x6C},\r
+ {0x3109, 0x82},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ {0x3200, 0x3e},\r
+ {0x3201, 0x0f},\r
+ {0x3028, 0x07},\r
+ {0x3029, 0x00},\r
+ {0x302a, 0x04},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xb3},\r
+ {0x300a, 0x09},\r
+ {0x300b, 0xc4},\r
+ {0x300c, 0x07},\r
+ {0x300d, 0x80},\r
+ {0x300e, 0x06},\r
+ {0x300f, 0x40},\r
+ {0x3010, 0x04},\r
+ {0x3011, 0xb0},\r
+ {0x3052, 0x10},\r
+ {0x32bb, 0x1b},\r
+ {0x32bc, 0x40},\r
+ {0x32c1, 0x27},\r
+ {0x32c2, 0x80},\r
+ {0x32c8, 0x60},\r
+ {0x32c9, 0x50},\r
+ {0x32c4, 0x00},\r
+ {0x3201, 0x3f},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ {0x3200, 0x3e},\r
+ {0x3201, 0x0f},\r
+ {0x3028, 0x07},\r
+ {0x3029, 0x00},\r
+ {0x302a, 0x04},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xb3},\r
+ {0x300a, 0x08},\r
+ {0x300b, 0x34},\r
+ {0x300c, 0x04},\r
+ {0x300d, 0xbd},\r
+ {0x300e, 0x06},\r
+ {0x300f, 0x40},\r
+ {0x3010, 0x04},\r
+ {0x3011, 0xb0},\r
+ {0x3052, 0x10},\r
+ {0x32bb, 0x1b},\r
+ {0x32bc, 0x40},\r
+ {0x32c1, 0x24},\r
+ {0x32c2, 0x74},\r
+ {0x32c8, 0x72},\r
+ {0x32c9, 0x5f},\r
+ {0x32c4, 0x00},\r
+ {0x3201, 0x3f},\r
+ {0x3021, 0x16},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x32e0, 0x03},\r
+ {0x32e1, 0x20},\r
+ {0x32e2, 0x02},\r
+ {0x32e3, 0x58},\r
+ {0x32e4, 0x01},\r
+ {0x32e5, 0x00},\r
+ {0x32e6, 0x00},\r
+ {0x32e7, 0x00},\r
+ {0x3200, 0x3e},\r
+ {0x3201, 0x0f},\r
+ {0x3028, 0x07},\r
+ {0x3029, 0x00},\r
+ {0x302a, 0x04},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x64},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xb3},\r
+ {0x300a, 0x09},\r
+ {0x300b, 0xc4},\r
+ {0x300c, 0x02},\r
+ {0x300d, 0x80},\r
+ {0x300e, 0x06},\r
+ {0x300f, 0x40},\r
+ {0x3010, 0x02},\r
+ {0x3011, 0x58},\r
+ {0x3052, 0x10},\r
+ {0x32bb, 0x1b},\r
+ {0x32bc, 0x40},\r
+ {0x32c1, 0x22},\r
+ {0x32c2, 0xa0},\r
+ {0x32c8, 0x60},\r
+ {0x32c9, 0x50},\r
+ {0x32c4, 0x00},\r
+ {0x3201, 0x7f},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ {0x3200, 0x3e},\r
+ {0x3201, 0x0f},\r
+ {0x3028, 0x07},\r
+ {0x3029, 0x00},\r
+ {0x302a, 0x04},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0xa4},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0xf4},\r
+ {0x3006, 0x05},\r
+ {0x3007, 0xa3},\r
+ {0x3008, 0x03},\r
+ {0x3009, 0xc3},\r
+ {0x300a, 0x06},\r
+ {0x300b, 0xf4},\r
+ {0x300c, 0x03},\r
+ {0x300d, 0x82},\r
+ {0x300e, 0x05},\r
+ {0x300f, 0x00},\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xd0},\r
+ {0x3052, 0x10},\r
+ {0x32bb, 0x1b},\r
+ {0x32bc, 0x40},\r
+ {0x32c1, 0x23},\r
+ {0x32c2, 0xaa},\r
+ {0x32c8, 0x86},\r
+ {0x32c9, 0x70},\r
+ {0x32c4, 0x00},\r
+ {0x3201, 0x3f},\r
+ {0x3021, 0x16},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x3021,0x61),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x3000,0),\r
+ SensorRegVal(0x3001,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x3201, 0x7F},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ //[WB-CLOUDY]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x51},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x00},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //[WB-DAYLIGHT]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0xD8},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x58}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //[WB-INCANDESCENCE]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x30},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xCB},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //[WB-FLUORESCENT]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x02},\r
+ {0x3291, 0x00},\r
+ {0x3296, 0x02},\r
+ {0x3297, 0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]=\r
+{\r
+ //[WB-TUNGSTEN]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x00},\r
+ {0x3296, 0x02},\r
+ {0x3297, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy, sensor_WhiteB_TungstenLamp3,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x32F1, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{ \r
+ //[SE-GrayScale]\r
+ {0x32F1, 0x01}, \r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ //[SE-SEPIA]\r
+ {0x32F1, 0x02},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Inverse[] =\r
+{\r
+ //[SE-Inverse] \r
+ {0x32F1, 0x03},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ //[SE-SEPIABlue]\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0xF0},\r
+ {0x32F5, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ //[SE-SEPIAGreen]\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0x60},\r
+ {0x32F5, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Solarization[] =\r
+{\r
+ \r
+ //[SE-Solarization]\r
+ {0x32F1, 0x04},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Solarization,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure04[]=\r
+{\r
+ //[EV-4] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure03[]=\r
+{\r
+ //[EV-3] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure02[]=\r
+{\r
+ //[EV-2] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure01[]=\r
+{\r
+ //[EV-1] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x70},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure00[]=\r
+{\r
+ \r
+ //[EV+0] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure11[]=\r
+{\r
+ //[EV+1] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0x90},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure12[]=\r
+{\r
+ //[EV+2] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xA0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure13[]=\r
+{\r
+ //[EV+3] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xB0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure14[]=\r
+{\r
+ //[EV+4] \r
+ {0x32F6, 0X0C},\r
+ {0x32F2, 0xC0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+ sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast04[]=\r
+{\r
+ //[Contrast : -4] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x40},\r
+ {0x32F2, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast03[]=\r
+{\r
+ //[Contrast : -3] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x30},\r
+ {0x32F2, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast02[]=\r
+{\r
+ //[Contrast : -2] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x20},\r
+ {0x32F2, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast01[]=\r
+{\r
+ //[Contrast : -1] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x10},\r
+ {0x32F2, 0x70},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast00[]=\r
+{\r
+ //[Contrast : 0] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0x00},\r
+ {0x32F2, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast11[]=\r
+{\r
+ //[Contrast : +1] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xF0},\r
+ {0x32F2, 0x90},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast12[]=\r
+{\r
+ //[Contrast : +2] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xE0},\r
+ {0x32F2, 0xA0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast13[]=\r
+{\r
+ //[Contrast : +3] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xD0},\r
+ {0x32F2, 0xB0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast14[]=\r
+{\r
+ //[Contrast : +4] \r
+ {0x32F6, 0x0C}, \r
+ {0x32C2, 0xC0},\r
+ {0x32F2, 0xC0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01,\r
+ sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+ //white balance\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0),\r
+\r
+ //speical effect\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,4,"posterize",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",0),\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+ new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+static int sensor_parameter_record(struct i2c_client *client)\r
+{\r
+ u8 ret_l,ret_m,ret_h;\r
+ int tp_l,tp_m,tp_h;\r
+ \r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+\r
+ sensor_read(client, 0x3200, &ret_l);\r
+ sensor_write(client, 0x3200, ret_l&0xf9); \r
+ sensor_read(client, 0x3201, &ret_l);\r
+ sensor_write(client, 0x3201, ret_l&0xcf); //stop ae awb\r
+\r
+ //read back ae\r
+ sensor_read(client,0x3012,&ret_h);\r
+ sensor_read(client,0x3013, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_exposure = ((tp_h<<8) & 0xF0) |((tp_l) & 0x0F);\r
+ \r
+ //Read back AGC Gain for preview\r
+ sensor_read(client,0x3014, &ret_l);\r
+ spsensor->parameter.preview_gain_dr = ret_l;\r
+ sensor_read(client,0x3015, &ret_l);\r
+ spsensor->parameter.preview_gain_ar = ret_l;\r
+ sensor_read(client,0x3016, &ret_l);\r
+ spsensor->parameter.preview_gain_dgr = ret_l;\r
+ sensor_read(client,0x3017, &ret_l);\r
+ spsensor->parameter.preview_gain_agr = ret_l;\r
+ sensor_read(client,0x3018, &ret_l);\r
+ spsensor->parameter.preview_gain_dgb = ret_l;\r
+ sensor_read(client,0x3019, &ret_l);\r
+ spsensor->parameter.preview_gain_agb = ret_l;\r
+ sensor_read(client,0x301a, &ret_l);\r
+ spsensor->parameter.preview_gain_db = ret_l;\r
+ sensor_read(client,0x301b, &ret_l);\r
+ spsensor->parameter.preview_gain_ab = ret_l;\r
+ sensor_read(client,0x301c, &ret_l);\r
+ spsensor->parameter.preview_gain_dglobal= ret_l;\r
+ sensor_read(client,0x301d, &ret_l);\r
+ spsensor->parameter.preview_gain_aglobal= ret_l;\r
+\r
+ spsensor->parameter.CapturePclk = 48000;\r
+ spsensor->parameter.PreviewPclk = 48000;\r
+ sensor_read(client,0x300a, &ret_h);\r
+ sensor_read(client,0x300b, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.PreviewDummyPixels = (tp_l&0x0F) | ((tp_h<<8)&0xF0);\r
+ spsensor->parameter.CaptureDummyPixels = 0;\r
+\r
+ #if 0\r
+ sensor_read(client,0x3290, &ret_h);\r
+ sensor_read(client,0x3291, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_awb_r = (tp_l&0x0F) | ((tp_h<<8)&0x10);\r
+\r
+ sensor_read(client,0x3296, &ret_h);\r
+ sensor_read(client,0x3297, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_awb_b = (tp_l&0x0F) | ((tp_h<<8)&0x10);\r
+ #endif\r
+ return 0;\r
+}\r
+#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode\r
+#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode\r
+#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode\r
+#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode\r
+\r
+/* SENSOR EXPOSURE LINE LIMITATION */\r
+#define OV2659_FULL_EXPOSURE_LIMITATION (1236)\r
+#define OV2659_PV_EXPOSURE_LIMITATION (618)\r
+\r
+// SENSOR UXGA SIZE\r
+#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600)\r
+#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200)\r
+\r
+#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16)\r
+#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12)\r
+\r
+static int sensor_ae_transfer(struct i2c_client *client)\r
+{\r
+ unsigned int prev_line_len,cap_line_len,shutter;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+ int preview_ae_integration, capture_ae_integration;\r
+ int capture_pixel;\r
+ u8 ret_h,ret_l;\r
+ int val_h, val_l;\r
+ \r
+ mdelay(100);\r
+ \r
+ sensor_read(client, 0x3200, &ret_h);\r
+ val_h=ret_h;\r
+ sensor_write(client, 0x3200, ret_h&0xfd); \r
+ sensor_read(client, 0x3201, &ret_l);\r
+ val_l=ret_l;\r
+ sensor_write(client, 0x3201, ret_l&0xdf); //stop ae awb\r
+ \r
+ sensor_read(client,0x300a, &ret_h);\r
+ sensor_read(client,0x300b, &ret_l);\r
+ capture_pixel = (ret_l&0x0F) | ((ret_h<<8)&0xF0);\r
+ preview_ae_integration = spsensor->parameter.preview_exposure*spsensor->parameter.PreviewDummyPixels;\r
+ capture_ae_integration = preview_ae_integration/capture_pixel;\r
+ \r
+ //write back ae\r
+ sensor_write(client,0x3012,(capture_ae_integration>>8)&0x0F);\r
+ sensor_write(client,0x3013,capture_ae_integration&0x0F);\r
+ \r
+ //write back AGC Gain for preview\r
+ sensor_write(client,0x3014, spsensor->parameter.preview_gain_dr);\r
+ sensor_write(client,0x3015, spsensor->parameter.preview_gain_ar);\r
+ sensor_write(client,0x3016, spsensor->parameter.preview_gain_dgr);\r
+ sensor_write(client,0x3017, spsensor->parameter.preview_gain_agr);\r
+ sensor_write(client,0x3018, spsensor->parameter.preview_gain_dgb);\r
+ sensor_write(client,0x3019, spsensor->parameter.preview_gain_agb);\r
+ sensor_write(client,0x301a, spsensor->parameter.preview_gain_db);\r
+ sensor_write(client,0x301b, spsensor->parameter.preview_gain_ab);\r
+ sensor_write(client,0x301c, spsensor->parameter.preview_gain_dglobal);\r
+ sensor_write(client,0x301d, spsensor->parameter.preview_gain_aglobal);\r
+\r
+ #if 0\r
+ sensor_write(client,0x3290, (spsensor->parameter.preview_awb_r>>8)&0x01);\r
+ sensor_write(client,0x3291, spsensor->parameter.preview_awb_r&0x0F);\r
+ sensor_write(client,0x3296, (spsensor->parameter.preview_awb_b>>8)&0x01 );\r
+ sensor_write(client,0x3297, spsensor->parameter.preview_awb_b&0x0F );\r
+ #endif\r
+\r
+ //sensor_write(client, 0x3200, val_h); \r
+ //sensor_write(client, 0x3201, val_l); //enable ae awb\r
+ return 0;\r
+}\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */\r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ printk("set fmt set!!!!!!!!!!!!");\r
+ \r
+ if (capture) {\r
+ sensor_parameter_record(client);\r
+ printk("set fmt set!!!!!!!!!!!!"); \r
+ }\r
+ \r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ u8 val;\r
+\r
+ if (capture) {\r
+ sensor_ae_transfer(client);\r
+ printk("set fmt set!!!!!!!!!!!!"); \r
+ }\r
+ \r
+\r
+ return 0;\r
+}\r
+\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x02;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfd;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x01;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfe;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug =1;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_NT99252\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99252\r
+#define SENSOR_ID 0x2520\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 5000 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 10000 // 7.5fps\r
+#define SENSOR_720P_FPS 1\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = 0;\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x302A, 0x00},\r
+ {0x301F, 0x80},\r
+ {0x303f, 0x0e},\r
+ {0x3051, 0xE8},\r
+ {0x320A, 0x00},\r
+ {0x302E, 0x01},\r
+ {0x3069, 0x04},\r
+ {0x306a, 0x04},\r
+ {0x3101, 0x80},\r
+ {0x3104, 0x03},\r
+ {0x3105, 0x03},\r
+ {0x3106, 0x0D},\r
+ {0x310A, 0x62},\r
+ {0x310D, 0x60},\r
+ {0x3111, 0x5B},\r
+ {0x3131, 0x58},\r
+ {0x3127, 0x01},\r
+ {0x3210, 0x1E},\r
+ {0x3211, 0x1E},\r
+ {0x3212, 0x1E},\r
+ {0x3213, 0x1E},\r
+ {0x3214, 0x17},\r
+ {0x3215, 0x17},\r
+ {0x3216, 0x17},\r
+ {0x3217, 0x17},\r
+ {0x3218, 0x17},\r
+ {0x3219, 0x17},\r
+ {0x321A, 0x17},\r
+ {0x321B, 0x17},\r
+ {0x321C, 0x0F},\r
+ {0x321D, 0x10},\r
+ {0x321E, 0x0F},\r
+ {0x321F, 0x0F},\r
+ {0x3230, 0x00},\r
+ {0x3231, 0x00},\r
+ {0x3232, 0x00},\r
+ {0x3233, 0x00},\r
+ {0x3234, 0x00},\r
+ {0x3235, 0x00},\r
+ {0x3236, 0x00},\r
+ {0x3237, 0x08},\r
+ {0x3238, 0x20},\r
+ {0x3239, 0x20},\r
+ {0x323A, 0x20},\r
+ {0x3243, 0xC3},\r
+ {0x3244, 0x00},\r
+ {0x3245, 0x00},\r
+ {0x3302, 0x00},\r
+ {0x3303, 0x54},\r
+ {0x3304, 0x00},\r
+ {0x3305, 0x91},\r
+ {0x3306, 0x00},\r
+ {0x3307, 0x1A},\r
+ {0x3308, 0x07},\r
+ {0x3309, 0xCD},\r
+ {0x330A, 0x07},\r
+ {0x330B, 0x51},\r
+ {0x330C, 0x00},\r
+ {0x330D, 0xE3},\r
+ {0x330E, 0x00},\r
+ {0x330F, 0xC6},\r
+ {0x3310, 0x07},\r
+ {0x3311, 0x4A},\r
+ {0x3312, 0x07},\r
+ {0x3313, 0xF1},\r
+ {0x3270, 0x00},\r
+ {0x3271, 0x0B},\r
+ {0x3272, 0x16},\r
+ {0x3273, 0x2B},\r
+ {0x3274, 0x3F},\r
+ {0x3275, 0x51},\r
+ {0x3276, 0x72},\r
+ {0x3277, 0x8F},\r
+ {0x3278, 0xA7},\r
+ {0x3279, 0xBC},\r
+ {0x327A, 0xDC},\r
+ {0x327B, 0xF0},\r
+ {0x327C, 0xFA},\r
+ {0x327D, 0xFE},\r
+ {0x327E, 0xFF},\r
+ {0x3327, 0x00},\r
+ {0x3326, 0x1F},\r
+ {0x3360, 0x08},\r
+ {0x3361, 0x0E},\r
+ {0x3362, 0x14},\r
+ {0x3363, 0xB3},\r
+ {0x3331, 0x0C},\r
+ {0x3332, 0x60},\r
+ {0x3365, 0x10},\r
+ {0x3366, 0x10},\r
+ {0x3368, 0x08},\r
+ {0x3369, 0x08},\r
+ {0x336A, 0x06},\r
+ {0x336B, 0x00},\r
+ {0x336d, 0x14},\r
+ {0x336e, 0x14},\r
+ {0x336f, 0x00},\r
+ {0x3370, 0x00},\r
+ {0x3379, 0x0A},\r
+ {0x337A, 0x0A},\r
+ {0x337B, 0x0A},\r
+ {0x337C, 0x0A},\r
+ {0x3371, 0x38},\r
+ {0x3372, 0x38},\r
+ {0x3373, 0x3F},\r
+ {0x3374, 0x3F},\r
+ {0x33A2, 0x00},\r
+ {0x33A3, 0x30},\r
+ {0x33A4, 0x01},\r
+ {0x33c0, 0x03},\r
+ {0x33c9, 0xCF},\r
+ {0x33ca, 0x36},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x84},\r
+ {0x32C1, 0x84},\r
+ {0x32C2, 0x84},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x10},\r
+ {0x32C6, 0x18},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x7E},\r
+ {0x32C9, 0x84},\r
+ {0x32CA, 0x94},\r
+ {0x32CB, 0x94},\r
+ {0x32CC, 0x9C},\r
+ {0x32CD, 0x9C},\r
+ {0x32DB, 0x6F},\r
+ {0x3241, 0x89},\r
+ {0x33A0, 0xAF},\r
+ {0x33A1, 0x64},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x3F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x0C},\r
+ {0x302C, 0x0B},\r
+ {0x302D, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xCC},\r
+ {0x300A, 0x07},\r
+ {0x300B, 0x6C},\r
+ {0x300C, 0x09},\r
+ {0x300D, 0xDE},\r
+ {0x300E, 0x06},\r
+ {0x300F, 0x40},\r
+ {0x3010, 0x04},\r
+ {0x3011, 0xB0},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x36},\r
+ {0x32B9, 0x2A},\r
+ {0x32BC, 0x30},\r
+ {0x32BD, 0x33},\r
+ {0x32BE, 0x2D},\r
+ {0x325C, 0x03},\r
+ {0x320A, 0x00},\r
+ {0x3021, 0x06},\r
+ {0x334A, 0x34},\r
+ {0x334B, 0x14},\r
+ {0x334C, 0x10},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x74},\r
+ {0x32C1, 0x74},\r
+ {0x32C2, 0x74},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x10},\r
+ {0x32C6, 0x18},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x7E},\r
+ {0x32C9, 0x74},\r
+ {0x32CA, 0x84},\r
+ {0x32CB, 0x84},\r
+ {0x32CC, 0x8C},\r
+ {0x32CD, 0x8C},\r
+ {0x32DB, 0x6F},\r
+ {0x3241, 0x81},\r
+ {0x33A0, 0xAF},\r
+ {0x33A1, 0x54},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x3F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x0C},\r
+ {0x302C, 0x0B},\r
+ {0x302D, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xCC},\r
+ {0x300A, 0x07},\r
+ {0x300B, 0x6C},\r
+ {0x300C, 0x04},\r
+ {0x300D, 0xEF},\r
+ {0x300E, 0x06},\r
+ {0x300F, 0x40},\r
+ {0x3010, 0x04},\r
+ {0x3011, 0xB0},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x36},\r
+ {0x32B9, 0x2A},\r
+ {0x32BC, 0x30},\r
+ {0x32BD, 0x33},\r
+ {0x32BE, 0x2D},\r
+ {0x325C, 0x03},\r
+ {0x320A, 0x00},\r
+ {0x3021, 0x06},\r
+ {0x334A, 0x34},\r
+ {0x334B, 0x14},\r
+ {0x334C, 0x10},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A},\r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0xB9},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x77},\r
+ {0x3241, 0x80},\r
+ {0x33A0, 0xB7},\r
+ {0x33A1, 0x4A},\r
+ {0x32E0, 0x03},\r
+ {0x32E1, 0x20},\r
+ {0x32E2, 0x02},\r
+ {0x32E3, 0x58},\r
+ {0x32E4, 0x00},\r
+ {0x32E5, 0x00},\r
+ {0x32E6, 0x00},\r
+ {0x32E7, 0x00},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x7F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x0C},\r
+ {0x302C, 0x0B},\r
+ {0x302D, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x6E},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x06},\r
+ {0x3007, 0x43},//x_end=1603\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xCC},//y_end=1228\r
+ {0x300A, 0x05},\r
+ {0x300B, 0x14},//pixel=1300\r
+ {0x300C, 0x02},\r
+ {0x300D, 0x67},//line=615\r
+ {0x300E, 0x03},\r
+ {0x300F, 0x20},//x_width=800\r
+ {0x3010, 0x02},\r
+ {0x3011, 0x58},//y_width=600\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x36},\r
+ {0x32B9, 0x2A},\r
+ {0x32BC, 0x30},\r
+ {0x32BD, 0x33},\r
+ {0x32BE, 0x2D},\r
+ {0x325C, 0x02},\r
+ {0x320A, 0x00},\r
+ {0x3021, 0x06},\r
+ {0x334A, 0x00},\r
+ {0x334B, 0x7F},\r
+ {0x334C, 0x1F},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A}, \r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x98},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x73},\r
+ {0x3241, 0x7E},\r
+ {0x33A0, 0xB3},\r
+ {0x33A1, 0x4A},\r
+ {0x3200, 0x3E},\r
+ {0x3201, 0x3F},\r
+ {0x302A, 0x00},\r
+ {0x302C, 0x0C},\r
+ {0x302C, 0x0B},\r
+ {0x302D, 0x02},\r
+ {0x3022, 0x24},\r
+ {0x3023, 0x24},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0xA4},\r
+ {0x3004, 0x00},\r
+ {0x3005, 0xF4},\r
+ {0x3006, 0x05},\r
+ {0x3007, 0xA3},\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xCC},\r
+ {0x300A, 0x06},\r
+ {0x300B, 0x2C},\r
+ {0x300C, 0x02},\r
+ {0x300D, 0xDC},\r
+ {0x300E, 0x05},\r
+ {0x300F, 0x00},\r
+ {0x3010, 0x02},\r
+ {0x3011, 0xD0},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x36},\r
+ {0x32B9, 0x2A},\r
+ {0x32BC, 0x30},\r
+ {0x32BD, 0x33},\r
+ {0x32BE, 0x2D},\r
+ {0x325C, 0x03},\r
+ {0x320A, 0x00},\r
+ {0x3021, 0x06},\r
+ {0x334A, 0x00},\r
+ {0x334B, 0x7F},\r
+ {0x334C, 0x1F},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x3021,0x61),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x3000,0),\r
+ SensorRegVal(0x3001,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ //[WB-AUTO]\r
+ {0x3201, 0x7F}, //AWB auto, bit[4]:1,auto\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ //[WB-CLOUDY]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x51},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x00},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //[WB-DAYLIGHT]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x38},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x68}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //[WB-INCANDESCENCE]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x30},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xCB},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //[WB-FLUORESCENT]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x70},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xFF},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]=\r
+{\r
+ //[WB-TUNGSTEN]\r
+ {0x3201, 0x6F},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x00},\r
+ {0x3296, 0x02},\r
+ {0x3297, 0x30}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy, sensor_WhiteB_TungstenLamp3, NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x32f1, 0x00},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ //[SE-GrayScale]\r
+ {0x32f1, 0x01},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ //[SE-SEPIA]\r
+ {0x32f1, 0x02},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //[SE-Inverse] \r
+ {0x32f1, 0x03},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ //[SE-SEPIABlue]\r
+ {0x32f1, 0x05},\r
+ {0x32f4, 0xf0},\r
+ {0x32f5, 0x80},\r
+ {0x32f8, 0x01}, \r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ //[SE-SEPIAGreen]\r
+ {0x32f1, 0x05},\r
+ {0x32f4, 0x60},\r
+ {0x32f5, 0x20},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Solarization[] =\r
+{\r
+ //[SE-Solarization]\r
+ {0x32f1, 0x04},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green, sensor_Effect_Solarization, NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure04[]=\r
+{\r
+ //[EV-4] \r
+ {0x32F2, 0x40},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure03[]=\r
+{\r
+ //[EV-3] \r
+ {0x32F2, 0x50},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure02[]=\r
+{\r
+ //[EV-2] \r
+ {0x32F2, 0x60},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure01[]=\r
+{\r
+ //[EV-1] \r
+ {0x32F2, 0x70},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure00[]=\r
+{\r
+ //[EV+0] \r
+ {0x32F2, 0x80},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure11[]=\r
+{\r
+ //[EV+1] \r
+ {0x32F2, 0x90},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure12[]=\r
+{\r
+ //[EV+2] \r
+ {0x32F2, 0xA0},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure13[]=\r
+{\r
+ //[EV+3] \r
+ {0x32F2, 0xB0},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure14[]=\r
+{\r
+ //[EV+4] \r
+ {0x32F2, 0xC0},\r
+ {0x32F8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+ sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast04[]=\r
+{\r
+ //[Contrast : -4] \r
+ {0x32FC, 0x40},\r
+ {0x32F2, 0x40},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast03[]=\r
+{\r
+ //[Contrast : -3] \r
+ {0x32FC, 0x30},\r
+ {0x32F2, 0x50},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast02[]=\r
+{\r
+ //[Contrast : -2] \r
+ {0x32FC, 0x20},\r
+ {0x32F2, 0x60},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast01[]=\r
+{\r
+ //[Contrast : -1] \r
+ {0x32FC, 0x10},\r
+ {0x32F2, 0x70},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast00[]=\r
+{\r
+ //[Contrast : 0] \r
+ {0x32FC, 0x00},\r
+ {0x32F2, 0x80},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast11[]=\r
+{\r
+ //[Contrast : +1] \r
+ {0x32FC, 0xF0},\r
+ {0x32F2, 0x90},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast12[]=\r
+{\r
+ //[Contrast : +2] \r
+ {0x32FC, 0xE0},\r
+ {0x32F2, 0xA0},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast13[]=\r
+{\r
+ //[Contrast : +3] \r
+ {0x32FC, 0xD0},\r
+ {0x32F2, 0xB0},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast14[]=\r
+{\r
+ //[Contrast : +4] \r
+ {0x32FC, 0xC0},\r
+ {0x32F2, 0xC0},\r
+ {0x32f8, 0x01},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01,\r
+ sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+ //white balance\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0),\r
+\r
+ //speical effect\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,4,"posterize",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",0),\r
+\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+ new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+static int sensor_parameter_record(struct i2c_client *client)\r
+{\r
+ u8 ret_l,ret_m,ret_h;\r
+ int tp_l,tp_m,tp_h;\r
+ \r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+\r
+ sensor_read(client,0x3a00, &ret_l);\r
+ sensor_write(client,0x3a00, ret_l&0xfb);\r
+\r
+ sensor_write(client,0x3503,0x07); //stop AE/AG\r
+\r
+ sensor_read(client,0x3500,&ret_h);\r
+ sensor_read(client,0x3501, &ret_m);\r
+ sensor_read(client,0x3502, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_m = ret_m;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F);\r
+ \r
+ //Read back AGC Gain for preview\r
+ sensor_read(client,0x350b, &ret_l);\r
+ spsensor->parameter.preview_gain = ret_l;\r
+\r
+ spsensor->parameter.CapturePclk = 24000;\r
+ spsensor->parameter.PreviewPclk = 24000;\r
+ spsensor->parameter.PreviewDummyPixels = 0;\r
+ spsensor->parameter.CaptureDummyPixels = 0;\r
+ SENSOR_DG("Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x",\r
+ ret_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l);\r
+ return 0;\r
+}\r
+#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode\r
+#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode\r
+#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode\r
+#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode\r
+\r
+/* SENSOR EXPOSURE LINE LIMITATION */\r
+#define OV2659_FULL_EXPOSURE_LIMITATION (1236)\r
+#define OV2659_PV_EXPOSURE_LIMITATION (618)\r
+\r
+// SENSOR UXGA SIZE\r
+#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600)\r
+#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200)\r
+\r
+#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16)\r
+#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12)\r
+\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+\r
+ SENSOR_DG("%s",__FUNCTION__); \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */\r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ }\r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ //sensor_parameter_record(client);\r
+ }\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ //sensor_ae_transfer(client);\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x02;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfd;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x01;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfe;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
--- /dev/null
+\r
+#include "generic_sensor.h"\r
+\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug =1;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_NT99340\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_NT99340\r
+#define SENSOR_ID 0x3400\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\\r
+ SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 5000 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 10000 // 7.5fps\r
+#define SENSOR_720P_FPS 15000 \r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+\r
+static unsigned int SensorConfiguration = 0;\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+\r
+/* Sensor Driver Configuration End */\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x32F0, 0x00},\r
+ {0x32FF, 0x00},\r
+ {0x303E, 0x0C},\r
+ {0x303F, 0x02},\r
+ {0x3040, 0xFF},\r
+ {0x3041, 0x00},\r
+ {0x3042, 0x00},\r
+ {0x3051, 0xFC},\r
+ {0x3052, 0x10},\r
+ {0x3069, 0x03},\r
+ {0x306a, 0x03},\r
+ {0x3118, 0xA7},\r
+ {0x3119, 0xA7},\r
+ {0x311A, 0xA7},\r
+ {0x3100, 0x03},\r
+ {0x3101, 0x80},\r
+ {0x3102, 0x09},\r
+ {0x3103, 0x09},\r
+ {0x3104, 0x01},\r
+ {0x3105, 0x01},\r
+ {0x3106, 0x03},\r
+ {0x3107, 0x20},\r
+ {0x3108, 0x00},\r
+ {0x3109, 0x82},\r
+ {0x310A, 0x04},\r
+ {0x3030, 0x0A},\r
+ {0x306C, 0x0C},\r
+ {0x306D, 0x0C},\r
+ {0x3583, 0x18},\r
+ {0x3587, 0x02},\r
+ {0x3584, 0x00},\r
+ {0x3585, 0x00},\r
+ {0x3580, 0xB2},\r
+ {0x3600, 0x66},\r
+ {0x3601, 0x99},\r
+ {0x3604, 0x15},\r
+ {0x3605, 0x13},\r
+ {0x3614, 0x20},\r
+ {0x361A, 0x10},\r
+ {0x3615, 0x24},\r
+ {0x3610, 0x02},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x80},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x60},\r
+ {0x3250, 0x80},\r
+ {0x3251, 0x01},\r
+ {0x3252, 0x27},\r
+ {0x3253, 0x9D},\r
+ {0x3254, 0x00},\r
+ {0x3255, 0xE3},\r
+ {0x3256, 0x81},\r
+ {0x3257, 0x70},\r
+ {0x329B, 0x00},\r
+ {0x32A1, 0x00},\r
+ {0x32A2, 0xEC},\r
+ {0x32A3, 0x01},\r
+ {0x32A4, 0x7A},\r
+ {0x32A5, 0x01},\r
+ {0x32A6, 0x14},\r
+ {0x32A7, 0x01},\r
+ {0x32A8, 0xB3},\r
+ {0x3270, 0x00},\r
+ {0x3271, 0x0B},\r
+ {0x3272, 0x16},\r
+ {0x3273, 0x2B},\r
+ {0x3274, 0x3F},\r
+ {0x3275, 0x51},\r
+ {0x3276, 0x72},\r
+ {0x3277, 0x8F},\r
+ {0x3278, 0xA7},\r
+ {0x3279, 0xBC},\r
+ {0x327A, 0xDC},\r
+ {0x327B, 0xF0},\r
+ {0x327C, 0xFA},\r
+ {0x327D, 0xFE},\r
+ {0x327E, 0xFF},\r
+ {0x3302, 0x00},\r
+ {0x3303, 0x4D},\r
+ {0x3304, 0x00},\r
+ {0x3305, 0x96},\r
+ {0x3306, 0x00},\r
+ {0x3307, 0x1D},\r
+ {0x3308, 0x07},\r
+ {0x3309, 0xC7},\r
+ {0x330A, 0x07},\r
+ {0x330B, 0x0A},\r
+ {0x330C, 0x01},\r
+ {0x330D, 0x30},\r
+ {0x330E, 0x01},\r
+ {0x330F, 0x07},\r
+ {0x3310, 0x06},\r
+ {0x3311, 0xFF},\r
+ {0x3312, 0x07},\r
+ {0x3313, 0xFA},\r
+ {0x3210, 0x1E},\r
+ {0x3211, 0x20},\r
+ {0x3212, 0x20},\r
+ {0x3213, 0x1E},\r
+ {0x3214, 0x18},\r
+ {0x3215, 0x1A},\r
+ {0x3216, 0x1A},\r
+ {0x3217, 0x18},\r
+ {0x3218, 0x18},\r
+ {0x3219, 0x1A},\r
+ {0x321A, 0x1A},\r
+ {0x321B, 0x18},\r
+ {0x321C, 0x16},\r
+ {0x321D, 0x1A},\r
+ {0x321E, 0x17},\r
+ {0x321F, 0x15},\r
+ {0x3234, 0x0F},\r
+ {0x3235, 0x0F},\r
+ {0x3236, 0x0F},\r
+ {0x3237, 0x0F},\r
+ {0x3238, 0x40},\r
+ {0x3239, 0x40},\r
+ {0x323A, 0x40},\r
+ {0x3241, 0x40},\r
+ {0x3243, 0x41},\r
+ {0x32F6, 0x0F},\r
+ {0x32F9, 0x42},\r
+ {0x32FA, 0x24},\r
+ {0x3338, 0x18},\r
+ {0x3339, 0xC6},\r
+ {0x333A, 0x6C},\r
+ {0x3335, 0x60},\r
+ {0x3336, 0x20},\r
+ {0x3337, 0x40},\r
+ {0x333B, 0xC6},\r
+ {0x333C, 0x6C},\r
+ {0x3325, 0xAF},\r
+ {0x3326, 0x02},\r
+ {0x3327, 0x00},\r
+ {0x3331, 0x08},\r
+ {0x3332, 0xFF},\r
+ {0x333F, 0x07},\r
+ {0x334A, 0x34},\r
+ {0x334B, 0x14},\r
+ {0x334C, 0x10},\r
+ {0x3363, 0x33},\r
+ {0x3360, 0x08},\r
+ {0x3361, 0x10},\r
+ {0x3362, 0x18},\r
+ {0x3364, 0x88},\r
+ {0x3365, 0x80},\r
+ {0x3366, 0x68},\r
+ {0x3367, 0x40},\r
+ {0x3368, 0x50},\r
+ {0x3369, 0x40},\r
+ {0x336A, 0x30},\r
+ {0x336B, 0x20},\r
+ {0x336C, 0x00},\r
+ {0x336D, 0x1A},\r
+ {0x336E, 0x16},\r
+ {0x336F, 0x14},\r
+ {0x3370, 0x0C},\r
+ {0x3371, 0x3F},\r
+ {0x3372, 0x3F},\r
+ {0x3373, 0x3F},\r
+ {0x3374, 0x3F},\r
+ {0x3375, 0x0E},\r
+ {0x3376, 0x10},\r
+ {0x3377, 0x14},\r
+ {0x3378, 0x20},\r
+ {0x3012, 0x02},\r
+ {0x3013, 0x58},\r
+ {0x301D, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x84},\r
+ {0x32C1, 0x84},\r
+ {0x32C2, 0x84},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x9E},\r
+ {0x32C9, 0x84},\r
+ {0x32CA, 0xA4},\r
+ {0x32CB, 0xA4},\r
+ {0x32CC, 0xA4},\r
+ {0x32CD, 0xA4},\r
+ {0x32DB, 0x73},\r
+ {0x32D0, 0x01},\r
+ {0x3200, 0x3F},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302B, 0x01},\r
+ {0x302C, 0x0F},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x08},\r
+ {0x3007, 0x03},//x_end=2051\r
+ {0x3008, 0x06},\r
+ {0x3009, 0x03},//y_end=1539\r
+ {0x300A, 0x0B},\r
+ {0x300B, 0xD0},//pixel=3024\r
+ {0x300C, 0x0C},\r
+ {0x300D, 0x66},//line=3174\r
+ {0x300E, 0x08},\r
+ {0x300F, 0x00},//x=2048\r
+ {0x3010, 0x06},\r
+ {0x3011, 0x00},//y=1536\r
+ {0x3052, 0x10},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x3B},\r
+ {0x32B9, 0x2D},\r
+ {0x32BC, 0x34},\r
+ {0x32BD, 0x38},\r
+ {0x32BE, 0x30},\r
+ {0x3201, 0xBF},\r
+ {0x3109, 0x82},\r
+ {0x3530, 0xC0},\r
+ {0x320A, 0x42},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x74},\r
+ {0x32C1, 0x74},\r
+ {0x32C2, 0x74},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0x9E},\r
+ {0x32C9, 0x74},\r
+ {0x32CA, 0x94},\r
+ {0x32CB, 0x94},\r
+ {0x32CC, 0x94},\r
+ {0x32CD, 0x94},\r
+ {0x32DB, 0x73},\r
+ {0x32D0, 0x01},\r
+ {0x3200, 0x3F},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302B, 0x01},\r
+ {0x302C, 0x0F},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x08},\r
+ {0x3007, 0x03},//x_end=2051\r
+ {0x3008, 0x06},\r
+ {0x3009, 0x03},//y_end=1539\r
+ {0x300A, 0x0B},\r
+ {0x300B, 0xD0},//pixel=3024\r
+ {0x300C, 0x06},\r
+ {0x300D, 0x33},//line=1587\r
+ {0x300E, 0x08},\r
+ {0x300F, 0x00},//x=2048\r
+ {0x3010, 0x06},\r
+ {0x3011, 0x00},//y=1536\r
+ {0x3052, 0x10},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x3B},\r
+ {0x32B9, 0x2D},\r
+ {0x32BC, 0x34},\r
+ {0x32BD, 0x38},\r
+ {0x32BE, 0x30},\r
+ {0x3201, 0xBF},\r
+ {0x3109, 0x82},\r
+ {0x3530, 0xC0},\r
+ {0x320A, 0x42},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A},\r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x00},\r
+ {0x32C8, 0xF0},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x7E},\r
+ {0x32D0, 0x01},\r
+ {0x32E0, 0x03},\r
+ {0x32E1, 0x20},\r
+ {0x32E2, 0x02},\r
+ {0x32E3, 0x58},\r
+ {0x32E4, 0x00},\r
+ {0x32E5, 0x48},\r
+ {0x32E6, 0x00},\r
+ {0x32E7, 0x48},\r
+ {0x3200, 0x3F},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302B, 0x01},\r
+ {0x302C, 0x0F},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x6E},\r
+ {0x3128, 0x01},\r
+ {0x3002, 0x00},\r
+ {0x3003, 0x04},//x_start=4\r
+ {0x3004, 0x00},\r
+ {0x3005, 0x04},//y_start=4\r
+ {0x3006, 0x08},\r
+ {0x3007, 0x03},//x_end=2051\r
+ {0x3008, 0x06},\r
+ {0x3009, 0x03},//y_end=1539\r
+ {0x300A, 0x07},\r
+ {0x300B, 0xD0},//pixel=2000\r
+ {0x300C, 0x03},\r
+ {0x300D, 0x20},//line=800\r
+ {0x300E, 0x04},\r
+ {0x300F, 0x00},//x=1024\r
+ {0x3010, 0x03},\r
+ {0x3011, 0x00},//y=768\r
+ {0x3052, 0x10},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x3B},\r
+ {0x32B9, 0x2D},\r
+ {0x32BC, 0x34},\r
+ {0x32BD, 0x38},\r
+ {0x32BE, 0x30},\r
+ {0x3201, 0xFF},\r
+ {0x3109, 0x82},\r
+ {0x3530, 0xC0},\r
+ {0x320A, 0x42},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ {0x32BF, 0x60},\r
+ {0x32C0, 0x6A},\r
+ {0x32C1, 0x6A},\r
+ {0x32C2, 0x6A},\r
+ {0x32C3, 0x00},\r
+ {0x32C4, 0x20},\r
+ {0x32C5, 0x20},\r
+ {0x32C6, 0x20},\r
+ {0x32C7, 0x40},\r
+ {0x32C8, 0x08},\r
+ {0x32C9, 0x6A},\r
+ {0x32CA, 0x8A},\r
+ {0x32CB, 0x8A},\r
+ {0x32CC, 0x8A},\r
+ {0x32CD, 0x8A},\r
+ {0x32DB, 0x80},\r
+ {0x32D0, 0x01},\r
+ {0x32E0, 0x05},\r
+ {0x32E1, 0x00},\r
+ {0x32E2, 0x02},\r
+ {0x32E3, 0xD0},\r
+ {0x32E4, 0x00},\r
+ {0x32E5, 0x28},\r
+ {0x32E6, 0x00},\r
+ {0x32E7, 0x28},\r
+ {0x3200, 0x3F},\r
+ {0x3201, 0x0F},\r
+ {0x302A, 0x00},\r
+ {0x302B, 0x01},\r
+ {0x302C, 0x0F},\r
+ {0x302D, 0x00},\r
+ {0x302E, 0x00},\r
+ {0x302F, 0x02},\r
+ {0x3022, 0x27},\r
+ {0x3023, 0x24},\r
+ {0x3128, 0x00},\r
+ {0x3002, 0x01},\r
+ {0x3003, 0x20},//x_start=288\r
+ {0x3004, 0x01},\r
+ {0x3005, 0x64},//y_start = 356\r
+ {0x3006, 0x06},\r
+ {0x3007, 0xE7},//x_end = 1767\r
+ {0x3008, 0x04},\r
+ {0x3009, 0xA3},//y_end=1187\r
+ {0x300A, 0x07},\r
+ {0x300B, 0x14},//pixel=1812\r
+ {0x300C, 0x03},\r
+ {0x300D, 0x73},//line=883\r
+ {0x300E, 0x05},\r
+ {0x300F, 0xC8},//x=1480\r
+ {0x3010, 0x03},\r
+ {0x3011, 0x40},//y=832\r
+ {0x3052, 0x10},\r
+ {0x32BB, 0x87},\r
+ {0x32B8, 0x3B},\r
+ {0x32B9, 0x2D},\r
+ {0x32BC, 0x34},\r
+ {0x32BD, 0x38},\r
+ {0x32BE, 0x30},\r
+ {0x3201, 0xFF},\r
+ {0x3109, 0x82},\r
+ {0x3530, 0xC0},\r
+ {0x320A, 0x42},\r
+ {0x3021, 0x06},\r
+ {0x3060, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x3021,0x61),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x3000,0),\r
+ SensorRegVal(0x3001,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ //[WB-AUTO]\r
+ {0x3201, 0xFF},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ //[WB-CLOUDY]\r
+ {0x3201, 0xEF},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x51},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x00},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //[WB-DAYLIGHT]\r
+ {0x3201, 0xEF},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x38},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0x68}, \r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //[WB-INCANDESCENCE]\r
+ {0x3201, 0xEF},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x30},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xCB},\r
+ SensorEnd\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //[WB-FLUORESCENT]\r
+ {0x3201, 0xEF},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x70},\r
+ {0x3296, 0x01},\r
+ {0x3297, 0xFF},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp3[]=\r
+{\r
+ //[WB-TUNGSTEN]\r
+ {0x3201, 0xEF},\r
+ {0x3290, 0x01},\r
+ {0x3291, 0x00},\r
+ {0x3296, 0x02},\r
+ {0x3297, 0x30},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,sensor_WhiteB_TungstenLamp3,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ //[SE-Normal]\r
+ {0x32F1, 0x00},\r
+ {0x32F4, 0x80},\r
+ {0x32F5, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ //[SE-GrayScale]\r
+ {0x32F1, 0x01},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ //[SE-SEPIA]\r
+ {0x32F1, 0x02},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Inverse[] =\r
+{\r
+ //[SE-Inverse] \r
+ {0x32F1, 0x03},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ //[SE-SEPIABlue]\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0xF0},\r
+ {0x32F5, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{ \r
+ //[SE-SEPIAGreen]\r
+ {0x32F1, 0x05},\r
+ {0x32F4, 0x60},\r
+ {0x32F5, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Solarization[] =\r
+{ \r
+ //[SE-Solarization]\r
+ {0x32F1, 0x04},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Inverse,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,sensor_Effect_Solarization,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure04[]=\r
+{\r
+ //[EV-4] \r
+ {0x32F2, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure03[]=\r
+{\r
+ //[EV-3] \r
+ {0x32F2, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure02[]=\r
+{\r
+ //[EV-2] \r
+ {0x32F2, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure01[]=\r
+{\r
+ //[EV-1] \r
+ {0x32F2, 0x70},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure00[]=\r
+{\r
+ //[EV+0] \r
+ {0x32F2, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure11[]=\r
+{\r
+ //[EV+1] \r
+ {0x32F2, 0x90},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure12[]=\r
+{\r
+ //[EV+2] \r
+ {0x32F2, 0xA0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure13[]=\r
+{\r
+ //[EV+3] \r
+ {0x32F2, 0xB0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure14[]=\r
+{ \r
+ //[EV+4] \r
+ {0x32F2, 0xC0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure04,sensor_Exposure03, sensor_Exposure02, sensor_Exposure01, sensor_Exposure00,\r
+ sensor_Exposure11, sensor_Exposure12,sensor_Exposure13,sensor_Exposure14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast04[]=\r
+{\r
+ //[Contrast : -4] \r
+ {0x32C2, 0x40},\r
+ {0x32F2, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast03[]=\r
+{\r
+ //[Contrast : -3] \r
+ {0x32C2, 0x30},\r
+ {0x32F2, 0x50},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast02[]=\r
+{\r
+ //[Contrast : -2] \r
+ {0x32C2, 0x20},\r
+ {0x32F2, 0x60},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast01[]=\r
+{\r
+ //[Contrast : -1] \r
+ {0x32C2, 0x10},\r
+ {0x32F2, 0x70},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast00[]=\r
+{\r
+ //[Contrast : 0] \r
+ {0x32C2, 0x00},\r
+ {0x32F2, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast11[]=\r
+{\r
+ //[Contrast : +1] \r
+ {0x32C2, 0xF0},\r
+ {0x32F2, 0x90},\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast12[]=\r
+{\r
+ //[Contrast : +2] \r
+ {0x32C2, 0xE0},\r
+ {0x32F2, 0xA0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast13[]=\r
+{\r
+ //[Contrast : +3] \r
+ {0x32C2, 0xD0},\r
+ {0x32F2, 0xB0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast14[]=\r
+{\r
+ //[Contrast : +4] \r
+ {0x32C2, 0xC0},\r
+ {0x32F2, 0xC0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast04, sensor_Contrast03, sensor_Contrast02, sensor_Contrast01,\r
+ sensor_Contrast00, sensor_Contrast11, sensor_Contrast12, sensor_Contrast13, sensor_Contrast14,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+ //white balance\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0),\r
+ new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,5,"tungsten",0),\r
+\r
+ //speical effect\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,0,"none",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,1,"mono",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,4,"posterize",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,5,"aqua",0),\r
+ new_usr_v4l2menu(V4L2_CID_EFFECT,6,"solarize",0),\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+ new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 5, 1, 0,sensor_v4l2ctrl_default_cb, sensor_WhiteBalanceSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ExposureSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 6, 1, 0,sensor_v4l2ctrl_default_cb, sensor_EffectSeqe),\r
+ new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_v4l2ctrl_default_cb, sensor_ContrastSeqe),\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+ //generic_sensor_ioctrl(icd, Sensor_PowerDown, 0);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct soc_camera_device *icd = client->dev.platform_data;\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */\r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ //generic_sensor_ioctrl(icd, Sensor_PowerDown, 1);\r
+ sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ // sensor_parameter_record(client);\r
+ }\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ // sensor_ae_transfer(client);\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x02;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfd;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val |= 0x01;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3022, &val);\r
+ if (err == 0) {\r
+ val &= 0xfe;\r
+ err = sensor_write(client, 0x3022, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+/*\r
+AF call back\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
+\r
+\r
+#include "generic_sensor.h"\r
/*
-o* Driver for MT9M001 CMOS Image Sensor from Micron
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char value;
- int ret,pid = 0;
- struct sensor *sensor = to_sensor(client);
-
- /* We must have a parent by now. And it cannot be a wrong one.
- * So this entire test is completely redundant. */
- if (!icd->dev.parent ||
- to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
- return -ENODEV;
-
- if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
- 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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_OV2659\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_OV2659\r
+#define SENSOR_ID 0x2656\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x3000, 0x0f},\r
+ {0x3001, 0xff},\r
+ {0x3002, 0xff},\r
+ //{0x0100, 0x01}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array\r
+ {0x3633, 0x3d},\r
+ {0x3620, 0x02},\r
+ {0x3631, 0x11},\r
+ {0x3612, 0x04},\r
+ {0x3630, 0x20},\r
+ {0x4702, 0x02},\r
+ {0x370c, 0x34},\r
+ {0x3004, 0x10},\r
+ {0x3005, 0x18},\r
+ {0x3800, 0x00},\r
+ {0x3801, 0x00},\r
+ {0x3802, 0x00},\r
+ {0x3803, 0x00},\r
+ {0x3804, 0x06},\r
+ {0x3805, 0x5f},\r
+ {0x3806, 0x04},\r
+ {0x3807, 0xb7},\r
+ {0x3808, 0x03},\r
+ {0x3809, 0x20},\r
+ {0x380a, 0x02},\r
+ {0x380b, 0x58},\r
+ {0x380c, 0x05},\r
+ {0x380d, 0x14},\r
+ {0x380e, 0x02},\r
+ {0x380f, 0x68},\r
+ {0x3811, 0x08},\r
+ {0x3813, 0x02},\r
+ {0x3814, 0x31},\r
+ {0x3815, 0x31},\r
+ {0x3a02, 0x02},\r
+ {0x3a03, 0x68},\r
+ {0x3a08, 0x00},\r
+ {0x3a09, 0x5c},\r
+ {0x3a0a, 0x00},\r
+ {0x3a0b, 0x4d},\r
+ {0x3a0d, 0x08},\r
+ {0x3a0e, 0x06},\r
+ {0x3a14, 0x02},\r
+ {0x3a15, 0x28},\r
+ {0x4708, 0x01},\r
+ {0x3623, 0x00},\r
+ {0x3634, 0x76},\r
+ {0x3701, 0x44},\r
+ {0x3702, 0x18},\r
+ {0x3703, 0x24},\r
+ {0x3704, 0x24},\r
+ {0x3705, 0x0c},\r
+ {0x3820, 0x81},\r
+ {0x3821, 0x01},\r
+ {0x370a, 0x52},\r
+ {0x4608, 0x00},\r
+ {0x4609, 0x80},\r
+ {0x4300, 0x32},\r
+ {0x5086, 0x02},\r
+ {0x5000, 0xfb},\r
+ {0x5001, 0x1f},\r
+ {0x5002, 0x00},\r
+ {0x5025, 0x0e},\r
+ {0x5026, 0x18},\r
+ {0x5027, 0x34},\r
+ {0x5028, 0x4c},\r
+ {0x5029, 0x62},\r
+ {0x502a, 0x74},\r
+ {0x502b, 0x85},\r
+ {0x502c, 0x92},\r
+ {0x502d, 0x9e},\r
+ {0x502e, 0xb2},\r
+ {0x502f, 0xc0},\r
+ {0x5030, 0xcc},\r
+ {0x5031, 0xe0},\r
+ {0x5032, 0xee},\r
+ {0x5033, 0xf6},\r
+ {0x5034, 0x11},\r
+ {0x5070, 0x1c},\r
+ {0x5071, 0x5b},\r
+ {0x5072, 0x05},\r
+ {0x5073, 0x20},\r
+ {0x5074, 0x94},\r
+ {0x5075, 0xb4},\r
+ {0x5076, 0xb4},\r
+ {0x5077, 0xaf},\r
+ {0x5078, 0x05},\r
+ {0x5079, 0x98},\r
+ {0x507a, 0x21},\r
+ {0x5035, 0x6a},\r
+ {0x5036, 0x11},\r
+ {0x5037, 0x92},\r
+ {0x5038, 0x21},\r
+ \r
+ {0x5039, 0xe1},\r
+ {0x503a, 0x01},\r
+ {0x503c, 0x05},\r
+ {0x503d, 0x08},\r
+ {0x503e, 0x08},\r
+ {0x503f, 0x64},\r
+ {0x5040, 0x58},\r
+ {0x5041, 0x2a},\r
+ {0x5042, 0xc5},\r
+ {0x5043, 0x2e},\r
+ {0x5044, 0x3a},\r
+ {0x5045, 0x3c},\r
+ {0x5046, 0x44},\r
+ {0x5047, 0xf8},\r
+ {0x5048, 0x08},\r
+ {0x5049, 0x70},\r
+ {0x504a, 0xf0},\r
+ {0x504b, 0xf0},\r
+ {0x500c, 0x03},\r
+ {0x500d, 0x20},\r
+ {0x500e, 0x02},\r
+ {0x500f, 0x5c},\r
+ {0x5010, 0x48},\r
+ {0x5011, 0x00},\r
+ {0x5012, 0x66},\r
+ {0x5013, 0x03},\r
+ {0x5014, 0x30},\r
+ {0x5015, 0x02},\r
+ {0x5016, 0x7c},\r
+ {0x5017, 0x40},\r
+ {0x5018, 0x00},\r
+ {0x5019, 0x66},\r
+ {0x501a, 0x03},\r
+ {0x501b, 0x10},\r
+ {0x501c, 0x02},\r
+ {0x501d, 0x7c},\r
+ {0x501e, 0x3a},\r
+ {0x501f, 0x00},\r
+ {0x5020, 0x66},\r
+ {0x506e, 0x44},\r
+ {0x5064, 0x08},\r
+ {0x5065, 0x10},\r
+ {0x5066, 0x12},\r
+ {0x5067, 0x02},\r
+ {0x506c, 0x08},\r
+ {0x506d, 0x10},\r
+ {0x506f, 0xa6},\r
+ {0x5068, 0x08},\r
+ \r
+ \r
+ {0x5069, 0x10},\r
+ {0x506a, 0x04},\r
+ {0x506b, 0x12},\r
+ {0x507e, 0x40},\r
+ {0x507f, 0x20},\r
+ {0x507b, 0x02},\r
+ {0x507a, 0x01},\r
+ {0x5084, 0x0c},\r
+ {0x5085, 0x3e},\r
+ {0x5005, 0x80},\r
+ {0x3a0f, 0x30},\r
+ {0x3a10, 0x28},\r
+ {0x3a1b, 0x32},\r
+ {0x3a1e, 0x26},\r
+ {0x3a11, 0x60},\r
+ {0x3a1f, 0x14},\r
+ {0x5060, 0x69},\r
+ {0x5061, 0x7d},\r
+ {0x5062, 0x7d},\r
+ {0x5063, 0x69},\r
+ {0x3004, 0x20},\r
+ {0x0100, 0x01},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+\r
+ {0x3503,0x03}, \r
+ {0x506e,0x44}, \r
+ {0x5064,0x08}, \r
+ {0x5065,0x10},\r
+ {0x5066,0x18}, // zenghaihui 20110920 16\r
+ {0x5067,0x10},\r
+ {0x506c,0x08},\r
+ {0x506d,0x10}, \r
+ {0x506f,0xa6}, \r
+ {0x5068,0x08},\r
+ {0x5069,0x10}, \r
+ {0x506a,0x08},\r
+ {0x506b,0x28},\r
+ {0x5084,0x14},//0c\r
+ {0x5085,0x3c},//34 \r
+ {0x5005,0x80}, \r
+\r
+\r
+\r
+ {0x5066, 0x3c}, \r
+ {0x5067, 0x1a}, \r
+ {0x506a, 0x0e}, \r
+ {0x506b, 0x2e}, \r
+\r
+ {0x3800, 0x00}, \r
+ {0x3801, 0x00}, \r
+ {0x3802, 0x00}, \r
+ {0x3803, 0x00}, \r
+ {0x3804, 0x06}, \r
+ {0x3805, 0x5f}, \r
+ {0x3806, 0x04}, \r
+ {0x3807, 0xbb}, \r
+ {0x3808, 0x06}, \r
+ {0x3809, 0x40}, \r
+ {0x380a, 0x04}, \r
+ {0x380b, 0xb0}, \r
+ {0x3811, 0x10}, \r
+ {0x3813, 0x06}, \r
+ {0x3814, 0x11}, \r
+ {0x3815, 0x11}, \r
+\r
+ {0x3623, 0x00}, \r
+ {0x3634, 0x44}, \r
+ {0x3701, 0x44}, \r
+ {0x3208, 0xa2}, \r
+ {0x3705, 0x18}, \r
+ {0x3820, 0x80}, \r
+ {0x3821, 0x00}, \r
+\r
+ {0x3003, 0x80},//10fps \r
+ {0x3004, 0x20}, //10 \r
+ {0x3005, 0x18}, \r
+ {0x3006, 0x0d}, \r
+\r
+ {0x380c, 0x07}, \r
+ {0x380d, 0x9f}, \r
+ {0x380e, 0x04}, \r
+ {0x380f, 0xd0}, \r
+\r
+ {0x370a, 0x12}, \r
+ {0x4608, 0x00}, \r
+ {0x4609, 0x80}, \r
+ {0x5002, 0x00}, \r
+\r
+ {0x3a08, 0x00}, \r
+ {0x3a09, 0x3e},//7b \r
+ {0x3a0e, 0x13},//0a \r
+\r
+ {0x3a0a, 0x00}, \r
+ {0x3a0b, 0x3e},//7b \r
+ {0x3a0d, 0x13},//0a \r
+\r
+ {0x4003, 0x88},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x0100, 0x00}, //software sleep : Sensor vsync singal may not output if haven't sleep the sensor when transfer the array,\r
+ {0x3800, 0x00},\r
+ {0x3801, 0x00},\r
+ {0x3802, 0x00},\r
+ {0x3803, 0x00},\r
+ {0x3804, 0x06},\r
+ {0x3805, 0x5f},\r
+ {0x3806, 0x04},\r
+ {0x3807, 0xb7},\r
+ {0x3808, 0x03},\r
+ {0x3809, 0x20},\r
+ {0x380a, 0x02},\r
+ {0x380b, 0x58},\r
+ {0x380c, 0x05},\r
+ {0x380d, 0x14},\r
+ {0x380e, 0x02},\r
+ {0x380f, 0x68},\r
+ {0x3811, 0x08},\r
+ {0x3813, 0x02},\r
+ {0x3814, 0x31},\r
+ {0x3815, 0x31},\r
+ {0x3a02, 0x02},\r
+ {0x3a03, 0x68},\r
+ {0x3a08, 0x00},\r
+ {0x3a09, 0x5c},\r
+ {0x3a0a, 0x00},\r
+ {0x3a0b, 0x4d},\r
+ {0x3a0d, 0x08},\r
+ {0x3a0e, 0x06},\r
+ {0x3a14, 0x02},\r
+ {0x3a15, 0x28},\r
+ {0x3623, 0x00},\r
+ {0x3634, 0x76},\r
+ {0x3701, 0x44},\r
+ {0x3702, 0x18},\r
+ {0x3703, 0x24},\r
+ {0x3704, 0x24},\r
+ {0x3705, 0x0c},\r
+ //{0x3820, 0x81},\r
+ //{0x3821, 0x01},\r
+ {0x370a, 0x52},\r
+ {0x4608, 0x00},\r
+ {0x4609, 0x80},\r
+ {0x5002, 0x10},\r
+ {0x3005, 0x18},\r
+ {0x3004, 0x20},\r
+ {0x3503,0x00},\r
+ {0x0100, 0x01}, //software wake\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x0103,0x01),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x300a,0),\r
+ SensorRegVal(0x300b,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x3406, 0x00}, //AWB auto, bit[1]:0,auto\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x3406, 0x01},\r
+ {0x3400, 0x07},\r
+ {0x3401, 0x08},\r
+ {0x3402, 0x04},\r
+ {0x3403, 0x00},\r
+ {0x3404, 0x05},\r
+ {0x3405, 0x00},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ //Sunny\r
+ {0x3406, 0x01},\r
+ {0x3400, 0x07},\r
+ {0x3401, 0x02},\r
+ {0x3402, 0x04},\r
+ {0x3403, 0x00},\r
+ {0x3404, 0x05},\r
+ {0x3405, 0x15},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x3406, 0x01},\r
+ {0x3400, 0x06},\r
+ {0x3401, 0x2a},\r
+ {0x3402, 0x04},\r
+ {0x3403, 0x00},\r
+ {0x3404, 0x07},\r
+ {0x3405, 0x24},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x3406, 0x01},\r
+ {0x3400, 0x04},\r
+ {0x3401, 0x58},\r
+ {0x3402, 0x04},\r
+ {0x3403, 0x00},\r
+ {0x3404, 0x07},\r
+ {0x3405, 0x24},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x507b, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x507b, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x507b, 0x18},\r
+ {0x507e, 0x40},\r
+ {0x507f, 0xa0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x507b, 0x40}, //bit[6] negative\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x507b, 0x18},\r
+ {0x507e, 0xa0},\r
+ {0x507f, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x507b, 0x18},\r
+ {0x507e, 0x60},\r
+ {0x507f, 0x60},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0x3a00, 0x78},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ {0x3003, 0x80},\r
+ {0x3004, 0x20},\r
+ {0x3005, 0x18},\r
+ {0x3006, 0x0d},\r
+ {0x3a00, 0x7c},\r
+ {0x3a02 ,0x07},\r
+ {0x3a03 ,0x38},\r
+ {0x3a14 ,0x07},\r
+ {0x3a15 ,0x38},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+static int sensor_parameter_record(struct i2c_client *client)\r
+{\r
+ u8 ret_l,ret_m,ret_h;\r
+ int tp_l,tp_m,tp_h;\r
+ \r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+\r
+ sensor_read(client,0x3a00, &ret_l);\r
+ sensor_write(client,0x3a00, ret_l&0xfb);\r
+\r
+ sensor_write(client,0x3503,0x07); //stop AE/AG\r
+\r
+ sensor_read(client,0x3500,&ret_h);\r
+ sensor_read(client,0x3501, &ret_m);\r
+ sensor_read(client,0x3502, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_m = ret_m;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F);\r
+ \r
+ //Read back AGC Gain for preview\r
+ sensor_read(client,0x350b, &ret_l);\r
+ spsensor->parameter.preview_gain = ret_l;\r
+\r
+ spsensor->parameter.CapturePclk = 24000;\r
+ spsensor->parameter.PreviewPclk = 24000;\r
+ spsensor->parameter.PreviewDummyPixels = 0;\r
+ spsensor->parameter.CaptureDummyPixels = 0;\r
+ SENSOR_DG("Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x",\r
+ ret_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l);\r
+ return 0;\r
+}\r
+#define OV2659_FULL_PERIOD_PIXEL_NUMS (1940) // default pixel#(w/o dummy pixels) in UXGA mode\r
+#define OV2659_FULL_PERIOD_LINE_NUMS (1238) // default line#(w/o dummy lines) in UXGA mode\r
+#define OV2659_PV_PERIOD_PIXEL_NUMS (970) // default pixel#(w/o dummy pixels) in SVGA mode\r
+#define OV2659_PV_PERIOD_LINE_NUMS (618) // default line#(w/o dummy lines) in SVGA mode\r
+\r
+/* SENSOR EXPOSURE LINE LIMITATION */\r
+#define OV2659_FULL_EXPOSURE_LIMITATION (1236)\r
+#define OV2659_PV_EXPOSURE_LIMITATION (618)\r
+\r
+// SENSOR UXGA SIZE\r
+#define OV2659_IMAGE_SENSOR_FULL_WIDTH (1600)\r
+#define OV2659_IMAGE_SENSOR_FULL_HEIGHT (1200)\r
+\r
+#define OV2659_FULL_GRAB_WIDTH (OV2659_IMAGE_SENSOR_FULL_WIDTH - 16)\r
+#define OV2659_FULL_GRAB_HEIGHT (OV2659_IMAGE_SENSOR_FULL_HEIGHT - 12)\r
+static void OV2659SetDummy(struct i2c_client *client,unsigned int dummy_pixels, unsigned int dummy_lines)\r
+{\r
+ unsigned char val;\r
+ unsigned int temp_reg1, temp_reg2;\r
+ unsigned int temp_reg;\r
+ \r
+ if (dummy_pixels > 0)\r
+ {\r
+ sensor_read(client,0x380D,&val); // HTS[b7~b0]\r
+ temp_reg1 = val;\r
+ sensor_read(client,0x380C,&val); // HTS[b15~b8]\r
+ temp_reg2 = val;\r
+ temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8);\r
+ \r
+ temp_reg += dummy_pixels;\r
+ \r
+ sensor_write(client,0x380D,(temp_reg&0xFF)); //HTS[7:0]\r
+ sensor_write(client,0x380C,((temp_reg&0xFF00)>>8)); //HTS[15:8]\r
+ }\r
+\r
+ if (dummy_lines > 0)\r
+ {\r
+ sensor_read(client,0x380F,&val); // VTS[b7~b0]\r
+ temp_reg1 = val;\r
+ sensor_read(client,0x380E,&val); // VTS[b15~b8]\r
+ temp_reg2 = val;\r
+ temp_reg = (temp_reg1 & 0xFF) | (temp_reg2 << 8);\r
+ \r
+ temp_reg += dummy_lines;\r
+ \r
+ sensor_write(client,0x380F,(temp_reg&0xFF)); //VTS[7:0]\r
+ sensor_write(client,0x380E,((temp_reg&0xFF00)>>8)); //VTS[15:8]\r
+ }\r
+} /* OV2659_set_dummy */\r
+\r
+static void OV2659WriteShutter(struct i2c_client *client,bool is_preview, unsigned int shutter)\r
+{\r
+ unsigned int extra_exposure_lines = 0;\r
+\r
+ if (shutter < 1)\r
+ {\r
+ shutter = 1;\r
+ }\r
+ \r
+ if (is_preview) \r
+ {\r
+ if (shutter <= OV2659_PV_EXPOSURE_LIMITATION) \r
+ {\r
+ extra_exposure_lines = 0;\r
+ }\r
+ else \r
+ {\r
+ extra_exposure_lines=shutter - OV2659_PV_EXPOSURE_LIMITATION;\r
+ }\r
+ \r
+ }\r
+ else \r
+ {\r
+ if (shutter <= OV2659_FULL_EXPOSURE_LIMITATION) \r
+ {\r
+ extra_exposure_lines = 0;\r
+ }\r
+ else \r
+ {\r
+ extra_exposure_lines = shutter - OV2659_FULL_EXPOSURE_LIMITATION;\r
+ }\r
+ \r
+ }\r
+ \r
+ //AEC PK EXPOSURE\r
+ shutter*=16;\r
+ sensor_write(client,0x3502, (shutter & 0x00FF)); //AEC[7:0]\r
+ sensor_write(client,0x3501, ((shutter & 0x0FF00) >>8)); //AEC[15:8]\r
+ sensor_write(client,0x3500, ((shutter & 0xFF0000) >> 16)); \r
+ \r
+ if(extra_exposure_lines>0)\r
+ {\r
+ // set extra exposure line [aec add vts]\r
+ sensor_write(client,0x3507, extra_exposure_lines & 0xFF); // EXVTS[b7~b0]\r
+ sensor_write(client,0x3506, (extra_exposure_lines & 0xFF00) >> 8); // EXVTS[b15~b8]\r
+ }\r
+ else\r
+ {\r
+ // set extra exposure line [aec add vts]\r
+ sensor_write(client,0x3507, 0x00); // EXVTS[b7~b0]\r
+ sensor_write(client,0x3506, 0x00); // EXVTS[b15~b8]\r
+ }\r
+ \r
+} /* OV2659_write_shutter */\r
+static int sensor_ae_transfer(struct i2c_client *client)\r
+{\r
+ unsigned int prev_line_len,cap_line_len,shutter;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+\r
+ mdelay(100);\r
+ shutter = spsensor->parameter.preview_exposure;\r
+\r
+ OV2659SetDummy(client,600,0); \r
+ \r
+ prev_line_len = OV2659_PV_PERIOD_PIXEL_NUMS + spsensor->parameter.PreviewDummyPixels;\r
+ cap_line_len = OV2659_FULL_PERIOD_PIXEL_NUMS + spsensor->parameter.CaptureDummyPixels;\r
+ shutter = (shutter * spsensor->parameter.CapturePclk) / spsensor->parameter.PreviewPclk;\r
+ shutter = (shutter * prev_line_len) / cap_line_len;\r
+ shutter*=2;\r
+\r
+ OV2659WriteShutter(client,0,shutter);\r
+ \r
+ \r
+ return 0;\r
+}\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ sensor_read(client,0x3000,®_val);\r
+ sensor_write(client, 0x3000, reg_val|0x03);\r
+ sensor_write(client, 0x3001, 0xff);\r
+ sensor_read(client,0x3002,®_val);\r
+ sensor_write(client, 0x3002, reg_val|0xe0);\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ u8 reg_val;\r
+ struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ /* ddl@rock-chips.com : all sensor output pin must switch into Hi-Z */\r
+ if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) {\r
+ sensor_read(client,0x3000,®_val);\r
+ sensor_write(client, 0x3000, reg_val&0xfc);\r
+ sensor_write(client, 0x3001, 0x00);\r
+ sensor_read(client,0x3002,®_val);\r
+ sensor_write(client, 0x3002, reg_val&0x1f);\r
+ }\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ sensor_parameter_record(client);\r
+ }\r
+\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ if (capture) {\r
+ sensor_ae_transfer(client);\r
+ }\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ char val;\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ if (mirror) {\r
+ err = sensor_read(client, 0x3821, &val);\r
+ if (err == 0) {\r
+ val |= 0x06;\r
+ err = sensor_write(client, 0x3821, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3821, &val);\r
+ if (err == 0) {\r
+ val &= 0xf9;\r
+ err = sensor_write(client, 0x3821, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ char val;\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ if (flip) {\r
+ err = sensor_read(client, 0x3820, &val);\r
+ if (err == 0) {\r
+ val |= 0x06;\r
+ err = sensor_write(client, 0x3820, val);\r
+ }\r
+ } else {\r
+ err = sensor_read(client, 0x3820, &val);\r
+ if (err == 0) {\r
+ val &= 0xf9;\r
+ err = sensor_write(client, 0x3820, val);\r
+ }\r
+ }\r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
--- /dev/null
+/*
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+#include <linux/vmalloc.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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char value;
+ int ret,pid = 0;
+ struct sensor *sensor = to_sensor(client);
+
+ /* We must have a parent by now. And it cannot be a wrong one.
+ * So this entire test is completely redundant. */
+ if (!icd->dev.parent ||
+ to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
+ return -ENODEV;
+
+ if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+ 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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
+ #include "generic_sensor.h"\r
+\r
/*
- * Driver for OV5640 CMOS Image Sensor from OmniVision
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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<<i)) {
- if (sensor_write(client, CMD_PARA0_Reg+i, cmdinfo->cmd_para[i])) {
- SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
- goto sensor_af_cmdset_err;
- }
- SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
- }
- }
-
- 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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
-
-
+* Driver Version Note\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,1,0);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug >= level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_OV5640\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_OV5640\r
+#define SENSOR_ID 0x5640\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_LOW|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 30000\r
+#define SENSOR_1080P_FPS 15000\r
+\r
+#define SENSOR_REGISTER_LEN 2 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+ \r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect\r
+ |CFG_Scene|CFG_Focus\r
+ |CFG_FocusZone);\r
+\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+#if 1//CONFIG_SENSOR_Focus\r
+#include "ov5640_af_firmware.c"\r
+/* ov5640 VCM Command and Status Registers */\r
+#define CONFIG_SENSOR_FocusCenterInCapture 0\r
+#define CMD_MAIN_Reg 0x3022\r
+//#define CMD_TAG_Reg 0x3023\r
+#define CMD_ACK_Reg 0x3023\r
+#define CMD_PARA0_Reg 0x3024\r
+#define CMD_PARA1_Reg 0x3025\r
+#define CMD_PARA2_Reg 0x3026\r
+#define CMD_PARA3_Reg 0x3027\r
+#define CMD_PARA4_Reg 0x3028\r
+\r
+//#define STA_ZONE_Reg 0x3026\r
+#define STA_FOCUS_Reg 0x3029\r
+\r
+/* ov5640 VCM Command */\r
+\r
+#define ConstFocus_Cmd 0x04\r
+#define StepMode_Cmd 0x05\r
+#define PauseFocus_Cmd 0x06\r
+#define ReturnIdle_Cmd 0x08\r
+#define SetZone_Cmd 0x10\r
+#define UpdateZone_Cmd 0x12\r
+#define SetMotor_Cmd 0x20\r
+#define SingleFocus_Cmd 0x03\r
+#define GetFocusResult_Cmd 0x07\r
+#define ReleaseFocus_Cmd 0x08\r
+#define ZoneRelaunch_Cmd 0x12\r
+#define DefaultZoneConfig_Cmd 0x80\r
+#define TouchZoneConfig_Cmd 0x81\r
+#define CustomZoneConfig_Cmd 0x8f\r
+\r
+\r
+/* ov5640 Focus State */\r
+//#define S_FIRWRE 0xFF /*Firmware is downloaded and not run*/\r
+#define S_STARTUP 0x7e /*Firmware is initializing*/\r
+#define S_ERROR 0x7f\r
+#define S_IDLE 0x70 /*Idle state, focus is released; lens is located at the furthest position.*/\r
+#define S_FOCUSING 0x00 /*Auto Focus is running.*/\r
+#define S_FOCUSED 0x10 /*Auto Focus is completed.*/\r
+\r
+#define S_CAPTURE 0x12\r
+#define S_STEP 0x20\r
+\r
+/* ov5640 Zone State */\r
+#define Zone_Is_Focused(a, zone_val) (zone_val&(1<<(a-3)))\r
+#define Zone_Get_ID(zone_val) (zone_val&0x03)\r
+\r
+#define Zone_CenterMode 0x01\r
+#define Zone_5xMode 0x02\r
+#define Zone_5PlusMode 0x03\r
+#define Zone_4fMode 0x04\r
+\r
+#define ZoneSel_Auto 0x0b\r
+#define ZoneSel_SemiAuto 0x0c\r
+#define ZoneSel_Manual 0x0d\r
+#define ZoneSel_Rotate 0x0e\r
+\r
+/* ov5640 Step Focus Commands */\r
+#define StepFocus_Near_Tag 0x01\r
+#define StepFocus_Far_Tag 0x02\r
+#define StepFocus_Furthest_Tag 0x03\r
+#define StepFocus_Nearest_Tag 0x04\r
+#define StepFocus_Spec_Tag 0x10\r
+#endif\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+ unsigned short int preview_maxlines;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] ={\r
+ {0x3103, 0x11},\r
+ {0x3008, 0x82},\r
+ SensorWaitMs(5),\r
+ {0x3008, 0x42},\r
+ {0x3103, 0x03},\r
+ {0x3017, 0xff},\r
+ {0x3018, 0xff},\r
+ {0x3034, 0x1a},\r
+ {0x3035, 0x21},\r
+ {0x3036, 0x46},\r
+ {0x3037, 0x12},\r
+ {0x3108, 0x01},\r
+ {0x3630, 0x36},\r
+ {0x3631, 0x0e},\r
+ {0x3632, 0xe2},\r
+ {0x3633, 0x12},\r
+ {0x3621, 0xe0},\r
+ {0x3704, 0xa0},\r
+ {0x3703, 0x5a},\r
+ {0x3715, 0x78},\r
+ {0x3717, 0x01},\r
+ {0x370b, 0x60},\r
+ {0x3705, 0x1a},\r
+ {0x3905, 0x02},\r
+ {0x3906, 0x10},\r
+ {0x3901, 0x0a},\r
+ {0x3731, 0x12},\r
+ {0x3600, 0x08},\r
+ {0x3601, 0x33},\r
+ {0x302d, 0x60},\r
+ {0x3620, 0x52},\r
+ {0x371b, 0x20},\r
+ {0x471c, 0x50},\r
+ {0x3a13, 0x43},\r
+ {0x3a18, 0x00},\r
+ {0x3a19, 0xf8},\r
+ {0x3635, 0x13},\r
+ {0x3636, 0x03},\r
+ {0x3634, 0x40},\r
+ {0x3622, 0x01},\r
+ {0x3c01, 0x34},\r
+ {0x3c04, 0x28},\r
+ {0x3c05, 0x98},\r
+ {0x3c06, 0x00},\r
+ {0x3c07, 0x08},\r
+ {0x3c08, 0x00},\r
+ {0x3c09, 0x1c},\r
+ {0x3c0a, 0x9c},\r
+ {0x3c0b, 0x40},\r
+ {0x3820, 0x41},\r
+ {0x3821, 0x07},\r
+ {0x3814, 0x31},\r
+ {0x3815, 0x31},\r
+ {0x3800, 0x00},\r
+ {0x3801, 0x00},\r
+ {0x3802, 0x00},\r
+ {0x3803, 0x04},\r
+ {0x3804, 0x0a},\r
+ {0x3805, 0x3f},\r
+ {0x3806, 0x07},\r
+ {0x3807, 0x9b},\r
+ {0x3808, 0x03},\r
+ {0x3809, 0x20},\r
+ {0x380a, 0x02},\r
+ {0x380b, 0x58},\r
+ {0x380c, 0x07},\r
+ {0x380d, 0x68},\r
+ {0x380e, 0x03},\r
+ {0x380f, 0xd8},\r
+ {0x3810, 0x00},\r
+ {0x3811, 0x10},\r
+ {0x3812, 0x00},\r
+ {0x3813, 0x06},\r
+ {0x3618, 0x00},\r
+ {0x3612, 0x29},\r
+ {0x3708, 0x64},\r
+ {0x3709, 0x52},\r
+ {0x370c, 0x03},\r
+ {0x3a02, 0x03},\r
+ {0x3a03, 0xd8},\r
+ {0x3a08, 0x01},\r
+ {0x3a09, 0x27},\r
+ {0x3a0a, 0x00},\r
+ {0x3a0b, 0xf6},\r
+ {0x3a0e, 0x03},\r
+ {0x3a0d, 0x04},\r
+ {0x3a14, 0x03},\r
+ {0x3a15, 0xd8},\r
+ {0x4001, 0x02},\r
+ {0x4004, 0x02},\r
+ {0x3000, 0x00},\r
+ {0x3002, 0x1c},\r
+ {0x3004, 0xff},\r
+ {0x3006, 0xc3},\r
+ {0x300e, 0x58},\r
+ {0x302e, 0x00},\r
+ {0x4740, 0x20},\r
+ {0x4300, 0x32},//uyvy:0x32,yuyv:0x30\r
+ {0x501f, 0x00},\r
+ {0x4713, 0x03},\r
+ {0x4407, 0x04},\r
+ {0x440e, 0x00},\r
+ {0x460b, 0x35},\r
+ {0x460c, 0x20},\r
+ {0x4837, 0x22},\r
+ {0x3824, 0x02},\r
+ {0x5000, 0xa7},\r
+ {0x5001, 0xa3},\r
+ {0x5180, 0xff},\r
+ {0x5181, 0xf2},\r
+ {0x5182, 0x00},\r
+ {0x5183, 0x14},\r
+ {0x5184, 0x25},\r
+ {0x5185, 0x24},\r
+ {0x5186, 0x09},\r
+ {0x5187, 0x09},\r
+ {0x5188, 0x09},\r
+ {0x5189, 0x75},\r
+ {0x518a, 0x54},\r
+ {0x518b, 0xe0},\r
+ {0x518c, 0xb2},\r
+ {0x518d, 0x42},\r
+ {0x518e, 0x3d},\r
+ {0x518f, 0x56},\r
+ {0x5190, 0x46},\r
+ {0x5191, 0xf8},\r
+ {0x5192, 0x04},\r
+ {0x5193, 0x70},\r
+ {0x5194, 0xf0},\r
+ {0x5195, 0xf0},\r
+ {0x5196, 0x03},\r
+ {0x5197, 0x01},\r
+ {0x5198, 0x04},\r
+ {0x5199, 0x12},\r
+ {0x519a, 0x04},\r
+ {0x519b, 0x00},\r
+ {0x519c, 0x06},\r
+ {0x519d, 0x82},\r
+ {0x519e, 0x38},\r
+ {0x5381, 0x1e},\r
+ {0x5382, 0x5b},\r
+ {0x5383, 0x08},\r
+ {0x5384, 0x0a},\r
+ {0x5385, 0x7e},\r
+ {0x5386, 0x88},\r
+ {0x5387, 0x7c},\r
+ {0x5388, 0x6c},\r
+ {0x5389, 0x10},\r
+ {0x538a, 0x01},\r
+ {0x538b, 0x98},\r
+ {0x5300, 0x08},\r
+ {0x5301, 0x30},\r
+ {0x5302, 0x10},\r
+ {0x5303, 0x00},\r
+ {0x5304, 0x08},\r
+ {0x5305, 0x30},\r
+ {0x5306, 0x08},\r
+ {0x5307, 0x16},\r
+ {0x5309, 0x08},\r
+ {0x530a, 0x30},\r
+ {0x530b, 0x04},\r
+ {0x530c, 0x06},\r
+ {0x5480, 0x01},\r
+ {0x5481, 0x08},\r
+ {0x5482, 0x14},\r
+ {0x5483, 0x28},\r
+ {0x5484, 0x51},\r
+ {0x5485, 0x65},\r
+ {0x5486, 0x71},\r
+ {0x5487, 0x7d},\r
+ {0x5488, 0x87},\r
+ {0x5489, 0x91},\r
+ {0x548a, 0x9a},\r
+ {0x548b, 0xaa},\r
+ {0x548c, 0xb8},\r
+ {0x548d, 0xcd},\r
+ {0x548e, 0xdd},\r
+ {0x548f, 0xea},\r
+ {0x5490, 0x1d},\r
+ {0x5580, 0x02},\r
+ {0x5583, 0x40},\r
+ {0x5584, 0x10},\r
+ {0x5589, 0x10},\r
+ {0x558a, 0x00},\r
+ {0x558b, 0xf8},\r
+ {0x5800, 0x23},\r
+ {0x5801, 0x14},\r
+ {0x5802, 0x0f},\r
+ {0x5803, 0x0f},\r
+ {0x5804, 0x12},\r
+ {0x5805, 0x26},\r
+ {0x5806, 0x0c},\r
+ {0x5807, 0x08},\r
+ {0x5808, 0x05},\r
+ {0x5809, 0x05},\r
+ {0x580a, 0x08},\r
+ {0x580b, 0x0d},\r
+ {0x580c, 0x08},\r
+ {0x580d, 0x03},\r
+ {0x580e, 0x00},\r
+ {0x580f, 0x00},\r
+ {0x5810, 0x03},\r
+ {0x5811, 0x09},\r
+ {0x5812, 0x07},\r
+ {0x5813, 0x03},\r
+ {0x5814, 0x00},\r
+ {0x5815, 0x01},\r
+ {0x5816, 0x03},\r
+ {0x5817, 0x08},\r
+ {0x5818, 0x0d},\r
+ {0x5819, 0x08},\r
+ {0x581a, 0x05},\r
+ {0x581b, 0x06},\r
+ {0x581c, 0x08},\r
+ {0x581d, 0x0e},\r
+ {0x581e, 0x29},\r
+ {0x581f, 0x17},\r
+ {0x5820, 0x11},\r
+ {0x5821, 0x11},\r
+ {0x5822, 0x15},\r
+ {0x5823, 0x28},\r
+ {0x5824, 0x46},\r
+ {0x5825, 0x26},\r
+ {0x5826, 0x08},\r
+ {0x5827, 0x26},\r
+ {0x5828, 0x64},\r
+ {0x5829, 0x26},\r
+ {0x582a, 0x24},\r
+ {0x582b, 0x22},\r
+ {0x582c, 0x24},\r
+ {0x582d, 0x24},\r
+ {0x582e, 0x06},\r
+ {0x582f, 0x22},\r
+ {0x5830, 0x40},\r
+ {0x5831, 0x42},\r
+ {0x5832, 0x24},\r
+ {0x5833, 0x26},\r
+ {0x5834, 0x24},\r
+ {0x5835, 0x22},\r
+ {0x5836, 0x22},\r
+ {0x5837, 0x26},\r
+ {0x5838, 0x44},\r
+ {0x5839, 0x24},\r
+ {0x583a, 0x26},\r
+ {0x583b, 0x28},\r
+ {0x583c, 0x42},\r
+ {0x583d, 0xce},\r
+ {0x5025, 0x00},\r
+ {0x3a0f, 0x30},\r
+ {0x3a10, 0x28},\r
+ {0x3a1b, 0x30},\r
+ {0x3a1e, 0x26},\r
+ {0x3a11, 0x60},\r
+ {0x3a1f, 0x14},\r
+ {0x3008, 0x02},\r
+ {0x302c, 0xc2},\r
+ SensorWaitUs(1000),\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+\r
+ {0x3820, 0x40}, \r
+ {0x3821, 0x06}, \r
+ {0x3814, 0x11}, \r
+ {0x3815, 0x11}, \r
+ {0x3803, 0x00}, \r
+ {0x3807, 0x9f}, \r
+ {0x3808, 0x0a}, \r
+ {0x3809, 0x20}, \r
+ {0x380a, 0x07}, \r
+ {0x380b, 0x98}, \r
+ {0x380c, 0x0b}, \r
+ {0x380d, 0x1c}, \r
+ {0x380e, 0x07}, \r
+ {0x380f, 0xb0}, \r
+ {0x3811, 0x10}, //\r
+ {0x3813, 0x04}, \r
+ {0x3618, 0x04}, \r
+ {0x3612, 0x2b}, //4b \r
+ {0x3708, 0x64},\r
+ {0x3709, 0x12}, \r
+ {0x370c, 0x00}, \r
+ {0x3a02, 0x07}, \r
+ {0x3a03, 0xb0}, \r
+ {0x3a0e, 0x06}, \r
+ {0x3a0d, 0x08}, \r
+ {0x3a14, 0x07}, \r
+ {0x3a15, 0xb0}, \r
+ {0x4004, 0x06},\r
+ {0x5000, 0xa7}, \r
+ {0x5001, 0x83},\r
+ {0x519e, 0x38},\r
+ {0x5381, 0x1e},\r
+ {0x5382, 0x5b},\r
+ {0x5383, 0x08},\r
+ {0x460b, 0x37}, \r
+ {0x460c, 0x20}, \r
+ {0x3824, 0x01}, \r
+ {0x4005, 0x1A}, \r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0x3503, 0x00},\r
+ {0x3c07, 0x08},\r
+ {0x3820, 0x41},\r
+ {0x3821, 0x07},\r
+ {0x3814, 0x31},\r
+ {0x3815, 0x31},\r
+ {0x3803, 0x04},\r
+ {0x3806, 0x07},///\r
+ {0x3807, 0x9b},\r
+ {0x3808, 0x03},\r
+ {0x3809, 0x20},\r
+ {0x380a, 0x02},\r
+ {0x380b, 0x58},\r
+ {0x380c, 0x07},\r
+ {0x380d, 0x68},\r
+ {0x380e, 0x03},\r
+ {0x380f, 0xd8},\r
+ {0x3813, 0x06},\r
+ {0x3618, 0x00},\r
+ {0x3612, 0x29},\r
+ {0x3709, 0x52},\r
+ {0x370c, 0x03},\r
+ {0x3a02, 0x03},\r
+ {0x3a03, 0xd8},\r
+ {0x3a08 ,0x01},///\r
+ {0x3a09, 0x27},///\r
+ {0x3a0a, 0x00},///\r
+ {0x3a0b, 0xf6},///\r
+ {0x3a0e, 0x03},\r
+ {0x3a0d, 0x04},\r
+ {0x3a14, 0x03},\r
+ {0x3a15, 0xd8},\r
+ {0x4004, 0x02},\r
+ {0x3002, 0x1c},////\r
+ {0x4713, 0x03},////\r
+ {0x3035, 0x21},\r
+ {0x3036, 0x46},\r
+ {0x4837, 0x22},\r
+ {0x3824, 0x02},////\r
+ {0x5001, 0xa3},\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ {0x3503, 0x00},\r
+ \r
+ {0x3c07,0x07},\r
+ {0x3803,0xfa},\r
+ {0x3806,0x06},////\r
+ {0x3807,0xa9},\r
+ {0x3808,0x05},\r
+ {0x3809,0x00},\r
+ {0x380a,0x02},\r
+ {0x380b,0xd0},\r
+ {0x380c,0x07},\r
+ {0x380d,0x64},\r
+ {0x380e,0x02},\r
+ {0x380f,0xe4},\r
+ {0x3813,0x04},\r
+ {0x3a02,0x02},\r
+ {0x3a03,0xe4},\r
+ {0x3a08,0x01},///\r
+ {0x3a09,0xbc},////\r
+ {0x3a0a,0x01},///\r
+ {0x3a0b,0x72},////\r
+ {0x3a0e,0x01},\r
+ {0x3a0d,0x02},\r
+ {0x3a14,0x02},\r
+ {0x3a15,0xe4},\r
+ \r
+ {0x3820, 0x41}, //ddl@rock-chips.com add start: qsxvga -> 720p isn't stream on \r
+ {0x3821, 0x07},\r
+ {0x3814, 0x31},\r
+ {0x3815, 0x31},\r
+ \r
+ {0x3618, 0x00},\r
+ {0x3612, 0x29},\r
+ {0x3709, 0x52},\r
+ {0x370c, 0x03},\r
+ {0x3a02, 0x03},\r
+ {0x3a03, 0xd8},\r
+ {0x3a08 ,0x01},///\r
+ {0x3a09, 0x27},///\r
+ {0x3a0a, 0x00},///\r
+ {0x3a0b, 0xf6},///\r
+ {0x3a0e, 0x03},\r
+ {0x3a0d, 0x04},\r
+ {0x3a14, 0x03},\r
+ {0x3a15, 0xd8},\r
+ {0x4004, 0x02},\r
+ {0x3002, 0x1c},////\r
+ {0x4713, 0x03},//////ddl@rock-chips.com add end\r
+ \r
+ {0x3002,0x00},///\r
+ {0x4713,0x02},///\r
+ {0x4837,0x16},\r
+ {0x3824,0x04},///\r
+ {0x5001,0x83},\r
+ {0x3035,0x21},\r
+ {0x3036,0x46},\r
+ \r
+ {0x4837, 0x22},\r
+ {0x5001, 0xa3},\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorRegVal(0x3008, 0x80),\r
+ SensorWaitMs(5),\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x300a,0),\r
+ SensorRegVal(0x300b,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0x3406 ,0x00},\r
+ {0x5192 ,0x04},\r
+ {0x5191 ,0xf8},\r
+ {0x5193 ,0x70},\r
+ {0x5194 ,0xf0},\r
+ {0x5195 ,0xf0},\r
+ {0x518d ,0x3d},\r
+ {0x518f ,0x54},\r
+ {0x518e ,0x3d},\r
+ {0x5190 ,0x54},\r
+ {0x518b ,0xa8},\r
+ {0x518c ,0xa8},\r
+ {0x5187 ,0x18},\r
+ {0x5188 ,0x18},\r
+ {0x5189 ,0x6e},\r
+ {0x518a ,0x68},\r
+ {0x5186 ,0x1c},\r
+ {0x5181 ,0x50},\r
+ {0x5184 ,0x25},\r
+ {0x5182 ,0x11},\r
+ {0x5183 ,0x14},\r
+ {0x5184 ,0x25},\r
+ {0x5185 ,0x24},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0x3406 ,0x1 },\r
+ {0x3400 ,0x6 },\r
+ {0x3401 ,0x48},\r
+ {0x3402 ,0x4 },\r
+ {0x3403 ,0x0 },\r
+ {0x3404 ,0x4 },\r
+ {0x3405 ,0xd3 },\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ {0x3406 ,0x1 },\r
+ {0x3400 ,0x6 },\r
+ {0x3401 ,0x1c},\r
+ {0x3402 ,0x4 },\r
+ {0x3403 ,0x0 },\r
+ {0x3404 ,0x4 },\r
+ {0x3405 ,0xf3},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ //Office\r
+ {0x3406 ,0x1 },\r
+ {0x3400 ,0x5 },\r
+ {0x3401 ,0x48},\r
+ {0x3402 ,0x4 },\r
+ {0x3403 ,0x0 },\r
+ {0x3404 ,0x7 },\r
+ {0x3405 ,0xcf},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x3406 ,0x1 },\r
+ {0x3400 ,0x4 },\r
+ {0x3401 ,0x10},\r
+ {0x3402 ,0x4 },\r
+ {0x3403 ,0x0 },\r
+ {0x3404 ,0x8 },\r
+ {0x3405 ,0xb6},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0x5001, 0x7f},\r
+ {0x5580, 0x00},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0x5001, 0xff},\r
+ {0x5580, 0x18},\r
+ {0x5583, 0x80},\r
+ {0x5584, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0x5001, 0xff},\r
+ {0x5580, 0x18},\r
+ {0x5583, 0x40},\r
+ {0x5584, 0xa0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ //Negative\r
+ {0x5001, 0xff},\r
+ {0x5580, 0x40},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ // Bluish\r
+ {0x5001, 0xff},\r
+ {0x5580, 0x18},\r
+ {0x5583, 0xa0},\r
+ {0x5584, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ // Greenish\r
+ {0x5001, 0xff},\r
+ {0x5580, 0x18},\r
+ {0x5583, 0x60},\r
+ {0x5584, 0x60},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ {0x3a0f, 0x10},\r
+ {0x3a10, 0x08},\r
+ {0x3a1b, 0x10},\r
+ {0x3a1e, 0x08},\r
+ {0x3a11, 0x20},\r
+ {0x3a1f, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ {0x3a0f, 0x20},\r
+ {0x3a10, 0x18},\r
+ {0x3a11, 0x41},\r
+ {0x3a1b, 0x20},\r
+ {0x3a1e, 0x18},\r
+ {0x3a1f, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ {0x3a0f, 0x30},\r
+ {0x3a10, 0x28},\r
+ {0x3a11, 0x61},\r
+ {0x3a1b, 0x30},\r
+ {0x3a1e, 0x28},\r
+ {0x3a1f, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ {0x3a0f, 0x38},\r
+ {0x3a10, 0x30},\r
+ {0x3a11, 0x61},\r
+ {0x3a1b, 0x38},\r
+ {0x3a1e, 0x30},\r
+ {0x3a1f, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ {0x3a0f, 0x40},\r
+ {0x3a10, 0x38},\r
+ {0x3a11, 0x71},\r
+ {0x3a1b, 0x40},\r
+ {0x3a1e, 0x38},\r
+ {0x3a1f, 0x10},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ {0x3a0f, 0x50},\r
+ {0x3a10, 0x48},\r
+ {0x3a11, 0x90},\r
+ {0x3a1b, 0x50},\r
+ {0x3a1e, 0x48},\r
+ {0x3a1f, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ {0x3a0f, 0x60},\r
+ {0x3a10, 0x58},\r
+ {0x3a11, 0xa0},\r
+ {0x3a1b, 0x60},\r
+ {0x3a1e, 0x58},\r
+ {0x3a1f, 0x20},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0x3a00, 0x78},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ //15fps ~ 3.75fps night mode for 60/50Hz light environment, 24Mhz clock input,24Mzh pclk\r
+ {0x3034 ,0x1a},\r
+ {0x3035 ,0x21},\r
+ {0x3036 ,0x46},\r
+ {0x3037 ,0x13},\r
+ {0x3038 ,0x00},\r
+ {0x3039 ,0x00},\r
+ {0x3a00 ,0x7c},\r
+ {0x3a08 ,0x01},\r
+ {0x3a09 ,0x27},\r
+ {0x3a0a ,0x00},\r
+ {0x3a0b ,0xf6},\r
+ {0x3a0d ,0x04},\r
+ {0x3a0e ,0x04},\r
+ {0x3a02 ,0x0b},\r
+ {0x3a03 ,0x88},\r
+ {0x3a14 ,0x0b},\r
+ {0x3a15 ,0x88},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+ static int sensor_parameter_record(struct i2c_client *client)\r
+ {\r
+ u8 ret_l,ret_m,ret_h;\r
+ int tp_l,tp_m,tp_h;\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+ sensor_read(client,0x3a00, &ret_l);\r
+ sensor_write(client,0x3a00, ret_l&0xfb);\r
+ \r
+ sensor_write(client,0x3503,0x07); //stop AE/AG\r
+ sensor_read(client,0x3406, &ret_l);\r
+ sensor_write(client,0x3406, ret_l|0x01);\r
+ \r
+ sensor_read(client,0x3500,&ret_h);\r
+ sensor_read(client,0x3501, &ret_m);\r
+ sensor_read(client,0x3502, &ret_l);\r
+ tp_l = ret_l;\r
+ tp_m = ret_m;\r
+ tp_h = ret_h;\r
+ spsensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F);\r
+ \r
+ //Read back AGC Gain for preview\r
+ sensor_read(client,0x350b, &ret_l);\r
+ spsensor->parameter.preview_gain = ret_l;\r
+ \r
+ SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n",\r
+ SENSOR_NAME_STRING(), tp_l,spsensor->parameter.preview_exposure,tp_h, tp_m, tp_l);\r
+ return 0;\r
+ }\r
+#define OV5640_FULL_PERIOD_PIXEL_NUMS_HTS (2844) \r
+#define OV5640_FULL_PERIOD_LINE_NUMS_VTS (1968) \r
+#define OV5640_PV_PERIOD_PIXEL_NUMS_HTS (1896) \r
+#define OV5640_PV_PERIOD_LINE_NUMS_VTS (984) \r
+ static int sensor_ae_transfer(struct i2c_client *client)\r
+ {\r
+ u8 ExposureLow;\r
+ u8 ExposureMid;\r
+ u8 ExposureHigh;\r
+ u16 ulCapture_Exposure;\r
+ u16 Preview_Maxlines;\r
+ u8 Gain;\r
+ u16 OV5640_g_iExtra_ExpLines;\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ struct specific_sensor *spsensor = to_specific_sensor(sensor);\r
+ //Preview_Maxlines = sensor->parameter.preview_line_width;\r
+ Preview_Maxlines = spsensor->parameter.preview_maxlines;\r
+ Gain = spsensor->parameter.preview_gain;\r
+ \r
+ \r
+ ulCapture_Exposure = (spsensor->parameter.preview_exposure*OV5640_PV_PERIOD_PIXEL_NUMS_HTS)/OV5640_FULL_PERIOD_PIXEL_NUMS_HTS;\r
+ \r
+ SENSOR_DG("cap shutter calutaed = %d, 0x%x\n", ulCapture_Exposure,ulCapture_Exposure);\r
+ \r
+ // write the gain and exposure to 0x350* registers \r
+ sensor_write(client,0x350b, Gain); \r
+ \r
+ if (ulCapture_Exposure <= 1940) {\r
+ OV5640_g_iExtra_ExpLines = 0;\r
+ }else {\r
+ OV5640_g_iExtra_ExpLines = ulCapture_Exposure - 1940;\r
+ }\r
+ SENSOR_DG("Set Extra-line = %d, iExp = %d \n", OV5640_g_iExtra_ExpLines, ulCapture_Exposure);\r
+ \r
+ ExposureLow = (ulCapture_Exposure<<4)&0xff;\r
+ ExposureMid = (ulCapture_Exposure>>4)&0xff;\r
+ ExposureHigh = (ulCapture_Exposure>>12);\r
+ \r
+ sensor_write(client,0x350c, (OV5640_g_iExtra_ExpLines&0xff00)>>8);\r
+ sensor_write(client,0x350d, OV5640_g_iExtra_ExpLines&0xff);\r
+ sensor_write(client,0x3502, ExposureLow);\r
+ sensor_write(client,0x3501, ExposureMid);\r
+ sensor_write(client,0x3500, ExposureHigh);\r
+ \r
+ //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);\r
+ mdelay(100);\r
+ return 0;\r
+ }\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ \r
+ if (capture) {\r
+ sensor_parameter_record(client);\r
+ }\r
+ return 0;\r
+}\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ struct generic_sensor*sensor = to_generic_sensor(client);\r
+ if (capture) {\r
+ sensor_ae_transfer(client);\r
+ }\r
+ msleep(400);\r
+ return 0;\r
+}\r
+static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+\r
+ return 0; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ SENSOR_DG("flip: %d",flip);\r
+\r
+ return 0; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+/*\r
+for 5640 focus\r
+*/\r
+struct af_cmdinfo\r
+{\r
+ char cmd_tag;\r
+ char cmd_para[4];\r
+ char validate_bit;\r
+};\r
+static int sensor_af_cmdset(struct i2c_client *client, int cmd_main, struct af_cmdinfo *cmdinfo)\r
+{\r
+ int i;\r
+ char read_tag=0xff,cnt;\r
+\r
+ if (cmdinfo) {\r
+ for (i=0; i<4; i++) {\r
+ if (cmdinfo->validate_bit & (1<<i)) {\r
+ if (sensor_write(client, CMD_PARA0_Reg+i, cmdinfo->cmd_para[i])) {\r
+ 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]);\r
+ goto sensor_af_cmdset_err;\r
+ }\r
+ 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]);\r
+ }\r
+ }\r
+ \r
+ if (cmdinfo->validate_bit & 0x80) {\r
+ if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) {\r
+ SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);\r
+ goto sensor_af_cmdset_err;\r
+ }\r
+ SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);\r
+ }\r
+ \r
+ } else {\r
+ if (sensor_write(client, CMD_ACK_Reg, 0x01)) {\r
+ SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main);\r
+ goto sensor_af_cmdset_err;\r
+ }\r
+ SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x no tag) success!\n",SENSOR_NAME_STRING(),cmd_main);\r
+ }\r
+\r
+ if (sensor_write(client, CMD_MAIN_Reg, cmd_main)) {\r
+ SENSOR_TR("%s write CMD_MAIN_Reg(main:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main);\r
+ goto sensor_af_cmdset_err;\r
+ }\r
+\r
+ cnt = 0;\r
+ do\r
+ {\r
+ msleep(5);\r
+ if (sensor_read(client,CMD_ACK_Reg,&read_tag)){\r
+ SENSOR_TR("%s[%d] read TAG failed\n",SENSOR_NAME_STRING(),__LINE__);\r
+ break;\r
+ }\r
+ } while((read_tag != 0x00)&& (cnt++<100));\r
+\r
+ SENSOR_DG("%s write CMD_MAIN_Reg(main:0x%x read tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,read_tag);\r
+ return 0;\r
+sensor_af_cmdset_err:\r
+ return -1;\r
+}\r
+static int sensor_af_idlechk(struct i2c_client *client)\r
+{\r
+ int ret = 0;\r
+ char state; \r
+ struct af_cmdinfo cmdinfo;\r
+ \r
+ SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__);\r
+ \r
+ cmdinfo.cmd_tag = 0x01;\r
+ cmdinfo.validate_bit = 0x80;\r
+ ret = sensor_af_cmdset(client, ReturnIdle_Cmd, &cmdinfo);\r
+ if(0 != ret) {\r
+ SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);\r
+ ret = -1;\r
+ goto sensor_af_idlechk_end;\r
+ }\r
+ \r
+\r
+ do{\r
+ ret = sensor_read(client, CMD_ACK_Reg, &state);\r
+ if (ret != 0){\r
+ SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);\r
+ ret = -1;\r
+ goto sensor_af_idlechk_end;\r
+ }\r
+ }while(0x00 != state);\r
+\r
+ SENSOR_DG("%s , %d\n",__FUNCTION__,__LINE__);\r
+sensor_af_idlechk_end:\r
+ return ret;\r
+}\r
+/*for 5640 focus end*/\r
+//\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client);\r
+\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client)\r
+{\r
+ int ret = 0, cnt;\r
+ char state;\r
+\r
+ msleep(1);\r
+ ret = sensor_write_array(client, sensor_af_firmware);\r
+ if (ret != 0) {\r
+ SENSOR_TR("%s Download firmware failed\n",SENSOR_NAME_STRING());\r
+ ret = -1;\r
+ goto sensor_af_init_end;\r
+ }\r
+\r
+ cnt = 0;\r
+ do\r
+ {\r
+ msleep(1);\r
+ if (cnt++ > 500)\r
+ break;\r
+ ret = sensor_read(client, STA_FOCUS_Reg, &state);\r
+ if (ret != 0){\r
+ SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);\r
+ ret = -1;\r
+ goto sensor_af_init_end;\r
+ }\r
+ } while (state != S_IDLE);\r
+\r
+ if (state != S_IDLE) {\r
+ SENSOR_TR("%s focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),state);\r
+ ret = -1;\r
+ goto sensor_af_init_end;\r
+ }\r
+sensor_af_init_end:\r
+ SENSOR_DG("%s %s ret:0x%x \n",SENSOR_NAME_STRING(),__FUNCTION__,ret);\r
+ return ret;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client) \r
+{\r
+ int ret = 0;\r
+ char state,cnt;\r
+ struct af_cmdinfo cmdinfo;\r
+ char s_zone[5],i;\r
+ cmdinfo.cmd_tag = 0x01;\r
+ cmdinfo.validate_bit = 0x80;\r
+ ret = sensor_af_cmdset(client, SingleFocus_Cmd, &cmdinfo);\r
+ if(0 != ret) {\r
+ SENSOR_TR("%s single focus mode set error!\n",SENSOR_NAME_STRING());\r
+ ret = -1;\r
+ goto sensor_af_single_end;\r
+ }\r
+ \r
+ cnt = 0;\r
+ do\r
+ {\r
+ if (cnt != 0) {\r
+ msleep(1);\r
+ }\r
+ cnt++;\r
+ ret = sensor_read(client, STA_FOCUS_Reg, &state);\r
+ if (ret != 0){\r
+ SENSOR_TR("%s[%d] read focus_status failed\n",SENSOR_NAME_STRING(),__LINE__);\r
+ ret = -1;\r
+ goto sensor_af_single_end;\r
+ }\r
+ }while((state == S_FOCUSING) && (cnt<100));\r
+\r
+ if (state != S_FOCUSED) {\r
+ SENSOR_TR("%s[%d] focus state(0x%x) is error!\n",SENSOR_NAME_STRING(),__LINE__,state);\r
+ ret = -1;\r
+ goto sensor_af_single_end;\r
+ } else {\r
+ SENSOR_DG("%s[%d] single focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); \r
+ }\r
+sensor_af_single_end:\r
+ return ret;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client)\r
+{\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client)\r
+{\r
+ \r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos)\r
+{\r
+ struct af_cmdinfo cmdinfo;\r
+ sensor_af_idlechk(client);\r
+ return 0;\r
+ cmdinfo.cmd_tag = StepFocus_Spec_Tag;\r
+ cmdinfo.cmd_para[0] = pos;\r
+ cmdinfo.validate_bit = 0x81;\r
+ return sensor_af_cmdset(client, StepMode_Cmd, &cmdinfo);\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client)\r
+{\r
+ int ret = 0;\r
+ struct af_cmdinfo cmdinfo;\r
+ cmdinfo.cmd_tag = 0x01;\r
+ cmdinfo.cmd_para[0] = 0x00;\r
+ cmdinfo.validate_bit = 0x81;\r
+ sensor_af_idlechk(client);\r
+ if (sensor_af_cmdset(client, ConstFocus_Cmd, &cmdinfo)) {\r
+ SENSOR_TR("%s[%d] const focus mode set error!\n",SENSOR_NAME_STRING(),__LINE__);\r
+ ret = -1;\r
+ goto sensor_af_const_end;\r
+ } else {\r
+ SENSOR_DG("%s[%d] const focus mode set success!\n",SENSOR_NAME_STRING(),__LINE__); \r
+ }\r
+sensor_af_const_end:\r
+ return ret;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client)\r
+{\r
+ int ret = 0; \r
+ sensor_af_idlechk(client);\r
+ if (sensor_af_cmdset(client, PauseFocus_Cmd, NULL)) {\r
+ SENSOR_TR("%s pause focus mode set error!\n",SENSOR_NAME_STRING());\r
+ ret = -1;\r
+ goto sensor_af_pause_end;\r
+ }\r
+sensor_af_pause_end:\r
+ return ret;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos)\r
+{\r
+ int ret = 0;\r
+ struct af_cmdinfo cmdinfo;\r
+ //int zone_tm_pos[4];\r
+ int zone_center_pos[2];\r
+ struct generic_sensor*sensor = to_generic_sensor(client); \r
+ \r
+ if (zone_tm_pos) {\r
+ zone_tm_pos[0] += 1000;\r
+ zone_tm_pos[1] += 1000;\r
+ zone_tm_pos[2]+= 1000;\r
+ zone_tm_pos[3] += 1000;\r
+ zone_center_pos[0] = ((zone_tm_pos[0] + zone_tm_pos[2])>>1)*80/2000;\r
+ zone_center_pos[1] = ((zone_tm_pos[1] + zone_tm_pos[3])>>1)*60/2000;\r
+ } else {\r
+#if CONFIG_SENSOR_FocusCenterInCapture\r
+ zone_center_pos[0] = 32;\r
+ zone_center_pos[1] = 24;\r
+#else\r
+ zone_center_pos[0] = -1;\r
+ zone_center_pos[1] = -1;\r
+#endif\r
+ }\r
+ if ((zone_center_pos[0] >=0) && (zone_center_pos[1]>=0)){\r
+ cmdinfo.cmd_tag = 0x01;\r
+ cmdinfo.validate_bit = 0x83;\r
+ if (zone_center_pos[0]<=8)\r
+ cmdinfo.cmd_para[0] = 0;\r
+ else if ((zone_center_pos[0]>8) && (zone_center_pos[0]<72))\r
+ cmdinfo.cmd_para[0] = zone_center_pos[0]-8;\r
+ else \r
+ cmdinfo.cmd_para[0] = 72; \r
+ \r
+ if (zone_center_pos[1]<=6)\r
+ cmdinfo.cmd_para[1] = 0;\r
+ else if ((zone_center_pos[1]>6) && (zone_center_pos[1]<54))\r
+ cmdinfo.cmd_para[1] = zone_center_pos[1]-6;\r
+ else \r
+ cmdinfo.cmd_para[1] = 54;\r
+ \r
+ ret = sensor_af_cmdset(client, TouchZoneConfig_Cmd, &cmdinfo);\r
+ if(0 != ret) {\r
+ SENSOR_TR("%s touch zone config error!\n",SENSOR_NAME_STRING());\r
+ ret = -1;\r
+ goto sensor_af_zone_end;\r
+ } \r
+ }\r
+sensor_af_zone_end:\r
+ return ret;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+ \r
+\r
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/\r
-#include "ov5640.h"\r
+//#include "ov5640.h"\r
\r
-static struct reginfo sensor_af_firmware[] =\r
+static struct rk_sensor_reg sensor_af_firmware[] =\r
{\r
+ SensorStreamChk,\r
#if 0\r
{0x3000, 0x20},\r
{0x8000, 0x02},\r
{0x3029,0x7F},\r
{0x3000,0x00},\r
#endif\r
- {SEQUENCE_END,0x00},\r
+SensorEnd
};\r
--- /dev/null
+/*\r
+ * Driver for OV5640 CMOS Image Sensor from OmniVision\r
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */\r
+#include "ov5640.h"\r
+\r
+static struct reginfo sensor_af_firmware[] =\r
+{\r
+#if 0\r
+ {0x3000, 0x20},\r
+ {0x8000, 0x02},\r
+ {0x8001, 0x0b},\r
+ {0x8002, 0x61},\r
+ {0x8003, 0x02},\r
+ {0x8004, 0x07},\r
+ {0x8005, 0xb1},\r
+ {0x8006, 0xc2},\r
+ {0x8007, 0x01},\r
+ {0x8008, 0x22},\r
+ {0x8009, 0x22},\r
+ {0x800a, 0x00},\r
+ {0x800b, 0x02},\r
+ {0x800c, 0x0b},\r
+ {0x800d, 0x4b},\r
+ {0x800e, 0xe5},\r
+ {0x800f, 0x1f},\r
+ {0x8010, 0x60},\r
+ {0x8011, 0x03},\r
+ {0x8012, 0x02},\r
+ {0x8013, 0x00},\r
+ {0x8014, 0x97},\r
+ {0x8015, 0xf5},\r
+ {0x8016, 0x1e},\r
+ {0x8017, 0xd2},\r
+ {0x8018, 0x34},\r
+ {0x8019, 0x75},\r
+ {0x801a, 0x34},\r
+ {0x801b, 0xff},\r
+ {0x801c, 0x75},\r
+ {0x801d, 0x35},\r
+ {0x801e, 0x0e},\r
+ {0x801f, 0x75},\r
+ {0x8020, 0x36},\r
+ {0x8021, 0x55},\r
+ {0x8022, 0x75},\r
+ {0x8023, 0x37},\r
+ {0x8024, 0x01},\r
+ {0x8025, 0x12},\r
+ {0x8026, 0x0a},\r
+ {0x8027, 0x3e},\r
+ {0x8028, 0xe4},\r
+ {0x8029, 0xff},\r
+ {0x802a, 0xef},\r
+ {0x802b, 0x25},\r
+ {0x802c, 0xe0},\r
+ {0x802d, 0x24},\r
+ {0x802e, 0x4b},\r
+ {0x802f, 0xf8},\r
+ {0x8030, 0xe4},\r
+ {0x8031, 0xf6},\r
+ {0x8032, 0x08},\r
+ {0x8033, 0xf6},\r
+ {0x8034, 0x0f},\r
+ {0x8035, 0xbf},\r
+ {0x8036, 0x34},\r
+ {0x8037, 0xf2},\r
+ {0x8038, 0x90},\r
+ {0x8039, 0x0e},\r
+ {0x803a, 0x88},\r
+ {0x803b, 0xe4},\r
+ {0x803c, 0x93},\r
+ {0x803d, 0xff},\r
+ {0x803e, 0xe5},\r
+ {0x803f, 0x49},\r
+ {0x8040, 0xc3},\r
+ {0x8041, 0x9f},\r
+ {0x8042, 0x50},\r
+ {0x8043, 0x04},\r
+ {0x8044, 0x7f},\r
+ {0x8045, 0x05},\r
+ {0x8046, 0x80},\r
+ {0x8047, 0x02},\r
+ {0x8048, 0x7f},\r
+ {0x8049, 0xfb},\r
+ {0x804a, 0x78},\r
+ {0x804b, 0xba},\r
+ {0x804c, 0xa6},\r
+ {0x804d, 0x07},\r
+ {0x804e, 0x12},\r
+ {0x804f, 0x0a},\r
+ {0x8050, 0xa8},\r
+ {0x8051, 0x40},\r
+ {0x8052, 0x04},\r
+ {0x8053, 0x7f},\r
+ {0x8054, 0x03},\r
+ {0x8055, 0x80},\r
+ {0x8056, 0x02},\r
+ {0x8057, 0x7f},\r
+ {0x8058, 0x30},\r
+ {0x8059, 0x78},\r
+ {0x805a, 0xb9},\r
+ {0x805b, 0xa6},\r
+ {0x805c, 0x07},\r
+ {0x805d, 0xe6},\r
+ {0x805e, 0x18},\r
+ {0x805f, 0xf6},\r
+ {0x8060, 0x08},\r
+ {0x8061, 0xe6},\r
+ {0x8062, 0x78},\r
+ {0x8063, 0xb6},\r
+ {0x8064, 0xf6},\r
+ {0x8065, 0x78},\r
+ {0x8066, 0xb9},\r
+ {0x8067, 0xe6},\r
+ {0x8068, 0x78},\r
+ {0x8069, 0xb7},\r
+ {0x806a, 0xf6},\r
+ {0x806b, 0x78},\r
+ {0x806c, 0xbc},\r
+ {0x806d, 0x76},\r
+ {0x806e, 0x33},\r
+ {0x806f, 0xe4},\r
+ {0x8070, 0x08},\r
+ {0x8071, 0xf6},\r
+ {0x8072, 0x78},\r
+ {0x8073, 0xb5},\r
+ {0x8074, 0x76},\r
+ {0x8075, 0x01},\r
+ {0x8076, 0x75},\r
+ {0x8077, 0x48},\r
+ {0x8078, 0x02},\r
+ {0x8079, 0x78},\r
+ {0x807a, 0xb3},\r
+ {0x807b, 0xf6},\r
+ {0x807c, 0x08},\r
+ {0x807d, 0xf6},\r
+ {0x807e, 0x74},\r
+ {0x807f, 0xff},\r
+ {0x8080, 0x78},\r
+ {0x8081, 0xbe},\r
+ {0x8082, 0xf6},\r
+ {0x8083, 0x08},\r
+ {0x8084, 0xf6},\r
+ {0x8085, 0x75},\r
+ {0x8086, 0x1f},\r
+ {0x8087, 0x01},\r
+ {0x8088, 0x78},\r
+ {0x8089, 0xb9},\r
+ {0x808a, 0xe6},\r
+ {0x808b, 0x75},\r
+ {0x808c, 0xf0},\r
+ {0x808d, 0x05},\r
+ {0x808e, 0xa4},\r
+ {0x808f, 0xf5},\r
+ {0x8090, 0x49},\r
+ {0x8091, 0x12},\r
+ {0x8092, 0x08},\r
+ {0x8093, 0x4f},\r
+ {0x8094, 0xc2},\r
+ {0x8095, 0x36},\r
+ {0x8096, 0x22},\r
+ {0x8097, 0x78},\r
+ {0x8098, 0xb5},\r
+ {0x8099, 0xe6},\r
+ {0x809a, 0xd3},\r
+ {0x809b, 0x94},\r
+ {0x809c, 0x00},\r
+ {0x809d, 0x40},\r
+ {0x809e, 0x02},\r
+ {0x809f, 0x16},\r
+ {0x80a0, 0x22},\r
+ {0x80a1, 0xe5},\r
+ {0x80a2, 0x1f},\r
+ {0x80a3, 0xb4},\r
+ {0x80a4, 0x05},\r
+ {0x80a5, 0x23},\r
+ {0x80a6, 0xe4},\r
+ {0x80a7, 0xf5},\r
+ {0x80a8, 0x1f},\r
+ {0x80a9, 0xc2},\r
+ {0x80aa, 0x01},\r
+ {0x80ab, 0x78},\r
+ {0x80ac, 0xb3},\r
+ {0x80ad, 0xe6},\r
+ {0x80ae, 0xfe},\r
+ {0x80af, 0x08},\r
+ {0x80b0, 0xe6},\r
+ {0x80b1, 0xff},\r
+ {0x80b2, 0x78},\r
+ {0x80b3, 0x4b},\r
+ {0x80b4, 0xa6},\r
+ {0x80b5, 0x06},\r
+ {0x80b6, 0x08},\r
+ {0x80b7, 0xa6},\r
+ {0x80b8, 0x07},\r
+ {0x80b9, 0xa2},\r
+ {0x80ba, 0x36},\r
+ {0x80bb, 0xe4},\r
+ {0x80bc, 0x33},\r
+ {0x80bd, 0xf5},\r
+ {0x80be, 0x3c},\r
+ {0x80bf, 0x90},\r
+ {0x80c0, 0x30},\r
+ {0x80c1, 0x28},\r
+ {0x80c2, 0xf0},\r
+ {0x80c3, 0x75},\r
+ {0x80c4, 0x1e},\r
+ {0x80c5, 0x10},\r
+ {0x80c6, 0xd2},\r
+ {0x80c7, 0x34},\r
+ {0x80c8, 0x22},\r
+ {0x80c9, 0xe5},\r
+ {0x80ca, 0x49},\r
+ {0x80cb, 0x75},\r
+ {0x80cc, 0xf0},\r
+ {0x80cd, 0x05},\r
+ {0x80ce, 0x84},\r
+ {0x80cf, 0x78},\r
+ {0x80d0, 0xb9},\r
+ {0x80d1, 0xf6},\r
+ {0x80d2, 0x90},\r
+ {0x80d3, 0x0e},\r
+ {0x80d4, 0x85},\r
+ {0x80d5, 0xe4},\r
+ {0x80d6, 0x93},\r
+ {0x80d7, 0xff},\r
+ {0x80d8, 0x25},\r
+ {0x80d9, 0xe0},\r
+ {0x80da, 0x24},\r
+ {0x80db, 0x0a},\r
+ {0x80dc, 0xf8},\r
+ {0x80dd, 0xe6},\r
+ {0x80de, 0xfc},\r
+ {0x80df, 0x08},\r
+ {0x80e0, 0xe6},\r
+ {0x80e1, 0xfd},\r
+ {0x80e2, 0x78},\r
+ {0x80e3, 0xb9},\r
+ {0x80e4, 0xe6},\r
+ {0x80e5, 0x25},\r
+ {0x80e6, 0xe0},\r
+ {0x80e7, 0x24},\r
+ {0x80e8, 0x4b},\r
+ {0x80e9, 0xf8},\r
+ {0x80ea, 0xa6},\r
+ {0x80eb, 0x04},\r
+ {0x80ec, 0x08},\r
+ {0x80ed, 0xa6},\r
+ {0x80ee, 0x05},\r
+ {0x80ef, 0xef},\r
+ {0x80f0, 0x12},\r
+ {0x80f1, 0x0a},\r
+ {0x80f2, 0xaf},\r
+ {0x80f3, 0xd3},\r
+ {0x80f4, 0x78},\r
+ {0x80f5, 0xb4},\r
+ {0x80f6, 0x96},\r
+ {0x80f7, 0xee},\r
+ {0x80f8, 0x18},\r
+ {0x80f9, 0x96},\r
+ {0x80fa, 0x40},\r
+ {0x80fb, 0x0d},\r
+ {0x80fc, 0x78},\r
+ {0x80fd, 0xb9},\r
+ {0x80fe, 0xe6},\r
+ {0x80ff, 0x78},\r
+ {0x8100, 0xb6},\r
+ {0x8101, 0xf6},\r
+ {0x8102, 0x78},\r
+ {0x8103, 0xb3},\r
+ {0x8104, 0xa6},\r
+ {0x8105, 0x06},\r
+ {0x8106, 0x08},\r
+ {0x8107, 0xa6},\r
+ {0x8108, 0x07},\r
+ {0x8109, 0x90},\r
+ {0x810a, 0x0e},\r
+ {0x810b, 0x85},\r
+ {0x810c, 0xe4},\r
+ {0x810d, 0x93},\r
+ {0x810e, 0x12},\r
+ {0x810f, 0x0a},\r
+ {0x8110, 0xaf},\r
+ {0x8111, 0xc3},\r
+ {0x8112, 0x78},\r
+ {0x8113, 0xbf},\r
+ {0x8114, 0x96},\r
+ {0x8115, 0xee},\r
+ {0x8116, 0x18},\r
+ {0x8117, 0x96},\r
+ {0x8118, 0x50},\r
+ {0x8119, 0x0d},\r
+ {0x811a, 0x78},\r
+ {0x811b, 0xb9},\r
+ {0x811c, 0xe6},\r
+ {0x811d, 0x78},\r
+ {0x811e, 0xb7},\r
+ {0x811f, 0xf6},\r
+ {0x8120, 0x78},\r
+ {0x8121, 0xbe},\r
+ {0x8122, 0xa6},\r
+ {0x8123, 0x06},\r
+ {0x8124, 0x08},\r
+ {0x8125, 0xa6},\r
+ {0x8126, 0x07},\r
+ {0x8127, 0x78},\r
+ {0x8128, 0xb3},\r
+ {0x8129, 0xe6},\r
+ {0x812a, 0xfe},\r
+ {0x812b, 0x08},\r
+ {0x812c, 0xe6},\r
+ {0x812d, 0xc3},\r
+ {0x812e, 0x78},\r
+ {0x812f, 0xbf},\r
+ {0x8130, 0x96},\r
+ {0x8131, 0xff},\r
+ {0x8132, 0xee},\r
+ {0x8133, 0x18},\r
+ {0x8134, 0x96},\r
+ {0x8135, 0x78},\r
+ {0x8136, 0xc0},\r
+ {0x8137, 0xf6},\r
+ {0x8138, 0x08},\r
+ {0x8139, 0xa6},\r
+ {0x813a, 0x07},\r
+ {0x813b, 0x90},\r
+ {0x813c, 0x0e},\r
+ {0x813d, 0x8a},\r
+ {0x813e, 0xe4},\r
+ {0x813f, 0x18},\r
+ {0x8140, 0x12},\r
+ {0x8141, 0x0a},\r
+ {0x8142, 0x8d},\r
+ {0x8143, 0x40},\r
+ {0x8144, 0x02},\r
+ {0x8145, 0xd2},\r
+ {0x8146, 0x36},\r
+ {0x8147, 0x78},\r
+ {0x8148, 0xb9},\r
+ {0x8149, 0xe6},\r
+ {0x814a, 0x08},\r
+ {0x814b, 0x26},\r
+ {0x814c, 0x08},\r
+ {0x814d, 0xf6},\r
+ {0x814e, 0xe5},\r
+ {0x814f, 0x1f},\r
+ {0x8150, 0x64},\r
+ {0x8151, 0x01},\r
+ {0x8152, 0x70},\r
+ {0x8153, 0x4a},\r
+ {0x8154, 0xe6},\r
+ {0x8155, 0xc3},\r
+ {0x8156, 0x78},\r
+ {0x8157, 0xbd},\r
+ {0x8158, 0x12},\r
+ {0x8159, 0x0a},\r
+ {0x815a, 0x83},\r
+ {0x815b, 0x40},\r
+ {0x815c, 0x05},\r
+ {0x815d, 0x12},\r
+ {0x815e, 0x0a},\r
+ {0x815f, 0x7e},\r
+ {0x8160, 0x40},\r
+ {0x8161, 0x39},\r
+ {0x8162, 0x12},\r
+ {0x8163, 0x0a},\r
+ {0x8164, 0xa6},\r
+ {0x8165, 0x40},\r
+ {0x8166, 0x04},\r
+ {0x8167, 0x7f},\r
+ {0x8168, 0xfe},\r
+ {0x8169, 0x80},\r
+ {0x816a, 0x02},\r
+ {0x816b, 0x7f},\r
+ {0x816c, 0x02},\r
+ {0x816d, 0x78},\r
+ {0x816e, 0xba},\r
+ {0x816f, 0xa6},\r
+ {0x8170, 0x07},\r
+ {0x8171, 0x78},\r
+ {0x8172, 0xb6},\r
+ {0x8173, 0xe6},\r
+ {0x8174, 0x24},\r
+ {0x8175, 0x03},\r
+ {0x8176, 0x78},\r
+ {0x8177, 0xbc},\r
+ {0x8178, 0xf6},\r
+ {0x8179, 0x78},\r
+ {0x817a, 0xb6},\r
+ {0x817b, 0xe6},\r
+ {0x817c, 0x24},\r
+ {0x817d, 0xfd},\r
+ {0x817e, 0x78},\r
+ {0x817f, 0xbd},\r
+ {0x8180, 0xf6},\r
+ {0x8181, 0x12},\r
+ {0x8182, 0x0a},\r
+ {0x8183, 0xa6},\r
+ {0x8184, 0x40},\r
+ {0x8185, 0x06},\r
+ {0x8186, 0x78},\r
+ {0x8187, 0xbd},\r
+ {0x8188, 0xe6},\r
+ {0x8189, 0xff},\r
+ {0x818a, 0x80},\r
+ {0x818b, 0x04},\r
+ {0x818c, 0x78},\r
+ {0x818d, 0xbc},\r
+ {0x818e, 0xe6},\r
+ {0x818f, 0xff},\r
+ {0x8190, 0x78},\r
+ {0x8191, 0xbb},\r
+ {0x8192, 0xa6},\r
+ {0x8193, 0x07},\r
+ {0x8194, 0x75},\r
+ {0x8195, 0x1f},\r
+ {0x8196, 0x02},\r
+ {0x8197, 0x78},\r
+ {0x8198, 0xb5},\r
+ {0x8199, 0x76},\r
+ {0x819a, 0x01},\r
+ {0x819b, 0x02},\r
+ {0x819c, 0x02},\r
+ {0x819d, 0x5d},\r
+ {0x819e, 0xe5},\r
+ {0x819f, 0x1f},\r
+ {0x81a0, 0x64},\r
+ {0x81a1, 0x02},\r
+ {0x81a2, 0x60},\r
+ {0x81a3, 0x03},\r
+ {0x81a4, 0x02},\r
+ {0x81a5, 0x02},\r
+ {0x81a6, 0x3d},\r
+ {0x81a7, 0x78},\r
+ {0x81a8, 0xbb},\r
+ {0x81a9, 0xe6},\r
+ {0x81aa, 0xff},\r
+ {0x81ab, 0xc3},\r
+ {0x81ac, 0x78},\r
+ {0x81ad, 0xbd},\r
+ {0x81ae, 0x12},\r
+ {0x81af, 0x0a},\r
+ {0x81b0, 0x84},\r
+ {0x81b1, 0x40},\r
+ {0x81b2, 0x08},\r
+ {0x81b3, 0x12},\r
+ {0x81b4, 0x0a},\r
+ {0x81b5, 0x7e},\r
+ {0x81b6, 0x50},\r
+ {0x81b7, 0x03},\r
+ {0x81b8, 0x02},\r
+ {0x81b9, 0x02},\r
+ {0x81ba, 0x3b},\r
+ {0x81bb, 0x12},\r
+ {0x81bc, 0x0a},\r
+ {0x81bd, 0xa6},\r
+ {0x81be, 0x40},\r
+ {0x81bf, 0x04},\r
+ {0x81c0, 0x7f},\r
+ {0x81c1, 0xff},\r
+ {0x81c2, 0x80},\r
+ {0x81c3, 0x02},\r
+ {0x81c4, 0x7f},\r
+ {0x81c5, 0x01},\r
+ {0x81c6, 0x78},\r
+ {0x81c7, 0xba},\r
+ {0x81c8, 0xa6},\r
+ {0x81c9, 0x07},\r
+ {0x81ca, 0x78},\r
+ {0x81cb, 0xb6},\r
+ {0x81cc, 0xe6},\r
+ {0x81cd, 0x04},\r
+ {0x81ce, 0x78},\r
+ {0x81cf, 0xbc},\r
+ {0x81d0, 0xf6},\r
+ {0x81d1, 0x78},\r
+ {0x81d2, 0xb6},\r
+ {0x81d3, 0xe6},\r
+ {0x81d4, 0x14},\r
+ {0x81d5, 0x78},\r
+ {0x81d6, 0xbd},\r
+ {0x81d7, 0xf6},\r
+ {0x81d8, 0x18},\r
+ {0x81d9, 0x12},\r
+ {0x81da, 0x0a},\r
+ {0x81db, 0xa8},\r
+ {0x81dc, 0x40},\r
+ {0x81dd, 0x04},\r
+ {0x81de, 0xe6},\r
+ {0x81df, 0xff},\r
+ {0x81e0, 0x80},\r
+ {0x81e1, 0x02},\r
+ {0x81e2, 0x7f},\r
+ {0x81e3, 0x00},\r
+ {0x81e4, 0x78},\r
+ {0x81e5, 0xbc},\r
+ {0x81e6, 0xa6},\r
+ {0x81e7, 0x07},\r
+ {0x81e8, 0xd3},\r
+ {0x81e9, 0x08},\r
+ {0x81ea, 0xe6},\r
+ {0x81eb, 0x64},\r
+ {0x81ec, 0x80},\r
+ {0x81ed, 0x94},\r
+ {0x81ee, 0x80},\r
+ {0x81ef, 0x40},\r
+ {0x81f0, 0x04},\r
+ {0x81f1, 0xe6},\r
+ {0x81f2, 0xff},\r
+ {0x81f3, 0x80},\r
+ {0x81f4, 0x02},\r
+ {0x81f5, 0x7f},\r
+ {0x81f6, 0x00},\r
+ {0x81f7, 0x78},\r
+ {0x81f8, 0xbd},\r
+ {0x81f9, 0xa6},\r
+ {0x81fa, 0x07},\r
+ {0x81fb, 0xc3},\r
+ {0x81fc, 0x18},\r
+ {0x81fd, 0xe6},\r
+ {0x81fe, 0x64},\r
+ {0x81ff, 0x80},\r
+ {0x8200, 0x94},\r
+ {0x8201, 0xb3},\r
+ {0x8202, 0x50},\r
+ {0x8203, 0x04},\r
+ {0x8204, 0xe6},\r
+ {0x8205, 0xff},\r
+ {0x8206, 0x80},\r
+ {0x8207, 0x02},\r
+ {0x8208, 0x7f},\r
+ {0x8209, 0x33},\r
+ {0x820a, 0x78},\r
+ {0x820b, 0xbc},\r
+ {0x820c, 0xa6},\r
+ {0x820d, 0x07},\r
+ {0x820e, 0xc3},\r
+ {0x820f, 0x08},\r
+ {0x8210, 0xe6},\r
+ {0x8211, 0x64},\r
+ {0x8212, 0x80},\r
+ {0x8213, 0x94},\r
+ {0x8214, 0xb3},\r
+ {0x8215, 0x50},\r
+ {0x8216, 0x04},\r
+ {0x8217, 0xe6},\r
+ {0x8218, 0xff},\r
+ {0x8219, 0x80},\r
+ {0x821a, 0x02},\r
+ {0x821b, 0x7f},\r
+ {0x821c, 0x33},\r
+ {0x821d, 0x78},\r
+ {0x821e, 0xbd},\r
+ {0x821f, 0xa6},\r
+ {0x8220, 0x07},\r
+ {0x8221, 0x12},\r
+ {0x8222, 0x0a},\r
+ {0x8223, 0xa6},\r
+ {0x8224, 0x40},\r
+ {0x8225, 0x06},\r
+ {0x8226, 0x78},\r
+ {0x8227, 0xbd},\r
+ {0x8228, 0xe6},\r
+ {0x8229, 0xff},\r
+ {0x822a, 0x80},\r
+ {0x822b, 0x04},\r
+ {0x822c, 0x78},\r
+ {0x822d, 0xbc},\r
+ {0x822e, 0xe6},\r
+ {0x822f, 0xff},\r
+ {0x8230, 0x78},\r
+ {0x8231, 0xbb},\r
+ {0x8232, 0xa6},\r
+ {0x8233, 0x07},\r
+ {0x8234, 0x75},\r
+ {0x8235, 0x1f},\r
+ {0x8236, 0x03},\r
+ {0x8237, 0x78},\r
+ {0x8238, 0xb5},\r
+ {0x8239, 0x76},\r
+ {0x823a, 0x01},\r
+ {0x823b, 0x80},\r
+ {0x823c, 0x20},\r
+ {0x823d, 0xe5},\r
+ {0x823e, 0x1f},\r
+ {0x823f, 0x64},\r
+ {0x8240, 0x03},\r
+ {0x8241, 0x70},\r
+ {0x8242, 0x26},\r
+ {0x8243, 0x78},\r
+ {0x8244, 0xbb},\r
+ {0x8245, 0xe6},\r
+ {0x8246, 0xff},\r
+ {0x8247, 0xc3},\r
+ {0x8248, 0x78},\r
+ {0x8249, 0xbd},\r
+ {0x824a, 0x12},\r
+ {0x824b, 0x0a},\r
+ {0x824c, 0x84},\r
+ {0x824d, 0x40},\r
+ {0x824e, 0x05},\r
+ {0x824f, 0x12},\r
+ {0x8250, 0x0a},\r
+ {0x8251, 0x7e},\r
+ {0x8252, 0x40},\r
+ {0x8253, 0x09},\r
+ {0x8254, 0x78},\r
+ {0x8255, 0xb6},\r
+ {0x8256, 0xe6},\r
+ {0x8257, 0x78},\r
+ {0x8258, 0xbb},\r
+ {0x8259, 0xf6},\r
+ {0x825a, 0x75},\r
+ {0x825b, 0x1f},\r
+ {0x825c, 0x04},\r
+ {0x825d, 0x78},\r
+ {0x825e, 0xbb},\r
+ {0x825f, 0xe6},\r
+ {0x8260, 0x75},\r
+ {0x8261, 0xf0},\r
+ {0x8262, 0x05},\r
+ {0x8263, 0xa4},\r
+ {0x8264, 0xf5},\r
+ {0x8265, 0x49},\r
+ {0x8266, 0x02},\r
+ {0x8267, 0x08},\r
+ {0x8268, 0x4f},\r
+ {0x8269, 0xe5},\r
+ {0x826a, 0x1f},\r
+ {0x826b, 0xb4},\r
+ {0x826c, 0x04},\r
+ {0x826d, 0x1f},\r
+ {0x826e, 0x90},\r
+ {0x826f, 0x0e},\r
+ {0x8270, 0x89},\r
+ {0x8271, 0xe4},\r
+ {0x8272, 0x78},\r
+ {0x8273, 0xc0},\r
+ {0x8274, 0x12},\r
+ {0x8275, 0x0a},\r
+ {0x8276, 0x8d},\r
+ {0x8277, 0x40},\r
+ {0x8278, 0x02},\r
+ {0x8279, 0xd2},\r
+ {0x827a, 0x36},\r
+ {0x827b, 0x75},\r
+ {0x827c, 0x1f},\r
+ {0x827d, 0x05},\r
+ {0x827e, 0x75},\r
+ {0x827f, 0x34},\r
+ {0x8280, 0xff},\r
+ {0x8281, 0x75},\r
+ {0x8282, 0x35},\r
+ {0x8283, 0x0e},\r
+ {0x8284, 0x75},\r
+ {0x8285, 0x36},\r
+ {0x8286, 0x59},\r
+ {0x8287, 0x75},\r
+ {0x8288, 0x37},\r
+ {0x8289, 0x01},\r
+ {0x828a, 0x12},\r
+ {0x828b, 0x0a},\r
+ {0x828c, 0x3e},\r
+ {0x828d, 0x22},\r
+ {0x828e, 0xef},\r
+ {0x828f, 0x8d},\r
+ {0x8290, 0xf0},\r
+ {0x8291, 0xa4},\r
+ {0x8292, 0xa8},\r
+ {0x8293, 0xf0},\r
+ {0x8294, 0xcf},\r
+ {0x8295, 0x8c},\r
+ {0x8296, 0xf0},\r
+ {0x8297, 0xa4},\r
+ {0x8298, 0x28},\r
+ {0x8299, 0xce},\r
+ {0x829a, 0x8d},\r
+ {0x829b, 0xf0},\r
+ {0x829c, 0xa4},\r
+ {0x829d, 0x2e},\r
+ {0x829e, 0xfe},\r
+ {0x829f, 0x22},\r
+ {0x82a0, 0xbc},\r
+ {0x82a1, 0x00},\r
+ {0x82a2, 0x0b},\r
+ {0x82a3, 0xbe},\r
+ {0x82a4, 0x00},\r
+ {0x82a5, 0x29},\r
+ {0x82a6, 0xef},\r
+ {0x82a7, 0x8d},\r
+ {0x82a8, 0xf0},\r
+ {0x82a9, 0x84},\r
+ {0x82aa, 0xff},\r
+ {0x82ab, 0xad},\r
+ {0x82ac, 0xf0},\r
+ {0x82ad, 0x22},\r
+ {0x82ae, 0xe4},\r
+ {0x82af, 0xcc},\r
+ {0x82b0, 0xf8},\r
+ {0x82b1, 0x75},\r
+ {0x82b2, 0xf0},\r
+ {0x82b3, 0x08},\r
+ {0x82b4, 0xef},\r
+ {0x82b5, 0x2f},\r
+ {0x82b6, 0xff},\r
+ {0x82b7, 0xee},\r
+ {0x82b8, 0x33},\r
+ {0x82b9, 0xfe},\r
+ {0x82ba, 0xec},\r
+ {0x82bb, 0x33},\r
+ {0x82bc, 0xfc},\r
+ {0x82bd, 0xee},\r
+ {0x82be, 0x9d},\r
+ {0x82bf, 0xec},\r
+ {0x82c0, 0x98},\r
+ {0x82c1, 0x40},\r
+ {0x82c2, 0x05},\r
+ {0x82c3, 0xfc},\r
+ {0x82c4, 0xee},\r
+ {0x82c5, 0x9d},\r
+ {0x82c6, 0xfe},\r
+ {0x82c7, 0x0f},\r
+ {0x82c8, 0xd5},\r
+ {0x82c9, 0xf0},\r
+ {0x82ca, 0xe9},\r
+ {0x82cb, 0xe4},\r
+ {0x82cc, 0xce},\r
+ {0x82cd, 0xfd},\r
+ {0x82ce, 0x22},\r
+ {0x82cf, 0xed},\r
+ {0x82d0, 0xf8},\r
+ {0x82d1, 0xf5},\r
+ {0x82d2, 0xf0},\r
+ {0x82d3, 0xee},\r
+ {0x82d4, 0x84},\r
+ {0x82d5, 0x20},\r
+ {0x82d6, 0xd2},\r
+ {0x82d7, 0x1c},\r
+ {0x82d8, 0xfe},\r
+ {0x82d9, 0xad},\r
+ {0x82da, 0xf0},\r
+ {0x82db, 0x75},\r
+ {0x82dc, 0xf0},\r
+ {0x82dd, 0x08},\r
+ {0x82de, 0xef},\r
+ {0x82df, 0x2f},\r
+ {0x82e0, 0xff},\r
+ {0x82e1, 0xed},\r
+ {0x82e2, 0x33},\r
+ {0x82e3, 0xfd},\r
+ {0x82e4, 0x40},\r
+ {0x82e5, 0x07},\r
+ {0x82e6, 0x98},\r
+ {0x82e7, 0x50},\r
+ {0x82e8, 0x06},\r
+ {0x82e9, 0xd5},\r
+ {0x82ea, 0xf0},\r
+ {0x82eb, 0xf2},\r
+ {0x82ec, 0x22},\r
+ {0x82ed, 0xc3},\r
+ {0x82ee, 0x98},\r
+ {0x82ef, 0xfd},\r
+ {0x82f0, 0x0f},\r
+ {0x82f1, 0xd5},\r
+ {0x82f2, 0xf0},\r
+ {0x82f3, 0xea},\r
+ {0x82f4, 0x22},\r
+ {0x82f5, 0xe8},\r
+ {0x82f6, 0x8f},\r
+ {0x82f7, 0xf0},\r
+ {0x82f8, 0xa4},\r
+ {0x82f9, 0xcc},\r
+ {0x82fa, 0x8b},\r
+ {0x82fb, 0xf0},\r
+ {0x82fc, 0xa4},\r
+ {0x82fd, 0x2c},\r
+ {0x82fe, 0xfc},\r
+ {0x82ff, 0xe9},\r
+ {0x8300, 0x8e},\r
+ {0x8301, 0xf0},\r
+ {0x8302, 0xa4},\r
+ {0x8303, 0x2c},\r
+ {0x8304, 0xfc},\r
+ {0x8305, 0x8a},\r
+ {0x8306, 0xf0},\r
+ {0x8307, 0xed},\r
+ {0x8308, 0xa4},\r
+ {0x8309, 0x2c},\r
+ {0x830a, 0xfc},\r
+ {0x830b, 0xea},\r
+ {0x830c, 0x8e},\r
+ {0x830d, 0xf0},\r
+ {0x830e, 0xa4},\r
+ {0x830f, 0xcd},\r
+ {0x8310, 0xa8},\r
+ {0x8311, 0xf0},\r
+ {0x8312, 0x8b},\r
+ {0x8313, 0xf0},\r
+ {0x8314, 0xa4},\r
+ {0x8315, 0x2d},\r
+ {0x8316, 0xcc},\r
+ {0x8317, 0x38},\r
+ {0x8318, 0x25},\r
+ {0x8319, 0xf0},\r
+ {0x831a, 0xfd},\r
+ {0x831b, 0xe9},\r
+ {0x831c, 0x8f},\r
+ {0x831d, 0xf0},\r
+ {0x831e, 0xa4},\r
+ {0x831f, 0x2c},\r
+ {0x8320, 0xcd},\r
+ {0x8321, 0x35},\r
+ {0x8322, 0xf0},\r
+ {0x8323, 0xfc},\r
+ {0x8324, 0xeb},\r
+ {0x8325, 0x8e},\r
+ {0x8326, 0xf0},\r
+ {0x8327, 0xa4},\r
+ {0x8328, 0xfe},\r
+ {0x8329, 0xa9},\r
+ {0x832a, 0xf0},\r
+ {0x832b, 0xeb},\r
+ {0x832c, 0x8f},\r
+ {0x832d, 0xf0},\r
+ {0x832e, 0xa4},\r
+ {0x832f, 0xcf},\r
+ {0x8330, 0xc5},\r
+ {0x8331, 0xf0},\r
+ {0x8332, 0x2e},\r
+ {0x8333, 0xcd},\r
+ {0x8334, 0x39},\r
+ {0x8335, 0xfe},\r
+ {0x8336, 0xe4},\r
+ {0x8337, 0x3c},\r
+ {0x8338, 0xfc},\r
+ {0x8339, 0xea},\r
+ {0x833a, 0xa4},\r
+ {0x833b, 0x2d},\r
+ {0x833c, 0xce},\r
+ {0x833d, 0x35},\r
+ {0x833e, 0xf0},\r
+ {0x833f, 0xfd},\r
+ {0x8340, 0xe4},\r
+ {0x8341, 0x3c},\r
+ {0x8342, 0xfc},\r
+ {0x8343, 0x22},\r
+ {0x8344, 0x75},\r
+ {0x8345, 0xf0},\r
+ {0x8346, 0x08},\r
+ {0x8347, 0x75},\r
+ {0x8348, 0x82},\r
+ {0x8349, 0x00},\r
+ {0x834a, 0xef},\r
+ {0x834b, 0x2f},\r
+ {0x834c, 0xff},\r
+ {0x834d, 0xee},\r
+ {0x834e, 0x33},\r
+ {0x834f, 0xfe},\r
+ {0x8350, 0xcd},\r
+ {0x8351, 0x33},\r
+ {0x8352, 0xcd},\r
+ {0x8353, 0xcc},\r
+ {0x8354, 0x33},\r
+ {0x8355, 0xcc},\r
+ {0x8356, 0xc5},\r
+ {0x8357, 0x82},\r
+ {0x8358, 0x33},\r
+ {0x8359, 0xc5},\r
+ {0x835a, 0x82},\r
+ {0x835b, 0x9b},\r
+ {0x835c, 0xed},\r
+ {0x835d, 0x9a},\r
+ {0x835e, 0xec},\r
+ {0x835f, 0x99},\r
+ {0x8360, 0xe5},\r
+ {0x8361, 0x82},\r
+ {0x8362, 0x98},\r
+ {0x8363, 0x40},\r
+ {0x8364, 0x0c},\r
+ {0x8365, 0xf5},\r
+ {0x8366, 0x82},\r
+ {0x8367, 0xee},\r
+ {0x8368, 0x9b},\r
+ {0x8369, 0xfe},\r
+ {0x836a, 0xed},\r
+ {0x836b, 0x9a},\r
+ {0x836c, 0xfd},\r
+ {0x836d, 0xec},\r
+ {0x836e, 0x99},\r
+ {0x836f, 0xfc},\r
+ {0x8370, 0x0f},\r
+ {0x8371, 0xd5},\r
+ {0x8372, 0xf0},\r
+ {0x8373, 0xd6},\r
+ {0x8374, 0xe4},\r
+ {0x8375, 0xce},\r
+ {0x8376, 0xfb},\r
+ {0x8377, 0xe4},\r
+ {0x8378, 0xcd},\r
+ {0x8379, 0xfa},\r
+ {0x837a, 0xe4},\r
+ {0x837b, 0xcc},\r
+ {0x837c, 0xf9},\r
+ {0x837d, 0xa8},\r
+ {0x837e, 0x82},\r
+ {0x837f, 0x22},\r
+ {0x8380, 0xb8},\r
+ {0x8381, 0x00},\r
+ {0x8382, 0xc1},\r
+ {0x8383, 0xb9},\r
+ {0x8384, 0x00},\r
+ {0x8385, 0x59},\r
+ {0x8386, 0xba},\r
+ {0x8387, 0x00},\r
+ {0x8388, 0x2d},\r
+ {0x8389, 0xec},\r
+ {0x838a, 0x8b},\r
+ {0x838b, 0xf0},\r
+ {0x838c, 0x84},\r
+ {0x838d, 0xcf},\r
+ {0x838e, 0xce},\r
+ {0x838f, 0xcd},\r
+ {0x8390, 0xfc},\r
+ {0x8391, 0xe5},\r
+ {0x8392, 0xf0},\r
+ {0x8393, 0xcb},\r
+ {0x8394, 0xf9},\r
+ {0x8395, 0x78},\r
+ {0x8396, 0x18},\r
+ {0x8397, 0xef},\r
+ {0x8398, 0x2f},\r
+ {0x8399, 0xff},\r
+ {0x839a, 0xee},\r
+ {0x839b, 0x33},\r
+ {0x839c, 0xfe},\r
+ {0x839d, 0xed},\r
+ {0x839e, 0x33},\r
+ {0x839f, 0xfd},\r
+ {0x83a0, 0xec},\r
+ {0x83a1, 0x33},\r
+ {0x83a2, 0xfc},\r
+ {0x83a3, 0xeb},\r
+ {0x83a4, 0x33},\r
+ {0x83a5, 0xfb},\r
+ {0x83a6, 0x10},\r
+ {0x83a7, 0xd7},\r
+ {0x83a8, 0x03},\r
+ {0x83a9, 0x99},\r
+ {0x83aa, 0x40},\r
+ {0x83ab, 0x04},\r
+ {0x83ac, 0xeb},\r
+ {0x83ad, 0x99},\r
+ {0x83ae, 0xfb},\r
+ {0x83af, 0x0f},\r
+ {0x83b0, 0xd8},\r
+ {0x83b1, 0xe5},\r
+ {0x83b2, 0xe4},\r
+ {0x83b3, 0xf9},\r
+ {0x83b4, 0xfa},\r
+ {0x83b5, 0x22},\r
+ {0x83b6, 0x78},\r
+ {0x83b7, 0x18},\r
+ {0x83b8, 0xef},\r
+ {0x83b9, 0x2f},\r
+ {0x83ba, 0xff},\r
+ {0x83bb, 0xee},\r
+ {0x83bc, 0x33},\r
+ {0x83bd, 0xfe},\r
+ {0x83be, 0xed},\r
+ {0x83bf, 0x33},\r
+ {0x83c0, 0xfd},\r
+ {0x83c1, 0xec},\r
+ {0x83c2, 0x33},\r
+ {0x83c3, 0xfc},\r
+ {0x83c4, 0xc9},\r
+ {0x83c5, 0x33},\r
+ {0x83c6, 0xc9},\r
+ {0x83c7, 0x10},\r
+ {0x83c8, 0xd7},\r
+ {0x83c9, 0x05},\r
+ {0x83ca, 0x9b},\r
+ {0x83cb, 0xe9},\r
+ {0x83cc, 0x9a},\r
+ {0x83cd, 0x40},\r
+ {0x83ce, 0x07},\r
+ {0x83cf, 0xec},\r
+ {0x83d0, 0x9b},\r
+ {0x83d1, 0xfc},\r
+ {0x83d2, 0xe9},\r
+ {0x83d3, 0x9a},\r
+ {0x83d4, 0xf9},\r
+ {0x83d5, 0x0f},\r
+ {0x83d6, 0xd8},\r
+ {0x83d7, 0xe0},\r
+ {0x83d8, 0xe4},\r
+ {0x83d9, 0xc9},\r
+ {0x83da, 0xfa},\r
+ {0x83db, 0xe4},\r
+ {0x83dc, 0xcc},\r
+ {0x83dd, 0xfb},\r
+ {0x83de, 0x22},\r
+ {0x83df, 0x75},\r
+ {0x83e0, 0xf0},\r
+ {0x83e1, 0x10},\r
+ {0x83e2, 0xef},\r
+ {0x83e3, 0x2f},\r
+ {0x83e4, 0xff},\r
+ {0x83e5, 0xee},\r
+ {0x83e6, 0x33},\r
+ {0x83e7, 0xfe},\r
+ {0x83e8, 0xed},\r
+ {0x83e9, 0x33},\r
+ {0x83ea, 0xfd},\r
+ {0x83eb, 0xcc},\r
+ {0x83ec, 0x33},\r
+ {0x83ed, 0xcc},\r
+ {0x83ee, 0xc8},\r
+ {0x83ef, 0x33},\r
+ {0x83f0, 0xc8},\r
+ {0x83f1, 0x10},\r
+ {0x83f2, 0xd7},\r
+ {0x83f3, 0x07},\r
+ {0x83f4, 0x9b},\r
+ {0x83f5, 0xec},\r
+ {0x83f6, 0x9a},\r
+ {0x83f7, 0xe8},\r
+ {0x83f8, 0x99},\r
+ {0x83f9, 0x40},\r
+ {0x83fa, 0x0a},\r
+ {0x83fb, 0xed},\r
+ {0x83fc, 0x9b},\r
+ {0x83fd, 0xfd},\r
+ {0x83fe, 0xec},\r
+ {0x83ff, 0x9a},\r
+ {0x8400, 0xfc},\r
+ {0x8401, 0xe8},\r
+ {0x8402, 0x99},\r
+ {0x8403, 0xf8},\r
+ {0x8404, 0x0f},\r
+ {0x8405, 0xd5},\r
+ {0x8406, 0xf0},\r
+ {0x8407, 0xda},\r
+ {0x8408, 0xe4},\r
+ {0x8409, 0xcd},\r
+ {0x840a, 0xfb},\r
+ {0x840b, 0xe4},\r
+ {0x840c, 0xcc},\r
+ {0x840d, 0xfa},\r
+ {0x840e, 0xe4},\r
+ {0x840f, 0xc8},\r
+ {0x8410, 0xf9},\r
+ {0x8411, 0x22},\r
+ {0x8412, 0xeb},\r
+ {0x8413, 0x9f},\r
+ {0x8414, 0xf5},\r
+ {0x8415, 0xf0},\r
+ {0x8416, 0xea},\r
+ {0x8417, 0x9e},\r
+ {0x8418, 0x42},\r
+ {0x8419, 0xf0},\r
+ {0x841a, 0xe9},\r
+ {0x841b, 0x9d},\r
+ {0x841c, 0x42},\r
+ {0x841d, 0xf0},\r
+ {0x841e, 0xe8},\r
+ {0x841f, 0x9c},\r
+ {0x8420, 0x45},\r
+ {0x8421, 0xf0},\r
+ {0x8422, 0x22},\r
+ {0x8423, 0xe8},\r
+ {0x8424, 0x60},\r
+ {0x8425, 0x0f},\r
+ {0x8426, 0xef},\r
+ {0x8427, 0xc3},\r
+ {0x8428, 0x33},\r
+ {0x8429, 0xff},\r
+ {0x842a, 0xee},\r
+ {0x842b, 0x33},\r
+ {0x842c, 0xfe},\r
+ {0x842d, 0xed},\r
+ {0x842e, 0x33},\r
+ {0x842f, 0xfd},\r
+ {0x8430, 0xec},\r
+ {0x8431, 0x33},\r
+ {0x8432, 0xfc},\r
+ {0x8433, 0xd8},\r
+ {0x8434, 0xf1},\r
+ {0x8435, 0x22},\r
+ {0x8436, 0xe4},\r
+ {0x8437, 0x93},\r
+ {0x8438, 0xfc},\r
+ {0x8439, 0x74},\r
+ {0x843a, 0x01},\r
+ {0x843b, 0x93},\r
+ {0x843c, 0xfd},\r
+ {0x843d, 0x74},\r
+ {0x843e, 0x02},\r
+ {0x843f, 0x93},\r
+ {0x8440, 0xfe},\r
+ {0x8441, 0x74},\r
+ {0x8442, 0x03},\r
+ {0x8443, 0x93},\r
+ {0x8444, 0xff},\r
+ {0x8445, 0x22},\r
+ {0x8446, 0xe6},\r
+ {0x8447, 0xfb},\r
+ {0x8448, 0x08},\r
+ {0x8449, 0xe6},\r
+ {0x844a, 0xf9},\r
+ {0x844b, 0x08},\r
+ {0x844c, 0xe6},\r
+ {0x844d, 0xfa},\r
+ {0x844e, 0x08},\r
+ {0x844f, 0xe6},\r
+ {0x8450, 0xcb},\r
+ {0x8451, 0xf8},\r
+ {0x8452, 0x22},\r
+ {0x8453, 0xec},\r
+ {0x8454, 0xf6},\r
+ {0x8455, 0x08},\r
+ {0x8456, 0xed},\r
+ {0x8457, 0xf6},\r
+ {0x8458, 0x08},\r
+ {0x8459, 0xee},\r
+ {0x845a, 0xf6},\r
+ {0x845b, 0x08},\r
+ {0x845c, 0xef},\r
+ {0x845d, 0xf6},\r
+ {0x845e, 0x22},\r
+ {0x845f, 0xa4},\r
+ {0x8460, 0x25},\r
+ {0x8461, 0x82},\r
+ {0x8462, 0xf5},\r
+ {0x8463, 0x82},\r
+ {0x8464, 0xe5},\r
+ {0x8465, 0xf0},\r
+ {0x8466, 0x35},\r
+ {0x8467, 0x83},\r
+ {0x8468, 0xf5},\r
+ {0x8469, 0x83},\r
+ {0x846a, 0x22},\r
+ {0x846b, 0xd0},\r
+ {0x846c, 0x83},\r
+ {0x846d, 0xd0},\r
+ {0x846e, 0x82},\r
+ {0x846f, 0xf8},\r
+ {0x8470, 0xe4},\r
+ {0x8471, 0x93},\r
+ {0x8472, 0x70},\r
+ {0x8473, 0x12},\r
+ {0x8474, 0x74},\r
+ {0x8475, 0x01},\r
+ {0x8476, 0x93},\r
+ {0x8477, 0x70},\r
+ {0x8478, 0x0d},\r
+ {0x8479, 0xa3},\r
+ {0x847a, 0xa3},\r
+ {0x847b, 0x93},\r
+ {0x847c, 0xf8},\r
+ {0x847d, 0x74},\r
+ {0x847e, 0x01},\r
+ {0x847f, 0x93},\r
+ {0x8480, 0xf5},\r
+ {0x8481, 0x82},\r
+ {0x8482, 0x88},\r
+ {0x8483, 0x83},\r
+ {0x8484, 0xe4},\r
+ {0x8485, 0x73},\r
+ {0x8486, 0x74},\r
+ {0x8487, 0x02},\r
+ {0x8488, 0x93},\r
+ {0x8489, 0x68},\r
+ {0x848a, 0x60},\r
+ {0x848b, 0xef},\r
+ {0x848c, 0xa3},\r
+ {0x848d, 0xa3},\r
+ {0x848e, 0xa3},\r
+ {0x848f, 0x80},\r
+ {0x8490, 0xdf},\r
+ {0x8491, 0x90},\r
+ {0x8492, 0x38},\r
+ {0x8493, 0x04},\r
+ {0x8494, 0x78},\r
+ {0x8495, 0x4f},\r
+ {0x8496, 0x12},\r
+ {0x8497, 0x09},\r
+ {0x8498, 0x44},\r
+ {0x8499, 0x90},\r
+ {0x849a, 0x38},\r
+ {0x849b, 0x00},\r
+ {0x849c, 0xe0},\r
+ {0x849d, 0xfe},\r
+ {0x849e, 0xa3},\r
+ {0x849f, 0xe0},\r
+ {0x84a0, 0xfd},\r
+ {0x84a1, 0xed},\r
+ {0x84a2, 0xff},\r
+ {0x84a3, 0xc3},\r
+ {0x84a4, 0x12},\r
+ {0x84a5, 0x08},\r
+ {0x84a6, 0xfd},\r
+ {0x84a7, 0x90},\r
+ {0x84a8, 0x38},\r
+ {0x84a9, 0x10},\r
+ {0x84aa, 0x12},\r
+ {0x84ab, 0x08},\r
+ {0x84ac, 0xf1},\r
+ {0x84ad, 0x90},\r
+ {0x84ae, 0x38},\r
+ {0x84af, 0x06},\r
+ {0x84b0, 0x78},\r
+ {0x84b1, 0x51},\r
+ {0x84b2, 0x12},\r
+ {0x84b3, 0x09},\r
+ {0x84b4, 0x44},\r
+ {0x84b5, 0x90},\r
+ {0x84b6, 0x38},\r
+ {0x84b7, 0x02},\r
+ {0x84b8, 0xe0},\r
+ {0x84b9, 0xfe},\r
+ {0x84ba, 0xa3},\r
+ {0x84bb, 0xe0},\r
+ {0x84bc, 0xfd},\r
+ {0x84bd, 0xed},\r
+ {0x84be, 0xff},\r
+ {0x84bf, 0xc3},\r
+ {0x84c0, 0x12},\r
+ {0x84c1, 0x08},\r
+ {0x84c2, 0xfd},\r
+ {0x84c3, 0x90},\r
+ {0x84c4, 0x38},\r
+ {0x84c5, 0x12},\r
+ {0x84c6, 0x12},\r
+ {0x84c7, 0x08},\r
+ {0x84c8, 0xf1},\r
+ {0x84c9, 0xa3},\r
+ {0x84ca, 0xe0},\r
+ {0x84cb, 0xb4},\r
+ {0x84cc, 0x31},\r
+ {0x84cd, 0x07},\r
+ {0x84ce, 0x78},\r
+ {0x84cf, 0x4f},\r
+ {0x84d0, 0x79},\r
+ {0x84d1, 0x4f},\r
+ {0x84d2, 0x12},\r
+ {0x84d3, 0x09},\r
+ {0x84d4, 0x5a},\r
+ {0x84d5, 0x90},\r
+ {0x84d6, 0x38},\r
+ {0x84d7, 0x14},\r
+ {0x84d8, 0xe0},\r
+ {0x84d9, 0xb4},\r
+ {0x84da, 0x71},\r
+ {0x84db, 0x15},\r
+ {0x84dc, 0x78},\r
+ {0x84dd, 0x4f},\r
+ {0x84de, 0xe6},\r
+ {0x84df, 0xfe},\r
+ {0x84e0, 0x08},\r
+ {0x84e1, 0xe6},\r
+ {0x84e2, 0x78},\r
+ {0x84e3, 0x02},\r
+ {0x84e4, 0xce},\r
+ {0x84e5, 0xc3},\r
+ {0x84e6, 0x13},\r
+ {0x84e7, 0xce},\r
+ {0x84e8, 0x13},\r
+ {0x84e9, 0xd8},\r
+ {0x84ea, 0xf9},\r
+ {0x84eb, 0x79},\r
+ {0x84ec, 0x50},\r
+ {0x84ed, 0xf7},\r
+ {0x84ee, 0xee},\r
+ {0x84ef, 0x19},\r
+ {0x84f0, 0xf7},\r
+ {0x84f1, 0x90},\r
+ {0x84f2, 0x38},\r
+ {0x84f3, 0x15},\r
+ {0x84f4, 0xe0},\r
+ {0x84f5, 0xb4},\r
+ {0x84f6, 0x31},\r
+ {0x84f7, 0x07},\r
+ {0x84f8, 0x78},\r
+ {0x84f9, 0x51},\r
+ {0x84fa, 0x79},\r
+ {0x84fb, 0x51},\r
+ {0x84fc, 0x12},\r
+ {0x84fd, 0x09},\r
+ {0x84fe, 0x5a},\r
+ {0x84ff, 0x90},\r
+ {0x8500, 0x38},\r
+ {0x8501, 0x15},\r
+ {0x8502, 0xe0},\r
+ {0x8503, 0xb4},\r
+ {0x8504, 0x71},\r
+ {0x8505, 0x15},\r
+ {0x8506, 0x78},\r
+ {0x8507, 0x51},\r
+ {0x8508, 0xe6},\r
+ {0x8509, 0xfe},\r
+ {0x850a, 0x08},\r
+ {0x850b, 0xe6},\r
+ {0x850c, 0x78},\r
+ {0x850d, 0x02},\r
+ {0x850e, 0xce},\r
+ {0x850f, 0xc3},\r
+ {0x8510, 0x13},\r
+ {0x8511, 0xce},\r
+ {0x8512, 0x13},\r
+ {0x8513, 0xd8},\r
+ {0x8514, 0xf9},\r
+ {0x8515, 0x79},\r
+ {0x8516, 0x52},\r
+ {0x8517, 0xf7},\r
+ {0x8518, 0xee},\r
+ {0x8519, 0x19},\r
+ {0x851a, 0xf7},\r
+ {0x851b, 0x79},\r
+ {0x851c, 0x4f},\r
+ {0x851d, 0x12},\r
+ {0x851e, 0x09},\r
+ {0x851f, 0x2c},\r
+ {0x8520, 0x09},\r
+ {0x8521, 0x12},\r
+ {0x8522, 0x09},\r
+ {0x8523, 0x2c},\r
+ {0x8524, 0xaf},\r
+ {0x8525, 0x45},\r
+ {0x8526, 0x12},\r
+ {0x8527, 0x08},\r
+ {0x8528, 0xe2},\r
+ {0x8529, 0x7d},\r
+ {0x852a, 0x50},\r
+ {0x852b, 0x12},\r
+ {0x852c, 0x02},\r
+ {0x852d, 0xa0},\r
+ {0x852e, 0x78},\r
+ {0x852f, 0x57},\r
+ {0x8530, 0xa6},\r
+ {0x8531, 0x06},\r
+ {0x8532, 0x08},\r
+ {0x8533, 0xa6},\r
+ {0x8534, 0x07},\r
+ {0x8535, 0xaf},\r
+ {0x8536, 0x43},\r
+ {0x8537, 0x12},\r
+ {0x8538, 0x08},\r
+ {0x8539, 0xe2},\r
+ {0x853a, 0x7d},\r
+ {0x853b, 0x50},\r
+ {0x853c, 0x12},\r
+ {0x853d, 0x02},\r
+ {0x853e, 0xa0},\r
+ {0x853f, 0x78},\r
+ {0x8540, 0x53},\r
+ {0x8541, 0xa6},\r
+ {0x8542, 0x06},\r
+ {0x8543, 0x08},\r
+ {0x8544, 0xa6},\r
+ {0x8545, 0x07},\r
+ {0x8546, 0xaf},\r
+ {0x8547, 0x46},\r
+ {0x8548, 0x78},\r
+ {0x8549, 0x51},\r
+ {0x854a, 0x12},\r
+ {0x854b, 0x08},\r
+ {0x854c, 0xe4},\r
+ {0x854d, 0x7d},\r
+ {0x854e, 0x3c},\r
+ {0x854f, 0x12},\r
+ {0x8550, 0x02},\r
+ {0x8551, 0xa0},\r
+ {0x8552, 0x78},\r
+ {0x8553, 0x59},\r
+ {0x8554, 0xa6},\r
+ {0x8555, 0x06},\r
+ {0x8556, 0x08},\r
+ {0x8557, 0xa6},\r
+ {0x8558, 0x07},\r
+ {0x8559, 0xaf},\r
+ {0x855a, 0x44},\r
+ {0x855b, 0x7e},\r
+ {0x855c, 0x00},\r
+ {0x855d, 0x78},\r
+ {0x855e, 0x51},\r
+ {0x855f, 0x12},\r
+ {0x8560, 0x08},\r
+ {0x8561, 0xe6},\r
+ {0x8562, 0x7d},\r
+ {0x8563, 0x3c},\r
+ {0x8564, 0x12},\r
+ {0x8565, 0x02},\r
+ {0x8566, 0xa0},\r
+ {0x8567, 0x78},\r
+ {0x8568, 0x55},\r
+ {0x8569, 0xa6},\r
+ {0x856a, 0x06},\r
+ {0x856b, 0x08},\r
+ {0x856c, 0xa6},\r
+ {0x856d, 0x07},\r
+ {0x856e, 0xc3},\r
+ {0x856f, 0x78},\r
+ {0x8570, 0x58},\r
+ {0x8571, 0xe6},\r
+ {0x8572, 0x94},\r
+ {0x8573, 0x08},\r
+ {0x8574, 0x18},\r
+ {0x8575, 0xe6},\r
+ {0x8576, 0x94},\r
+ {0x8577, 0x00},\r
+ {0x8578, 0x50},\r
+ {0x8579, 0x05},\r
+ {0x857a, 0x76},\r
+ {0x857b, 0x00},\r
+ {0x857c, 0x08},\r
+ {0x857d, 0x76},\r
+ {0x857e, 0x08},\r
+ {0x857f, 0xc3},\r
+ {0x8580, 0x78},\r
+ {0x8581, 0x5a},\r
+ {0x8582, 0xe6},\r
+ {0x8583, 0x94},\r
+ {0x8584, 0x08},\r
+ {0x8585, 0x18},\r
+ {0x8586, 0xe6},\r
+ {0x8587, 0x94},\r
+ {0x8588, 0x00},\r
+ {0x8589, 0x50},\r
+ {0x858a, 0x05},\r
+ {0x858b, 0x76},\r
+ {0x858c, 0x00},\r
+ {0x858d, 0x08},\r
+ {0x858e, 0x76},\r
+ {0x858f, 0x08},\r
+ {0x8590, 0x78},\r
+ {0x8591, 0x57},\r
+ {0x8592, 0x12},\r
+ {0x8593, 0x09},\r
+ {0x8594, 0x19},\r
+ {0x8595, 0xff},\r
+ {0x8596, 0xd3},\r
+ {0x8597, 0x78},\r
+ {0x8598, 0x54},\r
+ {0x8599, 0xe6},\r
+ {0x859a, 0x9f},\r
+ {0x859b, 0x18},\r
+ {0x859c, 0xe6},\r
+ {0x859d, 0x9e},\r
+ {0x859e, 0x40},\r
+ {0x859f, 0x0e},\r
+ {0x85a0, 0x78},\r
+ {0x85a1, 0x57},\r
+ {0x85a2, 0xe6},\r
+ {0x85a3, 0x13},\r
+ {0x85a4, 0xfe},\r
+ {0x85a5, 0x08},\r
+ {0x85a6, 0xe6},\r
+ {0x85a7, 0x78},\r
+ {0x85a8, 0x54},\r
+ {0x85a9, 0x12},\r
+ {0x85aa, 0x09},\r
+ {0x85ab, 0x4f},\r
+ {0x85ac, 0x80},\r
+ {0x85ad, 0x04},\r
+ {0x85ae, 0x7e},\r
+ {0x85af, 0x00},\r
+ {0x85b0, 0x7f},\r
+ {0x85b1, 0x00},\r
+ {0x85b2, 0x78},\r
+ {0x85b3, 0x5b},\r
+ {0x85b4, 0x12},\r
+ {0x85b5, 0x09},\r
+ {0x85b6, 0x11},\r
+ {0x85b7, 0xff},\r
+ {0x85b8, 0xd3},\r
+ {0x85b9, 0x78},\r
+ {0x85ba, 0x56},\r
+ {0x85bb, 0xe6},\r
+ {0x85bc, 0x9f},\r
+ {0x85bd, 0x18},\r
+ {0x85be, 0xe6},\r
+ {0x85bf, 0x9e},\r
+ {0x85c0, 0x40},\r
+ {0x85c1, 0x0e},\r
+ {0x85c2, 0x78},\r
+ {0x85c3, 0x59},\r
+ {0x85c4, 0xe6},\r
+ {0x85c5, 0x13},\r
+ {0x85c6, 0xfe},\r
+ {0x85c7, 0x08},\r
+ {0x85c8, 0xe6},\r
+ {0x85c9, 0x78},\r
+ {0x85ca, 0x56},\r
+ {0x85cb, 0x12},\r
+ {0x85cc, 0x09},\r
+ {0x85cd, 0x4f},\r
+ {0x85ce, 0x80},\r
+ {0x85cf, 0x04},\r
+ {0x85d0, 0x7e},\r
+ {0x85d1, 0x00},\r
+ {0x85d2, 0x7f},\r
+ {0x85d3, 0x00},\r
+ {0x85d4, 0xe4},\r
+ {0x85d5, 0xfc},\r
+ {0x85d6, 0xfd},\r
+ {0x85d7, 0x78},\r
+ {0x85d8, 0x5f},\r
+ {0x85d9, 0x12},\r
+ {0x85da, 0x04},\r
+ {0x85db, 0x53},\r
+ {0x85dc, 0x78},\r
+ {0x85dd, 0x57},\r
+ {0x85de, 0x12},\r
+ {0x85df, 0x09},\r
+ {0x85e0, 0x19},\r
+ {0x85e1, 0x78},\r
+ {0x85e2, 0x54},\r
+ {0x85e3, 0x26},\r
+ {0x85e4, 0xff},\r
+ {0x85e5, 0xee},\r
+ {0x85e6, 0x18},\r
+ {0x85e7, 0x36},\r
+ {0x85e8, 0xfe},\r
+ {0x85e9, 0x78},\r
+ {0x85ea, 0x63},\r
+ {0x85eb, 0x12},\r
+ {0x85ec, 0x09},\r
+ {0x85ed, 0x11},\r
+ {0x85ee, 0x78},\r
+ {0x85ef, 0x56},\r
+ {0x85f0, 0x26},\r
+ {0x85f1, 0xff},\r
+ {0x85f2, 0xee},\r
+ {0x85f3, 0x18},\r
+ {0x85f4, 0x36},\r
+ {0x85f5, 0xfe},\r
+ {0x85f6, 0xe4},\r
+ {0x85f7, 0xfc},\r
+ {0x85f8, 0xfd},\r
+ {0x85f9, 0x78},\r
+ {0x85fa, 0x67},\r
+ {0x85fb, 0x12},\r
+ {0x85fc, 0x04},\r
+ {0x85fd, 0x53},\r
+ {0x85fe, 0x12},\r
+ {0x85ff, 0x09},\r
+ {0x8600, 0x21},\r
+ {0x8601, 0x78},\r
+ {0x8602, 0x63},\r
+ {0x8603, 0x12},\r
+ {0x8604, 0x04},\r
+ {0x8605, 0x46},\r
+ {0x8606, 0xd3},\r
+ {0x8607, 0x12},\r
+ {0x8608, 0x04},\r
+ {0x8609, 0x12},\r
+ {0x860a, 0x40},\r
+ {0x860b, 0x08},\r
+ {0x860c, 0x12},\r
+ {0x860d, 0x09},\r
+ {0x860e, 0x21},\r
+ {0x860f, 0x78},\r
+ {0x8610, 0x63},\r
+ {0x8611, 0x12},\r
+ {0x8612, 0x04},\r
+ {0x8613, 0x53},\r
+ {0x8614, 0x78},\r
+ {0x8615, 0x51},\r
+ {0x8616, 0x12},\r
+ {0x8617, 0x09},\r
+ {0x8618, 0x23},\r
+ {0x8619, 0x78},\r
+ {0x861a, 0x67},\r
+ {0x861b, 0x12},\r
+ {0x861c, 0x04},\r
+ {0x861d, 0x46},\r
+ {0x861e, 0xd3},\r
+ {0x861f, 0x12},\r
+ {0x8620, 0x04},\r
+ {0x8621, 0x12},\r
+ {0x8622, 0x40},\r
+ {0x8623, 0x0a},\r
+ {0x8624, 0x78},\r
+ {0x8625, 0x51},\r
+ {0x8626, 0x12},\r
+ {0x8627, 0x09},\r
+ {0x8628, 0x23},\r
+ {0x8629, 0x78},\r
+ {0x862a, 0x67},\r
+ {0x862b, 0x12},\r
+ {0x862c, 0x04},\r
+ {0x862d, 0x53},\r
+ {0x862e, 0xe4},\r
+ {0x862f, 0xfd},\r
+ {0x8630, 0x78},\r
+ {0x8631, 0x5e},\r
+ {0x8632, 0x12},\r
+ {0x8633, 0x09},\r
+ {0x8634, 0x3c},\r
+ {0x8635, 0x24},\r
+ {0x8636, 0x01},\r
+ {0x8637, 0x12},\r
+ {0x8638, 0x09},\r
+ {0x8639, 0x05},\r
+ {0x863a, 0x78},\r
+ {0x863b, 0x62},\r
+ {0x863c, 0x12},\r
+ {0x863d, 0x09},\r
+ {0x863e, 0x3c},\r
+ {0x863f, 0x24},\r
+ {0x8640, 0x02},\r
+ {0x8641, 0x12},\r
+ {0x8642, 0x09},\r
+ {0x8643, 0x05},\r
+ {0x8644, 0x78},\r
+ {0x8645, 0x66},\r
+ {0x8646, 0x12},\r
+ {0x8647, 0x09},\r
+ {0x8648, 0x3c},\r
+ {0x8649, 0x24},\r
+ {0x864a, 0x03},\r
+ {0x864b, 0x12},\r
+ {0x864c, 0x09},\r
+ {0x864d, 0x05},\r
+ {0x864e, 0x78},\r
+ {0x864f, 0x6a},\r
+ {0x8650, 0x12},\r
+ {0x8651, 0x09},\r
+ {0x8652, 0x3c},\r
+ {0x8653, 0x24},\r
+ {0x8654, 0x04},\r
+ {0x8655, 0x12},\r
+ {0x8656, 0x09},\r
+ {0x8657, 0x05},\r
+ {0x8658, 0x0d},\r
+ {0x8659, 0xbd},\r
+ {0x865a, 0x05},\r
+ {0x865b, 0xd4},\r
+ {0x865c, 0xc2},\r
+ {0x865d, 0x0e},\r
+ {0x865e, 0xc2},\r
+ {0x865f, 0x06},\r
+ {0x8660, 0x22},\r
+ {0x8661, 0x85},\r
+ {0x8662, 0x08},\r
+ {0x8663, 0x41},\r
+ {0x8664, 0x90},\r
+ {0x8665, 0x30},\r
+ {0x8666, 0x24},\r
+ {0x8667, 0xe0},\r
+ {0x8668, 0xf5},\r
+ {0x8669, 0x3d},\r
+ {0x866a, 0xa3},\r
+ {0x866b, 0xe0},\r
+ {0x866c, 0xf5},\r
+ {0x866d, 0x3e},\r
+ {0x866e, 0xa3},\r
+ {0x866f, 0xe0},\r
+ {0x8670, 0xf5},\r
+ {0x8671, 0x3f},\r
+ {0x8672, 0xa3},\r
+ {0x8673, 0xe0},\r
+ {0x8674, 0xf5},\r
+ {0x8675, 0x40},\r
+ {0x8676, 0xa3},\r
+ {0x8677, 0xe0},\r
+ {0x8678, 0xf5},\r
+ {0x8679, 0x3c},\r
+ {0x867a, 0xd2},\r
+ {0x867b, 0x33},\r
+ {0x867c, 0xe5},\r
+ {0x867d, 0x41},\r
+ {0x867e, 0x12},\r
+ {0x867f, 0x04},\r
+ {0x8680, 0x6b},\r
+ {0x8681, 0x06},\r
+ {0x8682, 0xbe},\r
+ {0x8683, 0x03},\r
+ {0x8684, 0x06},\r
+ {0x8685, 0xc2},\r
+ {0x8686, 0x04},\r
+ {0x8687, 0x06},\r
+ {0x8688, 0xc8},\r
+ {0x8689, 0x07},\r
+ {0x868a, 0x06},\r
+ {0x868b, 0xd1},\r
+ {0x868c, 0x08},\r
+ {0x868d, 0x06},\r
+ {0x868e, 0xe2},\r
+ {0x868f, 0x12},\r
+ {0x8690, 0x06},\r
+ {0x8691, 0xfd},\r
+ {0x8692, 0x18},\r
+ {0x8693, 0x07},\r
+ {0x8694, 0x13},\r
+ {0x8695, 0x19},\r
+ {0x8696, 0x06},\r
+ {0x8697, 0xe8},\r
+ {0x8698, 0x1a},\r
+ {0x8699, 0x06},\r
+ {0x869a, 0xf4},\r
+ {0x869b, 0x1b},\r
+ {0x869c, 0x07},\r
+ {0x869d, 0x37},\r
+ {0x869e, 0x80},\r
+ {0x869f, 0x07},\r
+ {0x86a0, 0x3a},\r
+ {0x86a1, 0x81},\r
+ {0x86a2, 0x07},\r
+ {0x86a3, 0x95},\r
+ {0x86a4, 0x8f},\r
+ {0x86a5, 0x07},\r
+ {0x86a6, 0x84},\r
+ {0x86a7, 0x90},\r
+ {0x86a8, 0x07},\r
+ {0x86a9, 0x95},\r
+ {0x86aa, 0x91},\r
+ {0x86ab, 0x07},\r
+ {0x86ac, 0x95},\r
+ {0x86ad, 0x92},\r
+ {0x86ae, 0x07},\r
+ {0x86af, 0x95},\r
+ {0x86b0, 0x93},\r
+ {0x86b1, 0x07},\r
+ {0x86b2, 0x95},\r
+ {0x86b3, 0x94},\r
+ {0x86b4, 0x07},\r
+ {0x86b5, 0x95},\r
+ {0x86b6, 0x98},\r
+ {0x86b7, 0x07},\r
+ {0x86b8, 0x92},\r
+ {0x86b9, 0x9f},\r
+ {0x86ba, 0x00},\r
+ {0x86bb, 0x00},\r
+ {0x86bc, 0x07},\r
+ {0x86bd, 0xb0},\r
+ {0x86be, 0x12},\r
+ {0x86bf, 0x0a},\r
+ {0x86c0, 0xe8},\r
+ {0x86c1, 0x22},\r
+ {0x86c2, 0x12},\r
+ {0x86c3, 0x0a},\r
+ {0x86c4, 0xe8},\r
+ {0x86c5, 0xd2},\r
+ {0x86c6, 0x03},\r
+ {0x86c7, 0x22},\r
+ {0x86c8, 0xa2},\r
+ {0x86c9, 0x36},\r
+ {0x86ca, 0xe4},\r
+ {0x86cb, 0x33},\r
+ {0x86cc, 0xf5},\r
+ {0x86cd, 0x3c},\r
+ {0x86ce, 0x02},\r
+ {0x86cf, 0x07},\r
+ {0x86d0, 0x95},\r
+ {0x86d1, 0xc2},\r
+ {0x86d2, 0x01},\r
+ {0x86d3, 0xc2},\r
+ {0x86d4, 0x02},\r
+ {0x86d5, 0xc2},\r
+ {0x86d6, 0x03},\r
+ {0x86d7, 0x12},\r
+ {0x86d8, 0x09},\r
+ {0x86d9, 0x64},\r
+ {0x86da, 0x75},\r
+ {0x86db, 0x1e},\r
+ {0x86dc, 0x70},\r
+ {0x86dd, 0xd2},\r
+ {0x86de, 0x34},\r
+ {0x86df, 0x02},\r
+ {0x86e0, 0x07},\r
+ {0x86e1, 0x95},\r
+ {0x86e2, 0x12},\r
+ {0x86e3, 0x04},\r
+ {0x86e4, 0x91},\r
+ {0x86e5, 0x02},\r
+ {0x86e6, 0x07},\r
+ {0x86e7, 0x95},\r
+ {0x86e8, 0x85},\r
+ {0x86e9, 0x40},\r
+ {0x86ea, 0x48},\r
+ {0x86eb, 0x85},\r
+ {0x86ec, 0x3c},\r
+ {0x86ed, 0x49},\r
+ {0x86ee, 0x12},\r
+ {0x86ef, 0x08},\r
+ {0x86f0, 0x4f},\r
+ {0x86f1, 0x02},\r
+ {0x86f2, 0x07},\r
+ {0x86f3, 0x95},\r
+ {0x86f4, 0x85},\r
+ {0x86f5, 0x48},\r
+ {0x86f6, 0x40},\r
+ {0x86f7, 0x85},\r
+ {0x86f8, 0x49},\r
+ {0x86f9, 0x3c},\r
+ {0x86fa, 0x02},\r
+ {0x86fb, 0x07},\r
+ {0x86fc, 0x95},\r
+ {0x86fd, 0xe4},\r
+ {0x86fe, 0xf5},\r
+ {0x86ff, 0x22},\r
+ {0x8700, 0xf5},\r
+ {0x8701, 0x23},\r
+ {0x8702, 0x85},\r
+ {0x8703, 0x40},\r
+ {0x8704, 0x31},\r
+ {0x8705, 0x85},\r
+ {0x8706, 0x3f},\r
+ {0x8707, 0x30},\r
+ {0x8708, 0x85},\r
+ {0x8709, 0x3e},\r
+ {0x870a, 0x2f},\r
+ {0x870b, 0x85},\r
+ {0x870c, 0x3d},\r
+ {0x870d, 0x2e},\r
+ {0x870e, 0x12},\r
+ {0x870f, 0x0a},\r
+ {0x8710, 0xba},\r
+ {0x8711, 0x80},\r
+ {0x8712, 0x1f},\r
+ {0x8713, 0x75},\r
+ {0x8714, 0x22},\r
+ {0x8715, 0x00},\r
+ {0x8716, 0x75},\r
+ {0x8717, 0x23},\r
+ {0x8718, 0x01},\r
+ {0x8719, 0x74},\r
+ {0x871a, 0xff},\r
+ {0x871b, 0xf5},\r
+ {0x871c, 0x2d},\r
+ {0x871d, 0xf5},\r
+ {0x871e, 0x2c},\r
+ {0x871f, 0xf5},\r
+ {0x8720, 0x2b},\r
+ {0x8721, 0xf5},\r
+ {0x8722, 0x2a},\r
+ {0x8723, 0x12},\r
+ {0x8724, 0x0a},\r
+ {0x8725, 0xba},\r
+ {0x8726, 0x85},\r
+ {0x8727, 0x2d},\r
+ {0x8728, 0x40},\r
+ {0x8729, 0x85},\r
+ {0x872a, 0x2c},\r
+ {0x872b, 0x3f},\r
+ {0x872c, 0x85},\r
+ {0x872d, 0x2b},\r
+ {0x872e, 0x3e},\r
+ {0x872f, 0x85},\r
+ {0x8730, 0x2a},\r
+ {0x8731, 0x3d},\r
+ {0x8732, 0xe4},\r
+ {0x8733, 0xf5},\r
+ {0x8734, 0x3c},\r
+ {0x8735, 0x80},\r
+ {0x8736, 0x5e},\r
+ {0x8737, 0x02},\r
+ {0x8738, 0x0b},\r
+ {0x8739, 0x31},\r
+ {0x873a, 0x85},\r
+ {0x873b, 0x3d},\r
+ {0x873c, 0x43},\r
+ {0x873d, 0x85},\r
+ {0x873e, 0x3e},\r
+ {0x873f, 0x44},\r
+ {0x8740, 0xe5},\r
+ {0x8741, 0x45},\r
+ {0x8742, 0xc3},\r
+ {0x8743, 0x13},\r
+ {0x8744, 0xff},\r
+ {0x8745, 0xe5},\r
+ {0x8746, 0x43},\r
+ {0x8747, 0xc3},\r
+ {0x8748, 0x9f},\r
+ {0x8749, 0x50},\r
+ {0x874a, 0x02},\r
+ {0x874b, 0x8f},\r
+ {0x874c, 0x43},\r
+ {0x874d, 0xe5},\r
+ {0x874e, 0x46},\r
+ {0x874f, 0xc3},\r
+ {0x8750, 0x13},\r
+ {0x8751, 0xff},\r
+ {0x8752, 0xe5},\r
+ {0x8753, 0x44},\r
+ {0x8754, 0xc3},\r
+ {0x8755, 0x9f},\r
+ {0x8756, 0x50},\r
+ {0x8757, 0x02},\r
+ {0x8758, 0x8f},\r
+ {0x8759, 0x44},\r
+ {0x875a, 0xe5},\r
+ {0x875b, 0x45},\r
+ {0x875c, 0xc3},\r
+ {0x875d, 0x13},\r
+ {0x875e, 0xff},\r
+ {0x875f, 0xfd},\r
+ {0x8760, 0xe5},\r
+ {0x8761, 0x43},\r
+ {0x8762, 0x90},\r
+ {0x8763, 0x0e},\r
+ {0x8764, 0x7f},\r
+ {0x8765, 0x12},\r
+ {0x8766, 0x0b},\r
+ {0x8767, 0x04},\r
+ {0x8768, 0x40},\r
+ {0x8769, 0x04},\r
+ {0x876a, 0xee},\r
+ {0x876b, 0x9f},\r
+ {0x876c, 0xf5},\r
+ {0x876d, 0x43},\r
+ {0x876e, 0xe5},\r
+ {0x876f, 0x46},\r
+ {0x8770, 0xc3},\r
+ {0x8771, 0x13},\r
+ {0x8772, 0xff},\r
+ {0x8773, 0xfd},\r
+ {0x8774, 0xe5},\r
+ {0x8775, 0x44},\r
+ {0x8776, 0x90},\r
+ {0x8777, 0x0e},\r
+ {0x8778, 0x80},\r
+ {0x8779, 0x12},\r
+ {0x877a, 0x0b},\r
+ {0x877b, 0x04},\r
+ {0x877c, 0x40},\r
+ {0x877d, 0x14},\r
+ {0x877e, 0xee},\r
+ {0x877f, 0x9f},\r
+ {0x8780, 0xf5},\r
+ {0x8781, 0x44},\r
+ {0x8782, 0x80},\r
+ {0x8783, 0x0e},\r
+ {0x8784, 0x85},\r
+ {0x8785, 0x40},\r
+ {0x8786, 0x46},\r
+ {0x8787, 0x85},\r
+ {0x8788, 0x3f},\r
+ {0x8789, 0x45},\r
+ {0x878a, 0x85},\r
+ {0x878b, 0x3e},\r
+ {0x878c, 0x44},\r
+ {0x878d, 0x85},\r
+ {0x878e, 0x3d},\r
+ {0x878f, 0x43},\r
+ {0x8790, 0x80},\r
+ {0x8791, 0x03},\r
+ {0x8792, 0x02},\r
+ {0x8793, 0x04},\r
+ {0x8794, 0x91},\r
+ {0x8795, 0x90},\r
+ {0x8796, 0x30},\r
+ {0x8797, 0x24},\r
+ {0x8798, 0xe5},\r
+ {0x8799, 0x3d},\r
+ {0x879a, 0xf0},\r
+ {0x879b, 0xa3},\r
+ {0x879c, 0xe5},\r
+ {0x879d, 0x3e},\r
+ {0x879e, 0xf0},\r
+ {0x879f, 0xa3},\r
+ {0x87a0, 0xe5},\r
+ {0x87a1, 0x3f},\r
+ {0x87a2, 0xf0},\r
+ {0x87a3, 0xa3},\r
+ {0x87a4, 0xe5},\r
+ {0x87a5, 0x40},\r
+ {0x87a6, 0xf0},\r
+ {0x87a7, 0xa3},\r
+ {0x87a8, 0xe5},\r
+ {0x87a9, 0x3c},\r
+ {0x87aa, 0xf0},\r
+ {0x87ab, 0x90},\r
+ {0x87ac, 0x30},\r
+ {0x87ad, 0x23},\r
+ {0x87ae, 0xe4},\r
+ {0x87af, 0xf0},\r
+ {0x87b0, 0x22},\r
+ {0x87b1, 0xc0},\r
+ {0x87b2, 0xe0},\r
+ {0x87b3, 0xc0},\r
+ {0x87b4, 0x83},\r
+ {0x87b5, 0xc0},\r
+ {0x87b6, 0x82},\r
+ {0x87b7, 0xc0},\r
+ {0x87b8, 0xd0},\r
+ {0x87b9, 0x90},\r
+ {0x87ba, 0x3f},\r
+ {0x87bb, 0x0c},\r
+ {0x87bc, 0xe0},\r
+ {0x87bd, 0xf5},\r
+ {0x87be, 0x32},\r
+ {0x87bf, 0xe5},\r
+ {0x87c0, 0x32},\r
+ {0x87c1, 0x30},\r
+ {0x87c2, 0xe3},\r
+ {0x87c3, 0x4c},\r
+ {0x87c4, 0x30},\r
+ {0x87c5, 0x35},\r
+ {0x87c6, 0x3e},\r
+ {0x87c7, 0x90},\r
+ {0x87c8, 0x60},\r
+ {0x87c9, 0x19},\r
+ {0x87ca, 0xe0},\r
+ {0x87cb, 0xf5},\r
+ {0x87cc, 0x0a},\r
+ {0x87cd, 0xa3},\r
+ {0x87ce, 0xe0},\r
+ {0x87cf, 0xf5},\r
+ {0x87d0, 0x0b},\r
+ {0x87d1, 0x90},\r
+ {0x87d2, 0x60},\r
+ {0x87d3, 0x1d},\r
+ {0x87d4, 0xe0},\r
+ {0x87d5, 0xf5},\r
+ {0x87d6, 0x14},\r
+ {0x87d7, 0xa3},\r
+ {0x87d8, 0xe0},\r
+ {0x87d9, 0xf5},\r
+ {0x87da, 0x15},\r
+ {0x87db, 0x30},\r
+ {0x87dc, 0x01},\r
+ {0x87dd, 0x06},\r
+ {0x87de, 0x30},\r
+ {0x87df, 0x32},\r
+ {0x87e0, 0x03},\r
+ {0x87e1, 0xd3},\r
+ {0x87e2, 0x80},\r
+ {0x87e3, 0x01},\r
+ {0x87e4, 0xc3},\r
+ {0x87e5, 0x92},\r
+ {0x87e6, 0x09},\r
+ {0x87e7, 0x30},\r
+ {0x87e8, 0x02},\r
+ {0x87e9, 0x06},\r
+ {0x87ea, 0x30},\r
+ {0x87eb, 0x32},\r
+ {0x87ec, 0x03},\r
+ {0x87ed, 0xd3},\r
+ {0x87ee, 0x80},\r
+ {0x87ef, 0x01},\r
+ {0x87f0, 0xc3},\r
+ {0x87f1, 0x92},\r
+ {0x87f2, 0x0a},\r
+ {0x87f3, 0x30},\r
+ {0x87f4, 0x32},\r
+ {0x87f5, 0x0c},\r
+ {0x87f6, 0x30},\r
+ {0x87f7, 0x03},\r
+ {0x87f8, 0x09},\r
+ {0x87f9, 0x20},\r
+ {0x87fa, 0x02},\r
+ {0x87fb, 0x06},\r
+ {0x87fc, 0x20},\r
+ {0x87fd, 0x01},\r
+ {0x87fe, 0x03},\r
+ {0x87ff, 0xd3},\r
+ {0x8800, 0x80},\r
+ {0x8801, 0x01},\r
+ {0x8802, 0xc3},\r
+ {0x8803, 0x92},\r
+ {0x8804, 0x0b},\r
+ {0x8805, 0x90},\r
+ {0x8806, 0x30},\r
+ {0x8807, 0x01},\r
+ {0x8808, 0xe0},\r
+ {0x8809, 0x44},\r
+ {0x880a, 0x40},\r
+ {0x880b, 0xf0},\r
+ {0x880c, 0xe0},\r
+ {0x880d, 0x54},\r
+ {0x880e, 0xbf},\r
+ {0x880f, 0xf0},\r
+ {0x8810, 0xe5},\r
+ {0x8811, 0x32},\r
+ {0x8812, 0x30},\r
+ {0x8813, 0xe1},\r
+ {0x8814, 0x14},\r
+ {0x8815, 0x30},\r
+ {0x8816, 0x33},\r
+ {0x8817, 0x11},\r
+ {0x8818, 0x90},\r
+ {0x8819, 0x30},\r
+ {0x881a, 0x22},\r
+ {0x881b, 0xe0},\r
+ {0x881c, 0xf5},\r
+ {0x881d, 0x08},\r
+ {0x881e, 0xe4},\r
+ {0x881f, 0xf0},\r
+ {0x8820, 0x30},\r
+ {0x8821, 0x00},\r
+ {0x8822, 0x03},\r
+ {0x8823, 0xd3},\r
+ {0x8824, 0x80},\r
+ {0x8825, 0x01},\r
+ {0x8826, 0xc3},\r
+ {0x8827, 0x92},\r
+ {0x8828, 0x08},\r
+ {0x8829, 0xe5},\r
+ {0x882a, 0x32},\r
+ {0x882b, 0x30},\r
+ {0x882c, 0xe5},\r
+ {0x882d, 0x12},\r
+ {0x882e, 0x90},\r
+ {0x882f, 0x56},\r
+ {0x8830, 0x90},\r
+ {0x8831, 0xe0},\r
+ {0x8832, 0xf5},\r
+ {0x8833, 0x09},\r
+ {0x8834, 0x30},\r
+ {0x8835, 0x30},\r
+ {0x8836, 0x09},\r
+ {0x8837, 0x30},\r
+ {0x8838, 0x05},\r
+ {0x8839, 0x03},\r
+ {0x883a, 0xd3},\r
+ {0x883b, 0x80},\r
+ {0x883c, 0x01},\r
+ {0x883d, 0xc3},\r
+ {0x883e, 0x92},\r
+ {0x883f, 0x0d},\r
+ {0x8840, 0x90},\r
+ {0x8841, 0x3f},\r
+ {0x8842, 0x0c},\r
+ {0x8843, 0xe5},\r
+ {0x8844, 0x32},\r
+ {0x8845, 0xf0},\r
+ {0x8846, 0xd0},\r
+ {0x8847, 0xd0},\r
+ {0x8848, 0xd0},\r
+ {0x8849, 0x82},\r
+ {0x884a, 0xd0},\r
+ {0x884b, 0x83},\r
+ {0x884c, 0xd0},\r
+ {0x884d, 0xe0},\r
+ {0x884e, 0x32},\r
+ {0x884f, 0x90},\r
+ {0x8850, 0x0e},\r
+ {0x8851, 0x7d},\r
+ {0x8852, 0xe4},\r
+ {0x8853, 0x93},\r
+ {0x8854, 0xfe},\r
+ {0x8855, 0x74},\r
+ {0x8856, 0x01},\r
+ {0x8857, 0x93},\r
+ {0x8858, 0xff},\r
+ {0x8859, 0xc3},\r
+ {0x885a, 0x90},\r
+ {0x885b, 0x0e},\r
+ {0x885c, 0x7b},\r
+ {0x885d, 0x74},\r
+ {0x885e, 0x01},\r
+ {0x885f, 0x93},\r
+ {0x8860, 0x9f},\r
+ {0x8861, 0xff},\r
+ {0x8862, 0xe4},\r
+ {0x8863, 0x93},\r
+ {0x8864, 0x9e},\r
+ {0x8865, 0xfe},\r
+ {0x8866, 0xe4},\r
+ {0x8867, 0x8f},\r
+ {0x8868, 0x3b},\r
+ {0x8869, 0x8e},\r
+ {0x886a, 0x3a},\r
+ {0x886b, 0xf5},\r
+ {0x886c, 0x39},\r
+ {0x886d, 0xf5},\r
+ {0x886e, 0x38},\r
+ {0x886f, 0xab},\r
+ {0x8870, 0x3b},\r
+ {0x8871, 0xaa},\r
+ {0x8872, 0x3a},\r
+ {0x8873, 0xa9},\r
+ {0x8874, 0x39},\r
+ {0x8875, 0xa8},\r
+ {0x8876, 0x38},\r
+ {0x8877, 0xaf},\r
+ {0x8878, 0x49},\r
+ {0x8879, 0xfc},\r
+ {0x887a, 0xfd},\r
+ {0x887b, 0xfe},\r
+ {0x887c, 0x12},\r
+ {0x887d, 0x02},\r
+ {0x887e, 0xf5},\r
+ {0x887f, 0x12},\r
+ {0x8880, 0x0b},\r
+ {0x8881, 0x16},\r
+ {0x8882, 0xe4},\r
+ {0x8883, 0x7b},\r
+ {0x8884, 0xff},\r
+ {0x8885, 0xfa},\r
+ {0x8886, 0xf9},\r
+ {0x8887, 0xf8},\r
+ {0x8888, 0x12},\r
+ {0x8889, 0x03},\r
+ {0x888a, 0x80},\r
+ {0x888b, 0x12},\r
+ {0x888c, 0x0b},\r
+ {0x888d, 0x16},\r
+ {0x888e, 0x90},\r
+ {0x888f, 0x0e},\r
+ {0x8890, 0x69},\r
+ {0x8891, 0xe4},\r
+ {0x8892, 0x12},\r
+ {0x8893, 0x0b},\r
+ {0x8894, 0x2b},\r
+ {0x8895, 0x12},\r
+ {0x8896, 0x0b},\r
+ {0x8897, 0x16},\r
+ {0x8898, 0xe4},\r
+ {0x8899, 0x85},\r
+ {0x889a, 0x48},\r
+ {0x889b, 0x37},\r
+ {0x889c, 0xf5},\r
+ {0x889d, 0x36},\r
+ {0x889e, 0xf5},\r
+ {0x889f, 0x35},\r
+ {0x88a0, 0xf5},\r
+ {0x88a1, 0x34},\r
+ {0x88a2, 0xaf},\r
+ {0x88a3, 0x37},\r
+ {0x88a4, 0xae},\r
+ {0x88a5, 0x36},\r
+ {0x88a6, 0xad},\r
+ {0x88a7, 0x35},\r
+ {0x88a8, 0xac},\r
+ {0x88a9, 0x34},\r
+ {0x88aa, 0xa3},\r
+ {0x88ab, 0x12},\r
+ {0x88ac, 0x0b},\r
+ {0x88ad, 0x2b},\r
+ {0x88ae, 0x8f},\r
+ {0x88af, 0x37},\r
+ {0x88b0, 0x8e},\r
+ {0x88b1, 0x36},\r
+ {0x88b2, 0x8d},\r
+ {0x88b3, 0x35},\r
+ {0x88b4, 0x8c},\r
+ {0x88b5, 0x34},\r
+ {0x88b6, 0xe5},\r
+ {0x88b7, 0x3b},\r
+ {0x88b8, 0x45},\r
+ {0x88b9, 0x37},\r
+ {0x88ba, 0xf5},\r
+ {0x88bb, 0x3b},\r
+ {0x88bc, 0xe5},\r
+ {0x88bd, 0x3a},\r
+ {0x88be, 0x45},\r
+ {0x88bf, 0x36},\r
+ {0x88c0, 0xf5},\r
+ {0x88c1, 0x3a},\r
+ {0x88c2, 0xe5},\r
+ {0x88c3, 0x39},\r
+ {0x88c4, 0x45},\r
+ {0x88c5, 0x35},\r
+ {0x88c6, 0xf5},\r
+ {0x88c7, 0x39},\r
+ {0x88c8, 0xe5},\r
+ {0x88c9, 0x38},\r
+ {0x88ca, 0x45},\r
+ {0x88cb, 0x34},\r
+ {0x88cc, 0xf5},\r
+ {0x88cd, 0x38},\r
+ {0x88ce, 0xe4},\r
+ {0x88cf, 0xf5},\r
+ {0x88d0, 0x22},\r
+ {0x88d1, 0xf5},\r
+ {0x88d2, 0x23},\r
+ {0x88d3, 0x85},\r
+ {0x88d4, 0x3b},\r
+ {0x88d5, 0x31},\r
+ {0x88d6, 0x85},\r
+ {0x88d7, 0x3a},\r
+ {0x88d8, 0x30},\r
+ {0x88d9, 0x85},\r
+ {0x88da, 0x39},\r
+ {0x88db, 0x2f},\r
+ {0x88dc, 0x85},\r
+ {0x88dd, 0x38},\r
+ {0x88de, 0x2e},\r
+ {0x88df, 0x02},\r
+ {0x88e0, 0x0a},\r
+ {0x88e1, 0xba},\r
+ {0x88e2, 0x78},\r
+ {0x88e3, 0x4f},\r
+ {0x88e4, 0x7e},\r
+ {0x88e5, 0x00},\r
+ {0x88e6, 0xe6},\r
+ {0x88e7, 0xfc},\r
+ {0x88e8, 0x08},\r
+ {0x88e9, 0xe6},\r
+ {0x88ea, 0xfd},\r
+ {0x88eb, 0x12},\r
+ {0x88ec, 0x02},\r
+ {0x88ed, 0x8e},\r
+ {0x88ee, 0x7c},\r
+ {0x88ef, 0x00},\r
+ {0x88f0, 0x22},\r
+ {0x88f1, 0xe0},\r
+ {0x88f2, 0xa3},\r
+ {0x88f3, 0xe0},\r
+ {0x88f4, 0x75},\r
+ {0x88f5, 0xf0},\r
+ {0x88f6, 0x02},\r
+ {0x88f7, 0xa4},\r
+ {0x88f8, 0xff},\r
+ {0x88f9, 0xae},\r
+ {0x88fa, 0xf0},\r
+ {0x88fb, 0xc3},\r
+ {0x88fc, 0x08},\r
+ {0x88fd, 0xe6},\r
+ {0x88fe, 0x9f},\r
+ {0x88ff, 0xf6},\r
+ {0x8900, 0x18},\r
+ {0x8901, 0xe6},\r
+ {0x8902, 0x9e},\r
+ {0x8903, 0xf6},\r
+ {0x8904, 0x22},\r
+ {0x8905, 0xff},\r
+ {0x8906, 0xe5},\r
+ {0x8907, 0xf0},\r
+ {0x8908, 0x34},\r
+ {0x8909, 0x60},\r
+ {0x890a, 0x8f},\r
+ {0x890b, 0x82},\r
+ {0x890c, 0xf5},\r
+ {0x890d, 0x83},\r
+ {0x890e, 0xec},\r
+ {0x890f, 0xf0},\r
+ {0x8910, 0x22},\r
+ {0x8911, 0xe4},\r
+ {0x8912, 0xfc},\r
+ {0x8913, 0xfd},\r
+ {0x8914, 0x12},\r
+ {0x8915, 0x04},\r
+ {0x8916, 0x53},\r
+ {0x8917, 0x78},\r
+ {0x8918, 0x59},\r
+ {0x8919, 0xe6},\r
+ {0x891a, 0xc3},\r
+ {0x891b, 0x13},\r
+ {0x891c, 0xfe},\r
+ {0x891d, 0x08},\r
+ {0x891e, 0xe6},\r
+ {0x891f, 0x13},\r
+ {0x8920, 0x22},\r
+ {0x8921, 0x78},\r
+ {0x8922, 0x4f},\r
+ {0x8923, 0xe6},\r
+ {0x8924, 0xfe},\r
+ {0x8925, 0x08},\r
+ {0x8926, 0xe6},\r
+ {0x8927, 0xff},\r
+ {0x8928, 0xe4},\r
+ {0x8929, 0xfc},\r
+ {0x892a, 0xfd},\r
+ {0x892b, 0x22},\r
+ {0x892c, 0xe7},\r
+ {0x892d, 0xc4},\r
+ {0x892e, 0xf8},\r
+ {0x892f, 0x54},\r
+ {0x8930, 0xf0},\r
+ {0x8931, 0xc8},\r
+ {0x8932, 0x68},\r
+ {0x8933, 0xf7},\r
+ {0x8934, 0x09},\r
+ {0x8935, 0xe7},\r
+ {0x8936, 0xc4},\r
+ {0x8937, 0x54},\r
+ {0x8938, 0x0f},\r
+ {0x8939, 0x48},\r
+ {0x893a, 0xf7},\r
+ {0x893b, 0x22},\r
+ {0x893c, 0xe6},\r
+ {0x893d, 0xfc},\r
+ {0x893e, 0xed},\r
+ {0x893f, 0x75},\r
+ {0x8940, 0xf0},\r
+ {0x8941, 0x04},\r
+ {0x8942, 0xa4},\r
+ {0x8943, 0x22},\r
+ {0x8944, 0xe0},\r
+ {0x8945, 0xfe},\r
+ {0x8946, 0xa3},\r
+ {0x8947, 0xe0},\r
+ {0x8948, 0xfd},\r
+ {0x8949, 0xee},\r
+ {0x894a, 0xf6},\r
+ {0x894b, 0xed},\r
+ {0x894c, 0x08},\r
+ {0x894d, 0xf6},\r
+ {0x894e, 0x22},\r
+ {0x894f, 0x13},\r
+ {0x8950, 0xff},\r
+ {0x8951, 0xc3},\r
+ {0x8952, 0xe6},\r
+ {0x8953, 0x9f},\r
+ {0x8954, 0xff},\r
+ {0x8955, 0x18},\r
+ {0x8956, 0xe6},\r
+ {0x8957, 0x9e},\r
+ {0x8958, 0xfe},\r
+ {0x8959, 0x22},\r
+ {0x895a, 0xe6},\r
+ {0x895b, 0xc3},\r
+ {0x895c, 0x13},\r
+ {0x895d, 0xf7},\r
+ {0x895e, 0x08},\r
+ {0x895f, 0xe6},\r
+ {0x8960, 0x13},\r
+ {0x8961, 0x09},\r
+ {0x8962, 0xf7},\r
+ {0x8963, 0x22},\r
+ {0x8964, 0xe4},\r
+ {0x8965, 0xf5},\r
+ {0x8966, 0x49},\r
+ {0x8967, 0x90},\r
+ {0x8968, 0x0e},\r
+ {0x8969, 0x77},\r
+ {0x896a, 0x93},\r
+ {0x896b, 0xff},\r
+ {0x896c, 0xe4},\r
+ {0x896d, 0x8f},\r
+ {0x896e, 0x37},\r
+ {0x896f, 0xf5},\r
+ {0x8970, 0x36},\r
+ {0x8971, 0xf5},\r
+ {0x8972, 0x35},\r
+ {0x8973, 0xf5},\r
+ {0x8974, 0x34},\r
+ {0x8975, 0xaf},\r
+ {0x8976, 0x37},\r
+ {0x8977, 0xae},\r
+ {0x8978, 0x36},\r
+ {0x8979, 0xad},\r
+ {0x897a, 0x35},\r
+ {0x897b, 0xac},\r
+ {0x897c, 0x34},\r
+ {0x897d, 0x90},\r
+ {0x897e, 0x0e},\r
+ {0x897f, 0x6a},\r
+ {0x8980, 0x12},\r
+ {0x8981, 0x0b},\r
+ {0x8982, 0x2b},\r
+ {0x8983, 0x8f},\r
+ {0x8984, 0x37},\r
+ {0x8985, 0x8e},\r
+ {0x8986, 0x36},\r
+ {0x8987, 0x8d},\r
+ {0x8988, 0x35},\r
+ {0x8989, 0x8c},\r
+ {0x898a, 0x34},\r
+ {0x898b, 0x90},\r
+ {0x898c, 0x0e},\r
+ {0x898d, 0x72},\r
+ {0x898e, 0x12},\r
+ {0x898f, 0x04},\r
+ {0x8990, 0x36},\r
+ {0x8991, 0xef},\r
+ {0x8992, 0x45},\r
+ {0x8993, 0x37},\r
+ {0x8994, 0xf5},\r
+ {0x8995, 0x37},\r
+ {0x8996, 0xee},\r
+ {0x8997, 0x45},\r
+ {0x8998, 0x36},\r
+ {0x8999, 0xf5},\r
+ {0x899a, 0x36},\r
+ {0x899b, 0xed},\r
+ {0x899c, 0x45},\r
+ {0x899d, 0x35},\r
+ {0x899e, 0xf5},\r
+ {0x899f, 0x35},\r
+ {0x89a0, 0xec},\r
+ {0x89a1, 0x45},\r
+ {0x89a2, 0x34},\r
+ {0x89a3, 0xf5},\r
+ {0x89a4, 0x34},\r
+ {0x89a5, 0xe4},\r
+ {0x89a6, 0xf5},\r
+ {0x89a7, 0x22},\r
+ {0x89a8, 0xf5},\r
+ {0x89a9, 0x23},\r
+ {0x89aa, 0x85},\r
+ {0x89ab, 0x37},\r
+ {0x89ac, 0x31},\r
+ {0x89ad, 0x85},\r
+ {0x89ae, 0x36},\r
+ {0x89af, 0x30},\r
+ {0x89b0, 0x85},\r
+ {0x89b1, 0x35},\r
+ {0x89b2, 0x2f},\r
+ {0x89b3, 0x85},\r
+ {0x89b4, 0x34},\r
+ {0x89b5, 0x2e},\r
+ {0x89b6, 0x12},\r
+ {0x89b7, 0x0a},\r
+ {0x89b8, 0xba},\r
+ {0x89b9, 0xe4},\r
+ {0x89ba, 0xf5},\r
+ {0x89bb, 0x22},\r
+ {0x89bc, 0xf5},\r
+ {0x89bd, 0x23},\r
+ {0x89be, 0x90},\r
+ {0x89bf, 0x0e},\r
+ {0x89c0, 0x72},\r
+ {0x89c1, 0x12},\r
+ {0x89c2, 0x0b},\r
+ {0x89c3, 0x1f},\r
+ {0x89c4, 0x12},\r
+ {0x89c5, 0x0a},\r
+ {0x89c6, 0xba},\r
+ {0x89c7, 0xe4},\r
+ {0x89c8, 0xf5},\r
+ {0x89c9, 0x22},\r
+ {0x89ca, 0xf5},\r
+ {0x89cb, 0x23},\r
+ {0x89cc, 0x90},\r
+ {0x89cd, 0x0e},\r
+ {0x89ce, 0x6e},\r
+ {0x89cf, 0x12},\r
+ {0x89d0, 0x0b},\r
+ {0x89d1, 0x1f},\r
+ {0x89d2, 0x02},\r
+ {0x89d3, 0x0a},\r
+ {0x89d4, 0xba},\r
+ {0x89d5, 0x75},\r
+ {0x89d6, 0x89},\r
+ {0x89d7, 0x03},\r
+ {0x89d8, 0x75},\r
+ {0x89d9, 0xa8},\r
+ {0x89da, 0x01},\r
+ {0x89db, 0x75},\r
+ {0x89dc, 0xb8},\r
+ {0x89dd, 0x04},\r
+ {0x89de, 0x75},\r
+ {0x89df, 0x34},\r
+ {0x89e0, 0xff},\r
+ {0x89e1, 0x75},\r
+ {0x89e2, 0x35},\r
+ {0x89e3, 0x0e},\r
+ {0x89e4, 0x75},\r
+ {0x89e5, 0x36},\r
+ {0x89e6, 0x15},\r
+ {0x89e7, 0x75},\r
+ {0x89e8, 0x37},\r
+ {0x89e9, 0x0d},\r
+ {0x89ea, 0x12},\r
+ {0x89eb, 0x0a},\r
+ {0x89ec, 0x3e},\r
+ {0x89ed, 0x12},\r
+ {0x89ee, 0x00},\r
+ {0x89ef, 0x09},\r
+ {0x89f0, 0x12},\r
+ {0x89f1, 0x0b},\r
+ {0x89f2, 0x31},\r
+ {0x89f3, 0x12},\r
+ {0x89f4, 0x00},\r
+ {0x89f5, 0x06},\r
+ {0x89f6, 0xd2},\r
+ {0x89f7, 0x00},\r
+ {0x89f8, 0xd2},\r
+ {0x89f9, 0x33},\r
+ {0x89fa, 0xd2},\r
+ {0x89fb, 0xaf},\r
+ {0x89fc, 0x75},\r
+ {0x89fd, 0x34},\r
+ {0x89fe, 0xff},\r
+ {0x89ff, 0x75},\r
+ {0x8a00, 0x35},\r
+ {0x8a01, 0x0e},\r
+ {0x8a02, 0x75},\r
+ {0x8a03, 0x36},\r
+ {0x8a04, 0x49},\r
+ {0x8a05, 0x75},\r
+ {0x8a06, 0x37},\r
+ {0x8a07, 0x03},\r
+ {0x8a08, 0x12},\r
+ {0x8a09, 0x0a},\r
+ {0x8a0a, 0x3e},\r
+ {0x8a0b, 0x30},\r
+ {0x8a0c, 0x08},\r
+ {0x8a0d, 0x09},\r
+ {0x8a0e, 0xc2},\r
+ {0x8a0f, 0x33},\r
+ {0x8a10, 0x12},\r
+ {0x8a11, 0x06},\r
+ {0x8a12, 0x61},\r
+ {0x8a13, 0xc2},\r
+ {0x8a14, 0x08},\r
+ {0x8a15, 0xd2},\r
+ {0x8a16, 0x33},\r
+ {0x8a17, 0x30},\r
+ {0x8a18, 0x09},\r
+ {0x8a19, 0x09},\r
+ {0x8a1a, 0xc2},\r
+ {0x8a1b, 0x35},\r
+ {0x8a1c, 0x12},\r
+ {0x8a1d, 0x00},\r
+ {0x8a1e, 0x0e},\r
+ {0x8a1f, 0xc2},\r
+ {0x8a20, 0x09},\r
+ {0x8a21, 0xd2},\r
+ {0x8a22, 0x35},\r
+ {0x8a23, 0x30},\r
+ {0x8a24, 0x0e},\r
+ {0x8a25, 0x03},\r
+ {0x8a26, 0x12},\r
+ {0x8a27, 0x04},\r
+ {0x8a28, 0x91},\r
+ {0x8a29, 0x30},\r
+ {0x8a2a, 0x34},\r
+ {0x8a2b, 0xdf},\r
+ {0x8a2c, 0x90},\r
+ {0x8a2d, 0x30},\r
+ {0x8a2e, 0x29},\r
+ {0x8a2f, 0xe5},\r
+ {0x8a30, 0x1e},\r
+ {0x8a31, 0xf0},\r
+ {0x8a32, 0xb4},\r
+ {0x8a33, 0x10},\r
+ {0x8a34, 0x05},\r
+ {0x8a35, 0x90},\r
+ {0x8a36, 0x30},\r
+ {0x8a37, 0x23},\r
+ {0x8a38, 0xe4},\r
+ {0x8a39, 0xf0},\r
+ {0x8a3a, 0xc2},\r
+ {0x8a3b, 0x34},\r
+ {0x8a3c, 0x80},\r
+ {0x8a3d, 0xcd},\r
+ {0x8a3e, 0xae},\r
+ {0x8a3f, 0x35},\r
+ {0x8a40, 0xaf},\r
+ {0x8a41, 0x36},\r
+ {0x8a42, 0xe4},\r
+ {0x8a43, 0xfd},\r
+ {0x8a44, 0xed},\r
+ {0x8a45, 0xc3},\r
+ {0x8a46, 0x95},\r
+ {0x8a47, 0x37},\r
+ {0x8a48, 0x50},\r
+ {0x8a49, 0x33},\r
+ {0x8a4a, 0x12},\r
+ {0x8a4b, 0x0b},\r
+ {0x8a4c, 0x78},\r
+ {0x8a4d, 0xe4},\r
+ {0x8a4e, 0x93},\r
+ {0x8a4f, 0xf5},\r
+ {0x8a50, 0x38},\r
+ {0x8a51, 0x74},\r
+ {0x8a52, 0x01},\r
+ {0x8a53, 0x93},\r
+ {0x8a54, 0xf5},\r
+ {0x8a55, 0x39},\r
+ {0x8a56, 0x45},\r
+ {0x8a57, 0x38},\r
+ {0x8a58, 0x60},\r
+ {0x8a59, 0x23},\r
+ {0x8a5a, 0x85},\r
+ {0x8a5b, 0x39},\r
+ {0x8a5c, 0x82},\r
+ {0x8a5d, 0x85},\r
+ {0x8a5e, 0x38},\r
+ {0x8a5f, 0x83},\r
+ {0x8a60, 0xe0},\r
+ {0x8a61, 0xfc},\r
+ {0x8a62, 0x12},\r
+ {0x8a63, 0x0b},\r
+ {0x8a64, 0x78},\r
+ {0x8a65, 0x74},\r
+ {0x8a66, 0x03},\r
+ {0x8a67, 0x93},\r
+ {0x8a68, 0x52},\r
+ {0x8a69, 0x04},\r
+ {0x8a6a, 0x12},\r
+ {0x8a6b, 0x0b},\r
+ {0x8a6c, 0x78},\r
+ {0x8a6d, 0x74},\r
+ {0x8a6e, 0x02},\r
+ {0x8a6f, 0x93},\r
+ {0x8a70, 0x42},\r
+ {0x8a71, 0x04},\r
+ {0x8a72, 0x85},\r
+ {0x8a73, 0x39},\r
+ {0x8a74, 0x82},\r
+ {0x8a75, 0x85},\r
+ {0x8a76, 0x38},\r
+ {0x8a77, 0x83},\r
+ {0x8a78, 0xec},\r
+ {0x8a79, 0xf0},\r
+ {0x8a7a, 0x0d},\r
+ {0x8a7b, 0x80},\r
+ {0x8a7c, 0xc7},\r
+ {0x8a7d, 0x22},\r
+ {0x8a7e, 0x78},\r
+ {0x8a7f, 0xbb},\r
+ {0x8a80, 0xe6},\r
+ {0x8a81, 0xd3},\r
+ {0x8a82, 0x08},\r
+ {0x8a83, 0xff},\r
+ {0x8a84, 0xe6},\r
+ {0x8a85, 0x64},\r
+ {0x8a86, 0x80},\r
+ {0x8a87, 0xf8},\r
+ {0x8a88, 0xef},\r
+ {0x8a89, 0x64},\r
+ {0x8a8a, 0x80},\r
+ {0x8a8b, 0x98},\r
+ {0x8a8c, 0x22},\r
+ {0x8a8d, 0x93},\r
+ {0x8a8e, 0xff},\r
+ {0x8a8f, 0x7e},\r
+ {0x8a90, 0x00},\r
+ {0x8a91, 0xe6},\r
+ {0x8a92, 0xfc},\r
+ {0x8a93, 0x08},\r
+ {0x8a94, 0xe6},\r
+ {0x8a95, 0xfd},\r
+ {0x8a96, 0x12},\r
+ {0x8a97, 0x02},\r
+ {0x8a98, 0x8e},\r
+ {0x8a99, 0x78},\r
+ {0x8a9a, 0xbe},\r
+ {0x8a9b, 0xe6},\r
+ {0x8a9c, 0xfc},\r
+ {0x8a9d, 0x08},\r
+ {0x8a9e, 0xe6},\r
+ {0x8a9f, 0xfd},\r
+ {0x8aa0, 0xd3},\r
+ {0x8aa1, 0xef},\r
+ {0x8aa2, 0x9d},\r
+ {0x8aa3, 0xee},\r
+ {0x8aa4, 0x9c},\r
+ {0x8aa5, 0x22},\r
+ {0x8aa6, 0x78},\r
+ {0x8aa7, 0xba},\r
+ {0x8aa8, 0xd3},\r
+ {0x8aa9, 0xe6},\r
+ {0x8aaa, 0x64},\r
+ {0x8aab, 0x80},\r
+ {0x8aac, 0x94},\r
+ {0x8aad, 0x80},\r
+ {0x8aae, 0x22},\r
+ {0x8aaf, 0x25},\r
+ {0x8ab0, 0xe0},\r
+ {0x8ab1, 0x24},\r
+ {0x8ab2, 0x0a},\r
+ {0x8ab3, 0xf8},\r
+ {0x8ab4, 0xe6},\r
+ {0x8ab5, 0xfe},\r
+ {0x8ab6, 0x08},\r
+ {0x8ab7, 0xe6},\r
+ {0x8ab8, 0xff},\r
+ {0x8ab9, 0x22},\r
+ {0x8aba, 0xa2},\r
+ {0x8abb, 0xaf},\r
+ {0x8abc, 0x92},\r
+ {0x8abd, 0x31},\r
+ {0x8abe, 0xc2},\r
+ {0x8abf, 0xaf},\r
+ {0x8ac0, 0xe5},\r
+ {0x8ac1, 0x23},\r
+ {0x8ac2, 0x45},\r
+ {0x8ac3, 0x22},\r
+ {0x8ac4, 0x90},\r
+ {0x8ac5, 0x0e},\r
+ {0x8ac6, 0x5d},\r
+ {0x8ac7, 0x60},\r
+ {0x8ac8, 0x0b},\r
+ {0x8ac9, 0x12},\r
+ {0x8aca, 0x0b},\r
+ {0x8acb, 0x6d},\r
+ {0x8acc, 0xe0},\r
+ {0x8acd, 0xf5},\r
+ {0x8ace, 0x2c},\r
+ {0x8acf, 0xe0},\r
+ {0x8ad0, 0xf5},\r
+ {0x8ad1, 0x2d},\r
+ {0x8ad2, 0x80},\r
+ {0x8ad3, 0x0f},\r
+ {0x8ad4, 0x12},\r
+ {0x8ad5, 0x0b},\r
+ {0x8ad6, 0x6d},\r
+ {0x8ad7, 0xe5},\r
+ {0x8ad8, 0x30},\r
+ {0x8ad9, 0xf0},\r
+ {0x8ada, 0x90},\r
+ {0x8adb, 0x0e},\r
+ {0x8adc, 0x5f},\r
+ {0x8add, 0x12},\r
+ {0x8ade, 0x0b},\r
+ {0x8adf, 0x6d},\r
+ {0x8ae0, 0xe5},\r
+ {0x8ae1, 0x31},\r
+ {0x8ae2, 0xf0},\r
+ {0x8ae3, 0xa2},\r
+ {0x8ae4, 0x31},\r
+ {0x8ae5, 0x92},\r
+ {0x8ae6, 0xaf},\r
+ {0x8ae7, 0x22},\r
+ {0x8ae8, 0xd2},\r
+ {0x8ae9, 0x01},\r
+ {0x8aea, 0xc2},\r
+ {0x8aeb, 0x02},\r
+ {0x8aec, 0xe4},\r
+ {0x8aed, 0xf5},\r
+ {0x8aee, 0x1f},\r
+ {0x8aef, 0xf5},\r
+ {0x8af0, 0x1e},\r
+ {0x8af1, 0xd2},\r
+ {0x8af2, 0x34},\r
+ {0x8af3, 0xd2},\r
+ {0x8af4, 0x32},\r
+ {0x8af5, 0xd2},\r
+ {0x8af6, 0x35},\r
+ {0x8af7, 0xd2},\r
+ {0x8af8, 0x01},\r
+ {0x8af9, 0xc2},\r
+ {0x8afa, 0x02},\r
+ {0x8afb, 0xf5},\r
+ {0x8afc, 0x1f},\r
+ {0x8afd, 0xf5},\r
+ {0x8afe, 0x1e},\r
+ {0x8aff, 0xd2},\r
+ {0x8b00, 0x34},\r
+ {0x8b01, 0xd2},\r
+ {0x8b02, 0x32},\r
+ {0x8b03, 0x22},\r
+ {0x8b04, 0x2d},\r
+ {0x8b05, 0xfd},\r
+ {0x8b06, 0xe4},\r
+ {0x8b07, 0x33},\r
+ {0x8b08, 0xfc},\r
+ {0x8b09, 0xe4},\r
+ {0x8b0a, 0x93},\r
+ {0x8b0b, 0xfe},\r
+ {0x8b0c, 0xfb},\r
+ {0x8b0d, 0xd3},\r
+ {0x8b0e, 0xed},\r
+ {0x8b0f, 0x9b},\r
+ {0x8b10, 0x74},\r
+ {0x8b11, 0x80},\r
+ {0x8b12, 0xf8},\r
+ {0x8b13, 0x6c},\r
+ {0x8b14, 0x98},\r
+ {0x8b15, 0x22},\r
+ {0x8b16, 0x8f},\r
+ {0x8b17, 0x3b},\r
+ {0x8b18, 0x8e},\r
+ {0x8b19, 0x3a},\r
+ {0x8b1a, 0x8d},\r
+ {0x8b1b, 0x39},\r
+ {0x8b1c, 0x8c},\r
+ {0x8b1d, 0x38},\r
+ {0x8b1e, 0x22},\r
+ {0x8b1f, 0x12},\r
+ {0x8b20, 0x04},\r
+ {0x8b21, 0x36},\r
+ {0x8b22, 0x8f},\r
+ {0x8b23, 0x31},\r
+ {0x8b24, 0x8e},\r
+ {0x8b25, 0x30},\r
+ {0x8b26, 0x8d},\r
+ {0x8b27, 0x2f},\r
+ {0x8b28, 0x8c},\r
+ {0x8b29, 0x2e},\r
+ {0x8b2a, 0x22},\r
+ {0x8b2b, 0x93},\r
+ {0x8b2c, 0xf9},\r
+ {0x8b2d, 0xf8},\r
+ {0x8b2e, 0x02},\r
+ {0x8b2f, 0x04},\r
+ {0x8b30, 0x23},\r
+ {0x8b31, 0x90},\r
+ {0x8b32, 0x0e},\r
+ {0x8b33, 0x81},\r
+ {0x8b34, 0x12},\r
+ {0x8b35, 0x04},\r
+ {0x8b36, 0x36},\r
+ {0x8b37, 0x8f},\r
+ {0x8b38, 0x46},\r
+ {0x8b39, 0x8e},\r
+ {0x8b3a, 0x45},\r
+ {0x8b3b, 0x8d},\r
+ {0x8b3c, 0x44},\r
+ {0x8b3d, 0x8c},\r
+ {0x8b3e, 0x43},\r
+ {0x8b3f, 0xd2},\r
+ {0x8b40, 0x06},\r
+ {0x8b41, 0x30},\r
+ {0x8b42, 0x06},\r
+ {0x8b43, 0x03},\r
+ {0x8b44, 0xd3},\r
+ {0x8b45, 0x80},\r
+ {0x8b46, 0x01},\r
+ {0x8b47, 0xc3},\r
+ {0x8b48, 0x92},\r
+ {0x8b49, 0x0e},\r
+ {0x8b4a, 0x22},\r
+ {0x8b4b, 0xc0},\r
+ {0x8b4c, 0xe0},\r
+ {0x8b4d, 0xc0},\r
+ {0x8b4e, 0x83},\r
+ {0x8b4f, 0xc0},\r
+ {0x8b50, 0x82},\r
+ {0x8b51, 0x90},\r
+ {0x8b52, 0x3f},\r
+ {0x8b53, 0x0d},\r
+ {0x8b54, 0xe0},\r
+ {0x8b55, 0xf5},\r
+ {0x8b56, 0x33},\r
+ {0x8b57, 0xe5},\r
+ {0x8b58, 0x33},\r
+ {0x8b59, 0xf0},\r
+ {0x8b5a, 0xd0},\r
+ {0x8b5b, 0x82},\r
+ {0x8b5c, 0xd0},\r
+ {0x8b5d, 0x83},\r
+ {0x8b5e, 0xd0},\r
+ {0x8b5f, 0xe0},\r
+ {0x8b60, 0x32},\r
+ {0x8b61, 0x78},\r
+ {0x8b62, 0x7f},\r
+ {0x8b63, 0xe4},\r
+ {0x8b64, 0xf6},\r
+ {0x8b65, 0xd8},\r
+ {0x8b66, 0xfd},\r
+ {0x8b67, 0x75},\r
+ {0x8b68, 0x81},\r
+ {0x8b69, 0xca},\r
+ {0x8b6a, 0x02},\r
+ {0x8b6b, 0x09},\r
+ {0x8b6c, 0xd5},\r
+ {0x8b6d, 0xe4},\r
+ {0x8b6e, 0x93},\r
+ {0x8b6f, 0xfe},\r
+ {0x8b70, 0x74},\r
+ {0x8b71, 0x01},\r
+ {0x8b72, 0x93},\r
+ {0x8b73, 0xf5},\r
+ {0x8b74, 0x82},\r
+ {0x8b75, 0x8e},\r
+ {0x8b76, 0x83},\r
+ {0x8b77, 0x22},\r
+ {0x8b78, 0x8f},\r
+ {0x8b79, 0x82},\r
+ {0x8b7a, 0x8e},\r
+ {0x8b7b, 0x83},\r
+ {0x8b7c, 0x75},\r
+ {0x8b7d, 0xf0},\r
+ {0x8b7e, 0x04},\r
+ {0x8b7f, 0xed},\r
+ {0x8b80, 0x02},\r
+ {0x8b81, 0x04},\r
+ {0x8b82, 0x5f},\r
+ {0x8b83, 0x00},\r
+ {0x8b84, 0x00},\r
+ {0x8b85, 0x00},\r
+ {0x8b86, 0x00},\r
+ {0x8b87, 0x00},\r
+ {0x8b88, 0x00},\r
+ {0x8b89, 0x00},\r
+ {0x8b8a, 0x00},\r
+ {0x8b8b, 0x00},\r
+ {0x8b8c, 0x00},\r
+ {0x8b8d, 0x00},\r
+ {0x8b8e, 0x00},\r
+ {0x8b8f, 0x00},\r
+ {0x8b90, 0x00},\r
+ {0x8b91, 0x00},\r
+ {0x8b92, 0x00},\r
+ {0x8b93, 0x00},\r
+ {0x8b94, 0x00},\r
+ {0x8b95, 0x00},\r
+ {0x8b96, 0x00},\r
+ {0x8b97, 0x00},\r
+ {0x8b98, 0x00},\r
+ {0x8b99, 0x00},\r
+ {0x8b9a, 0x00},\r
+ {0x8b9b, 0x00},\r
+ {0x8b9c, 0x00},\r
+ {0x8b9d, 0x00},\r
+ {0x8b9e, 0x00},\r
+ {0x8b9f, 0x00},\r
+ {0x8ba0, 0x00},\r
+ {0x8ba1, 0x00},\r
+ {0x8ba2, 0x00},\r
+ {0x8ba3, 0x00},\r
+ {0x8ba4, 0x00},\r
+ {0x8ba5, 0x00},\r
+ {0x8ba6, 0x00},\r
+ {0x8ba7, 0x00},\r
+ {0x8ba8, 0x00},\r
+ {0x8ba9, 0x00},\r
+ {0x8baa, 0x00},\r
+ {0x8bab, 0x00},\r
+ {0x8bac, 0x00},\r
+ {0x8bad, 0x00},\r
+ {0x8bae, 0x00},\r
+ {0x8baf, 0x00},\r
+ {0x8bb0, 0x00},\r
+ {0x8bb1, 0x00},\r
+ {0x8bb2, 0x00},\r
+ {0x8bb3, 0x00},\r
+ {0x8bb4, 0x00},\r
+ {0x8bb5, 0x00},\r
+ {0x8bb6, 0x00},\r
+ {0x8bb7, 0x00},\r
+ {0x8bb8, 0x00},\r
+ {0x8bb9, 0x00},\r
+ {0x8bba, 0x00},\r
+ {0x8bbb, 0x00},\r
+ {0x8bbc, 0x00},\r
+ {0x8bbd, 0x00},\r
+ {0x8bbe, 0x00},\r
+ {0x8bbf, 0x00},\r
+ {0x8bc0, 0x00},\r
+ {0x8bc1, 0x00},\r
+ {0x8bc2, 0x00},\r
+ {0x8bc3, 0x00},\r
+ {0x8bc4, 0x00},\r
+ {0x8bc5, 0x00},\r
+ {0x8bc6, 0x00},\r
+ {0x8bc7, 0x00},\r
+ {0x8bc8, 0x00},\r
+ {0x8bc9, 0x00},\r
+ {0x8bca, 0x00},\r
+ {0x8bcb, 0x00},\r
+ {0x8bcc, 0x00},\r
+ {0x8bcd, 0x00},\r
+ {0x8bce, 0x00},\r
+ {0x8bcf, 0x00},\r
+ {0x8bd0, 0x00},\r
+ {0x8bd1, 0x00},\r
+ {0x8bd2, 0x00},\r
+ {0x8bd3, 0x00},\r
+ {0x8bd4, 0x00},\r
+ {0x8bd5, 0x00},\r
+ {0x8bd6, 0x00},\r
+ {0x8bd7, 0x00},\r
+ {0x8bd8, 0x00},\r
+ {0x8bd9, 0x00},\r
+ {0x8bda, 0x00},\r
+ {0x8bdb, 0x00},\r
+ {0x8bdc, 0x00},\r
+ {0x8bdd, 0x00},\r
+ {0x8bde, 0x00},\r
+ {0x8bdf, 0x00},\r
+ {0x8be0, 0x00},\r
+ {0x8be1, 0x00},\r
+ {0x8be2, 0x00},\r
+ {0x8be3, 0x00},\r
+ {0x8be4, 0x00},\r
+ {0x8be5, 0x00},\r
+ {0x8be6, 0x00},\r
+ {0x8be7, 0x00},\r
+ {0x8be8, 0x00},\r
+ {0x8be9, 0x00},\r
+ {0x8bea, 0x00},\r
+ {0x8beb, 0x00},\r
+ {0x8bec, 0x00},\r
+ {0x8bed, 0x00},\r
+ {0x8bee, 0x00},\r
+ {0x8bef, 0x00},\r
+ {0x8bf0, 0x00},\r
+ {0x8bf1, 0x00},\r
+ {0x8bf2, 0x00},\r
+ {0x8bf3, 0x00},\r
+ {0x8bf4, 0x00},\r
+ {0x8bf5, 0x00},\r
+ {0x8bf6, 0x00},\r
+ {0x8bf7, 0x00},\r
+ {0x8bf8, 0x00},\r
+ {0x8bf9, 0x00},\r
+ {0x8bfa, 0x00},\r
+ {0x8bfb, 0x00},\r
+ {0x8bfc, 0x00},\r
+ {0x8bfd, 0x00},\r
+ {0x8bfe, 0x00},\r
+ {0x8bff, 0x00},\r
+ {0x8c00, 0x00},\r
+ {0x8c01, 0x00},\r
+ {0x8c02, 0x00},\r
+ {0x8c03, 0x00},\r
+ {0x8c04, 0x00},\r
+ {0x8c05, 0x00},\r
+ {0x8c06, 0x00},\r
+ {0x8c07, 0x00},\r
+ {0x8c08, 0x00},\r
+ {0x8c09, 0x00},\r
+ {0x8c0a, 0x00},\r
+ {0x8c0b, 0x00},\r
+ {0x8c0c, 0x00},\r
+ {0x8c0d, 0x00},\r
+ {0x8c0e, 0x00},\r
+ {0x8c0f, 0x00},\r
+ {0x8c10, 0x00},\r
+ {0x8c11, 0x00},\r
+ {0x8c12, 0x00},\r
+ {0x8c13, 0x00},\r
+ {0x8c14, 0x00},\r
+ {0x8c15, 0x00},\r
+ {0x8c16, 0x00},\r
+ {0x8c17, 0x00},\r
+ {0x8c18, 0x00},\r
+ {0x8c19, 0x00},\r
+ {0x8c1a, 0x00},\r
+ {0x8c1b, 0x00},\r
+ {0x8c1c, 0x00},\r
+ {0x8c1d, 0x00},\r
+ {0x8c1e, 0x00},\r
+ {0x8c1f, 0x00},\r
+ {0x8c20, 0x00},\r
+ {0x8c21, 0x00},\r
+ {0x8c22, 0x00},\r
+ {0x8c23, 0x00},\r
+ {0x8c24, 0x00},\r
+ {0x8c25, 0x00},\r
+ {0x8c26, 0x00},\r
+ {0x8c27, 0x00},\r
+ {0x8c28, 0x00},\r
+ {0x8c29, 0x00},\r
+ {0x8c2a, 0x00},\r
+ {0x8c2b, 0x00},\r
+ {0x8c2c, 0x00},\r
+ {0x8c2d, 0x00},\r
+ {0x8c2e, 0x00},\r
+ {0x8c2f, 0x00},\r
+ {0x8c30, 0x00},\r
+ {0x8c31, 0x00},\r
+ {0x8c32, 0x00},\r
+ {0x8c33, 0x00},\r
+ {0x8c34, 0x00},\r
+ {0x8c35, 0x00},\r
+ {0x8c36, 0x00},\r
+ {0x8c37, 0x00},\r
+ {0x8c38, 0x00},\r
+ {0x8c39, 0x00},\r
+ {0x8c3a, 0x00},\r
+ {0x8c3b, 0x00},\r
+ {0x8c3c, 0x00},\r
+ {0x8c3d, 0x00},\r
+ {0x8c3e, 0x00},\r
+ {0x8c3f, 0x00},\r
+ {0x8c40, 0x00},\r
+ {0x8c41, 0x00},\r
+ {0x8c42, 0x00},\r
+ {0x8c43, 0x00},\r
+ {0x8c44, 0x00},\r
+ {0x8c45, 0x00},\r
+ {0x8c46, 0x00},\r
+ {0x8c47, 0x00},\r
+ {0x8c48, 0x00},\r
+ {0x8c49, 0x00},\r
+ {0x8c4a, 0x00},\r
+ {0x8c4b, 0x00},\r
+ {0x8c4c, 0x00},\r
+ {0x8c4d, 0x00},\r
+ {0x8c4e, 0x00},\r
+ {0x8c4f, 0x00},\r
+ {0x8c50, 0x00},\r
+ {0x8c51, 0x00},\r
+ {0x8c52, 0x00},\r
+ {0x8c53, 0x00},\r
+ {0x8c54, 0x00},\r
+ {0x8c55, 0x00},\r
+ {0x8c56, 0x00},\r
+ {0x8c57, 0x00},\r
+ {0x8c58, 0x00},\r
+ {0x8c59, 0x00},\r
+ {0x8c5a, 0x00},\r
+ {0x8c5b, 0x00},\r
+ {0x8c5c, 0x00},\r
+ {0x8c5d, 0x00},\r
+ {0x8c5e, 0x00},\r
+ {0x8c5f, 0x00},\r
+ {0x8c60, 0x00},\r
+ {0x8c61, 0x00},\r
+ {0x8c62, 0x00},\r
+ {0x8c63, 0x00},\r
+ {0x8c64, 0x00},\r
+ {0x8c65, 0x00},\r
+ {0x8c66, 0x00},\r
+ {0x8c67, 0x00},\r
+ {0x8c68, 0x00},\r
+ {0x8c69, 0x00},\r
+ {0x8c6a, 0x00},\r
+ {0x8c6b, 0x00},\r
+ {0x8c6c, 0x00},\r
+ {0x8c6d, 0x00},\r
+ {0x8c6e, 0x00},\r
+ {0x8c6f, 0x00},\r
+ {0x8c70, 0x00},\r
+ {0x8c71, 0x00},\r
+ {0x8c72, 0x00},\r
+ {0x8c73, 0x00},\r
+ {0x8c74, 0x00},\r
+ {0x8c75, 0x00},\r
+ {0x8c76, 0x00},\r
+ {0x8c77, 0x00},\r
+ {0x8c78, 0x00},\r
+ {0x8c79, 0x00},\r
+ {0x8c7a, 0x00},\r
+ {0x8c7b, 0x00},\r
+ {0x8c7c, 0x00},\r
+ {0x8c7d, 0x00},\r
+ {0x8c7e, 0x00},\r
+ {0x8c7f, 0x00},\r
+ {0x8c80, 0x00},\r
+ {0x8c81, 0x00},\r
+ {0x8c82, 0x00},\r
+ {0x8c83, 0x00},\r
+ {0x8c84, 0x00},\r
+ {0x8c85, 0x00},\r
+ {0x8c86, 0x00},\r
+ {0x8c87, 0x00},\r
+ {0x8c88, 0x00},\r
+ {0x8c89, 0x00},\r
+ {0x8c8a, 0x00},\r
+ {0x8c8b, 0x00},\r
+ {0x8c8c, 0x00},\r
+ {0x8c8d, 0x00},\r
+ {0x8c8e, 0x00},\r
+ {0x8c8f, 0x00},\r
+ {0x8c90, 0x00},\r
+ {0x8c91, 0x00},\r
+ {0x8c92, 0x00},\r
+ {0x8c93, 0x00},\r
+ {0x8c94, 0x00},\r
+ {0x8c95, 0x00},\r
+ {0x8c96, 0x00},\r
+ {0x8c97, 0x00},\r
+ {0x8c98, 0x00},\r
+ {0x8c99, 0x00},\r
+ {0x8c9a, 0x00},\r
+ {0x8c9b, 0x00},\r
+ {0x8c9c, 0x00},\r
+ {0x8c9d, 0x00},\r
+ {0x8c9e, 0x00},\r
+ {0x8c9f, 0x00},\r
+ {0x8ca0, 0x00},\r
+ {0x8ca1, 0x00},\r
+ {0x8ca2, 0x00},\r
+ {0x8ca3, 0x00},\r
+ {0x8ca4, 0x00},\r
+ {0x8ca5, 0x00},\r
+ {0x8ca6, 0x00},\r
+ {0x8ca7, 0x00},\r
+ {0x8ca8, 0x00},\r
+ {0x8ca9, 0x00},\r
+ {0x8caa, 0x00},\r
+ {0x8cab, 0x00},\r
+ {0x8cac, 0x00},\r
+ {0x8cad, 0x00},\r
+ {0x8cae, 0x00},\r
+ {0x8caf, 0x00},\r
+ {0x8cb0, 0x00},\r
+ {0x8cb1, 0x00},\r
+ {0x8cb2, 0x00},\r
+ {0x8cb3, 0x00},\r
+ {0x8cb4, 0x00},\r
+ {0x8cb5, 0x00},\r
+ {0x8cb6, 0x00},\r
+ {0x8cb7, 0x00},\r
+ {0x8cb8, 0x00},\r
+ {0x8cb9, 0x00},\r
+ {0x8cba, 0x00},\r
+ {0x8cbb, 0x00},\r
+ {0x8cbc, 0x00},\r
+ {0x8cbd, 0x00},\r
+ {0x8cbe, 0x00},\r
+ {0x8cbf, 0x00},\r
+ {0x8cc0, 0x00},\r
+ {0x8cc1, 0x00},\r
+ {0x8cc2, 0x00},\r
+ {0x8cc3, 0x00},\r
+ {0x8cc4, 0x00},\r
+ {0x8cc5, 0x00},\r
+ {0x8cc6, 0x00},\r
+ {0x8cc7, 0x00},\r
+ {0x8cc8, 0x00},\r
+ {0x8cc9, 0x00},\r
+ {0x8cca, 0x00},\r
+ {0x8ccb, 0x00},\r
+ {0x8ccc, 0x00},\r
+ {0x8ccd, 0x00},\r
+ {0x8cce, 0x00},\r
+ {0x8ccf, 0x00},\r
+ {0x8cd0, 0x00},\r
+ {0x8cd1, 0x00},\r
+ {0x8cd2, 0x00},\r
+ {0x8cd3, 0x00},\r
+ {0x8cd4, 0x00},\r
+ {0x8cd5, 0x00},\r
+ {0x8cd6, 0x00},\r
+ {0x8cd7, 0x00},\r
+ {0x8cd8, 0x00},\r
+ {0x8cd9, 0x00},\r
+ {0x8cda, 0x00},\r
+ {0x8cdb, 0x00},\r
+ {0x8cdc, 0x00},\r
+ {0x8cdd, 0x00},\r
+ {0x8cde, 0x00},\r
+ {0x8cdf, 0x00},\r
+ {0x8ce0, 0x00},\r
+ {0x8ce1, 0x00},\r
+ {0x8ce2, 0x00},\r
+ {0x8ce3, 0x00},\r
+ {0x8ce4, 0x00},\r
+ {0x8ce5, 0x00},\r
+ {0x8ce6, 0x00},\r
+ {0x8ce7, 0x00},\r
+ {0x8ce8, 0x00},\r
+ {0x8ce9, 0x00},\r
+ {0x8cea, 0x00},\r
+ {0x8ceb, 0x00},\r
+ {0x8cec, 0x00},\r
+ {0x8ced, 0x00},\r
+ {0x8cee, 0x00},\r
+ {0x8cef, 0x00},\r
+ {0x8cf0, 0x00},\r
+ {0x8cf1, 0x00},\r
+ {0x8cf2, 0x00},\r
+ {0x8cf3, 0x00},\r
+ {0x8cf4, 0x00},\r
+ {0x8cf5, 0x00},\r
+ {0x8cf6, 0x00},\r
+ {0x8cf7, 0x00},\r
+ {0x8cf8, 0x00},\r
+ {0x8cf9, 0x00},\r
+ {0x8cfa, 0x00},\r
+ {0x8cfb, 0x00},\r
+ {0x8cfc, 0x00},\r
+ {0x8cfd, 0x00},\r
+ {0x8cfe, 0x00},\r
+ {0x8cff, 0x00},\r
+ {0x8d00, 0x00},\r
+ {0x8d01, 0x00},\r
+ {0x8d02, 0x00},\r
+ {0x8d03, 0x00},\r
+ {0x8d04, 0x00},\r
+ {0x8d05, 0x00},\r
+ {0x8d06, 0x00},\r
+ {0x8d07, 0x00},\r
+ {0x8d08, 0x00},\r
+ {0x8d09, 0x00},\r
+ {0x8d0a, 0x00},\r
+ {0x8d0b, 0x00},\r
+ {0x8d0c, 0x00},\r
+ {0x8d0d, 0x00},\r
+ {0x8d0e, 0x00},\r
+ {0x8d0f, 0x00},\r
+ {0x8d10, 0x00},\r
+ {0x8d11, 0x00},\r
+ {0x8d12, 0x00},\r
+ {0x8d13, 0x00},\r
+ {0x8d14, 0x00},\r
+ {0x8d15, 0x00},\r
+ {0x8d16, 0x00},\r
+ {0x8d17, 0x00},\r
+ {0x8d18, 0x00},\r
+ {0x8d19, 0x00},\r
+ {0x8d1a, 0x00},\r
+ {0x8d1b, 0x00},\r
+ {0x8d1c, 0x00},\r
+ {0x8d1d, 0x00},\r
+ {0x8d1e, 0x00},\r
+ {0x8d1f, 0x00},\r
+ {0x8d20, 0x00},\r
+ {0x8d21, 0x00},\r
+ {0x8d22, 0x00},\r
+ {0x8d23, 0x00},\r
+ {0x8d24, 0x00},\r
+ {0x8d25, 0x00},\r
+ {0x8d26, 0x00},\r
+ {0x8d27, 0x00},\r
+ {0x8d28, 0x00},\r
+ {0x8d29, 0x00},\r
+ {0x8d2a, 0x00},\r
+ {0x8d2b, 0x00},\r
+ {0x8d2c, 0x00},\r
+ {0x8d2d, 0x00},\r
+ {0x8d2e, 0x00},\r
+ {0x8d2f, 0x00},\r
+ {0x8d30, 0x00},\r
+ {0x8d31, 0x00},\r
+ {0x8d32, 0x00},\r
+ {0x8d33, 0x00},\r
+ {0x8d34, 0x00},\r
+ {0x8d35, 0x00},\r
+ {0x8d36, 0x00},\r
+ {0x8d37, 0x00},\r
+ {0x8d38, 0x00},\r
+ {0x8d39, 0x00},\r
+ {0x8d3a, 0x00},\r
+ {0x8d3b, 0x00},\r
+ {0x8d3c, 0x00},\r
+ {0x8d3d, 0x00},\r
+ {0x8d3e, 0x00},\r
+ {0x8d3f, 0x00},\r
+ {0x8d40, 0x00},\r
+ {0x8d41, 0x00},\r
+ {0x8d42, 0x00},\r
+ {0x8d43, 0x00},\r
+ {0x8d44, 0x00},\r
+ {0x8d45, 0x00},\r
+ {0x8d46, 0x00},\r
+ {0x8d47, 0x00},\r
+ {0x8d48, 0x00},\r
+ {0x8d49, 0x00},\r
+ {0x8d4a, 0x00},\r
+ {0x8d4b, 0x00},\r
+ {0x8d4c, 0x00},\r
+ {0x8d4d, 0x00},\r
+ {0x8d4e, 0x00},\r
+ {0x8d4f, 0x00},\r
+ {0x8d50, 0x00},\r
+ {0x8d51, 0x00},\r
+ {0x8d52, 0x00},\r
+ {0x8d53, 0x00},\r
+ {0x8d54, 0x00},\r
+ {0x8d55, 0x00},\r
+ {0x8d56, 0x00},\r
+ {0x8d57, 0x00},\r
+ {0x8d58, 0x00},\r
+ {0x8d59, 0x00},\r
+ {0x8d5a, 0x00},\r
+ {0x8d5b, 0x00},\r
+ {0x8d5c, 0x00},\r
+ {0x8d5d, 0x00},\r
+ {0x8d5e, 0x00},\r
+ {0x8d5f, 0x00},\r
+ {0x8d60, 0x00},\r
+ {0x8d61, 0x00},\r
+ {0x8d62, 0x00},\r
+ {0x8d63, 0x00},\r
+ {0x8d64, 0x00},\r
+ {0x8d65, 0x00},\r
+ {0x8d66, 0x00},\r
+ {0x8d67, 0x00},\r
+ {0x8d68, 0x00},\r
+ {0x8d69, 0x00},\r
+ {0x8d6a, 0x00},\r
+ {0x8d6b, 0x00},\r
+ {0x8d6c, 0x00},\r
+ {0x8d6d, 0x00},\r
+ {0x8d6e, 0x00},\r
+ {0x8d6f, 0x00},\r
+ {0x8d70, 0x00},\r
+ {0x8d71, 0x00},\r
+ {0x8d72, 0x00},\r
+ {0x8d73, 0x00},\r
+ {0x8d74, 0x00},\r
+ {0x8d75, 0x00},\r
+ {0x8d76, 0x00},\r
+ {0x8d77, 0x00},\r
+ {0x8d78, 0x00},\r
+ {0x8d79, 0x00},\r
+ {0x8d7a, 0x00},\r
+ {0x8d7b, 0x00},\r
+ {0x8d7c, 0x00},\r
+ {0x8d7d, 0x00},\r
+ {0x8d7e, 0x00},\r
+ {0x8d7f, 0x00},\r
+ {0x8d80, 0x00},\r
+ {0x8d81, 0x00},\r
+ {0x8d82, 0x00},\r
+ {0x8d83, 0x00},\r
+ {0x8d84, 0x00},\r
+ {0x8d85, 0x00},\r
+ {0x8d86, 0x00},\r
+ {0x8d87, 0x00},\r
+ {0x8d88, 0x00},\r
+ {0x8d89, 0x00},\r
+ {0x8d8a, 0x00},\r
+ {0x8d8b, 0x00},\r
+ {0x8d8c, 0x00},\r
+ {0x8d8d, 0x00},\r
+ {0x8d8e, 0x00},\r
+ {0x8d8f, 0x00},\r
+ {0x8d90, 0x00},\r
+ {0x8d91, 0x00},\r
+ {0x8d92, 0x00},\r
+ {0x8d93, 0x00},\r
+ {0x8d94, 0x00},\r
+ {0x8d95, 0x00},\r
+ {0x8d96, 0x00},\r
+ {0x8d97, 0x00},\r
+ {0x8d98, 0x00},\r
+ {0x8d99, 0x00},\r
+ {0x8d9a, 0x00},\r
+ {0x8d9b, 0x00},\r
+ {0x8d9c, 0x00},\r
+ {0x8d9d, 0x00},\r
+ {0x8d9e, 0x00},\r
+ {0x8d9f, 0x00},\r
+ {0x8da0, 0x00},\r
+ {0x8da1, 0x00},\r
+ {0x8da2, 0x00},\r
+ {0x8da3, 0x00},\r
+ {0x8da4, 0x00},\r
+ {0x8da5, 0x00},\r
+ {0x8da6, 0x00},\r
+ {0x8da7, 0x00},\r
+ {0x8da8, 0x00},\r
+ {0x8da9, 0x00},\r
+ {0x8daa, 0x00},\r
+ {0x8dab, 0x00},\r
+ {0x8dac, 0x00},\r
+ {0x8dad, 0x00},\r
+ {0x8dae, 0x00},\r
+ {0x8daf, 0x00},\r
+ {0x8db0, 0x00},\r
+ {0x8db1, 0x00},\r
+ {0x8db2, 0x00},\r
+ {0x8db3, 0x00},\r
+ {0x8db4, 0x00},\r
+ {0x8db5, 0x00},\r
+ {0x8db6, 0x00},\r
+ {0x8db7, 0x00},\r
+ {0x8db8, 0x00},\r
+ {0x8db9, 0x00},\r
+ {0x8dba, 0x00},\r
+ {0x8dbb, 0x00},\r
+ {0x8dbc, 0x00},\r
+ {0x8dbd, 0x00},\r
+ {0x8dbe, 0x00},\r
+ {0x8dbf, 0x00},\r
+ {0x8dc0, 0x00},\r
+ {0x8dc1, 0x00},\r
+ {0x8dc2, 0x00},\r
+ {0x8dc3, 0x00},\r
+ {0x8dc4, 0x00},\r
+ {0x8dc5, 0x00},\r
+ {0x8dc6, 0x00},\r
+ {0x8dc7, 0x00},\r
+ {0x8dc8, 0x00},\r
+ {0x8dc9, 0x00},\r
+ {0x8dca, 0x00},\r
+ {0x8dcb, 0x00},\r
+ {0x8dcc, 0x00},\r
+ {0x8dcd, 0x00},\r
+ {0x8dce, 0x00},\r
+ {0x8dcf, 0x00},\r
+ {0x8dd0, 0x00},\r
+ {0x8dd1, 0x00},\r
+ {0x8dd2, 0x00},\r
+ {0x8dd3, 0x00},\r
+ {0x8dd4, 0x00},\r
+ {0x8dd5, 0x00},\r
+ {0x8dd6, 0x00},\r
+ {0x8dd7, 0x00},\r
+ {0x8dd8, 0x00},\r
+ {0x8dd9, 0x00},\r
+ {0x8dda, 0x00},\r
+ {0x8ddb, 0x00},\r
+ {0x8ddc, 0x00},\r
+ {0x8ddd, 0x00},\r
+ {0x8dde, 0x00},\r
+ {0x8ddf, 0x00},\r
+ {0x8de0, 0x00},\r
+ {0x8de1, 0x00},\r
+ {0x8de2, 0x00},\r
+ {0x8de3, 0x00},\r
+ {0x8de4, 0x00},\r
+ {0x8de5, 0x00},\r
+ {0x8de6, 0x00},\r
+ {0x8de7, 0x00},\r
+ {0x8de8, 0x00},\r
+ {0x8de9, 0x00},\r
+ {0x8dea, 0x00},\r
+ {0x8deb, 0x00},\r
+ {0x8dec, 0x00},\r
+ {0x8ded, 0x00},\r
+ {0x8dee, 0x00},\r
+ {0x8def, 0x00},\r
+ {0x8df0, 0x00},\r
+ {0x8df1, 0x00},\r
+ {0x8df2, 0x00},\r
+ {0x8df3, 0x00},\r
+ {0x8df4, 0x00},\r
+ {0x8df5, 0x00},\r
+ {0x8df6, 0x00},\r
+ {0x8df7, 0x00},\r
+ {0x8df8, 0x00},\r
+ {0x8df9, 0x00},\r
+ {0x8dfa, 0x00},\r
+ {0x8dfb, 0x00},\r
+ {0x8dfc, 0x00},\r
+ {0x8dfd, 0x00},\r
+ {0x8dfe, 0x00},\r
+ {0x8dff, 0x00},\r
+ {0x8e00, 0x11},\r
+ {0x8e01, 0x04},\r
+ {0x8e02, 0x21},\r
+ {0x8e03, 0x15},\r
+ {0x8e04, 0x12},\r
+ {0x8e05, 0x52},\r
+ {0x8e06, 0x4f},\r
+ {0x8e07, 0x56},\r
+ {0x8e08, 0x54},\r
+ {0x8e09, 0x20},\r
+ {0x8e0a, 0x20},\r
+ {0x8e0b, 0x20},\r
+ {0x8e0c, 0x20},\r
+ {0x8e0d, 0x20},\r
+ {0x8e0e, 0x10},\r
+ {0x8e0f, 0x01},\r
+ {0x8e10, 0x10},\r
+ {0x8e11, 0x00},\r
+ {0x8e12, 0x56},\r
+ {0x8e13, 0x40},\r
+ {0x8e14, 0x1a},\r
+ {0x8e15, 0x30},\r
+ {0x8e16, 0x29},\r
+ {0x8e17, 0x7e},\r
+ {0x8e18, 0x00},\r
+ {0x8e19, 0x30},\r
+ {0x8e1a, 0x04},\r
+ {0x8e1b, 0x20},\r
+ {0x8e1c, 0xdf},\r
+ {0x8e1d, 0x30},\r
+ {0x8e1e, 0x05},\r
+ {0x8e1f, 0x40},\r
+ {0x8e20, 0xbf},\r
+ {0x8e21, 0x50},\r
+ {0x8e22, 0x25},\r
+ {0x8e23, 0x04},\r
+ {0x8e24, 0xfb},\r
+ {0x8e25, 0x50},\r
+ {0x8e26, 0x03},\r
+ {0x8e27, 0x00},\r
+ {0x8e28, 0xfd},\r
+ {0x8e29, 0x50},\r
+ {0x8e2a, 0x27},\r
+ {0x8e2b, 0x01},\r
+ {0x8e2c, 0xfe},\r
+ {0x8e2d, 0x60},\r
+ {0x8e2e, 0x00},\r
+ {0x8e2f, 0x11},\r
+ {0x8e30, 0x00},\r
+ {0x8e31, 0x3f},\r
+ {0x8e32, 0x05},\r
+ {0x8e33, 0x30},\r
+ {0x8e34, 0x00},\r
+ {0x8e35, 0x3f},\r
+ {0x8e36, 0x06},\r
+ {0x8e37, 0x22},\r
+ {0x8e38, 0x00},\r
+ {0x8e39, 0x3f},\r
+ {0x8e3a, 0x01},\r
+ {0x8e3b, 0x29},\r
+ {0x8e3c, 0x00},\r
+ {0x8e3d, 0x3f},\r
+ {0x8e3e, 0x02},\r
+ {0x8e3f, 0x00},\r
+ {0x8e40, 0x00},\r
+ {0x8e41, 0x36},\r
+ {0x8e42, 0x06},\r
+ {0x8e43, 0x07},\r
+ {0x8e44, 0x00},\r
+ {0x8e45, 0x3f},\r
+ {0x8e46, 0x0b},\r
+ {0x8e47, 0x0f},\r
+ {0x8e48, 0xf0},\r
+ {0x8e49, 0x30},\r
+ {0x8e4a, 0x01},\r
+ {0x8e4b, 0x40},\r
+ {0x8e4c, 0xbf},\r
+ {0x8e4d, 0x30},\r
+ {0x8e4e, 0x01},\r
+ {0x8e4f, 0x00},\r
+ {0x8e50, 0xbf},\r
+ {0x8e51, 0x30},\r
+ {0x8e52, 0x29},\r
+ {0x8e53, 0x70},\r
+ {0x8e54, 0x00},\r
+ {0x8e55, 0x3a},\r
+ {0x8e56, 0x00},\r
+ {0x8e57, 0x00},\r
+ {0x8e58, 0xff},\r
+ {0x8e59, 0x3a},\r
+ {0x8e5a, 0x00},\r
+ {0x8e5b, 0x00},\r
+ {0x8e5c, 0xff},\r
+ {0x8e5d, 0x36},\r
+ {0x8e5e, 0x03},\r
+ {0x8e5f, 0x36},\r
+ {0x8e60, 0x02},\r
+ {0x8e61, 0x41},\r
+ {0x8e62, 0x44},\r
+ {0x8e63, 0x58},\r
+ {0x8e64, 0x20},\r
+ {0x8e65, 0x18},\r
+ {0x8e66, 0x10},\r
+ {0x8e67, 0x0a},\r
+ {0x8e68, 0x04},\r
+ {0x8e69, 0x04},\r
+ {0x8e6a, 0x00},\r
+ {0x8e6b, 0x03},\r
+ {0x8e6c, 0xff},\r
+ {0x8e6d, 0x64},\r
+ {0x8e6e, 0x00},\r
+ {0x8e6f, 0x00},\r
+ {0x8e70, 0x80},\r
+ {0x8e71, 0x00},\r
+ {0x8e72, 0x00},\r
+ {0x8e73, 0x00},\r
+ {0x8e74, 0x00},\r
+ {0x8e75, 0x00},\r
+ {0x8e76, 0x00},\r
+ {0x8e77, 0x02},\r
+ {0x8e78, 0x04},\r
+ {0x8e79, 0x06},\r
+ {0x8e7a, 0x00},\r
+ {0x8e7b, 0x03},\r
+ {0x8e7c, 0x98},\r
+ {0x8e7d, 0x00},\r
+ {0x8e7e, 0xcc},\r
+ {0x8e7f, 0x50},\r
+ {0x8e80, 0x3c},\r
+ {0x8e81, 0x28},\r
+ {0x8e82, 0x1e},\r
+ {0x8e83, 0x10},\r
+ {0x8e84, 0x10},\r
+ {0x8e85, 0x00},\r
+ {0x8e86, 0x00},\r
+ {0x8e87, 0x00},\r
+ {0x8e88, 0x6e},\r
+ {0x8e89, 0x06},\r
+ {0x8e8a, 0x05},\r
+ {0x8e8b, 0x00},\r
+ {0x8e8c, 0xa5},\r
+ {0x8e8d, 0x5a},\r
+ {0x3022, 0x00},\r
+ {0x3023, 0x00},\r
+ {0x3024, 0x00},\r
+ {0x3025, 0x00},\r
+ {0x3026, 0x00},\r
+ {0x3027, 0x00},\r
+ {0x3028, 0x00},\r
+ {0x3029, 0xFF},\r
+ {0x3000, 0x00},\r
+#elif 0 // ddl@rock-chips.com : Touch Focus from OVT\r
+ {0x3000,0x20},\r
+{0x8000,0x02},\r
+{0x8001,0x0f},\r
+{0x8002,0xd6},\r
+{0x8003,0x02},\r
+{0x8004,0x0a},\r
+{0x8005,0x39},\r
+{0x8006,0xc2},\r
+{0x8007,0x01},\r
+{0x8008,0x22},\r
+{0x8009,0x22},\r
+{0x800a,0x00},\r
+{0x800b,0x02},\r
+{0x800c,0x0f},\r
+{0x800d,0xb2},\r
+{0x800e,0xe5},\r
+{0x800f,0x1f},\r
+{0x8010,0x70},\r
+{0x8011,0x72},\r
+{0x8012,0xf5},\r
+{0x8013,0x1e},\r
+{0x8014,0xd2},\r
+{0x8015,0x35},\r
+{0x8016,0xff},\r
+{0x8017,0xef},\r
+{0x8018,0x25},\r
+{0x8019,0xe0},\r
+{0x801a,0x24},\r
+{0x801b,0x4e},\r
+{0x801c,0xf8},\r
+{0x801d,0xe4},\r
+{0x801e,0xf6},\r
+{0x801f,0x08},\r
+{0x8020,0xf6},\r
+{0x8021,0x0f},\r
+{0x8022,0xbf},\r
+{0x8023,0x34},\r
+{0x8024,0xf2},\r
+{0x8025,0x90},\r
+{0x8026,0x0e},\r
+{0x8027,0x93},\r
+{0x8028,0xe4},\r
+{0x8029,0x93},\r
+{0x802a,0xff},\r
+{0x802b,0xe5},\r
+{0x802c,0x4b},\r
+{0x802d,0xc3},\r
+{0x802e,0x9f},\r
+{0x802f,0x50},\r
+{0x8030,0x04},\r
+{0x8031,0x7f},\r
+{0x8032,0x05},\r
+{0x8033,0x80},\r
+{0x8034,0x02},\r
+{0x8035,0x7f},\r
+{0x8036,0xfb},\r
+{0x8037,0x78},\r
+{0x8038,0xbd},\r
+{0x8039,0xa6},\r
+{0x803a,0x07},\r
+{0x803b,0x12},\r
+{0x803c,0x0f},\r
+{0x803d,0x04},\r
+{0x803e,0x40},\r
+{0x803f,0x04},\r
+{0x8040,0x7f},\r
+{0x8041,0x03},\r
+{0x8042,0x80},\r
+{0x8043,0x02},\r
+{0x8044,0x7f},\r
+{0x8045,0x30},\r
+{0x8046,0x78},\r
+{0x8047,0xbc},\r
+{0x8048,0xa6},\r
+{0x8049,0x07},\r
+{0x804a,0xe6},\r
+{0x804b,0x18},\r
+{0x804c,0xf6},\r
+{0x804d,0x08},\r
+{0x804e,0xe6},\r
+{0x804f,0x78},\r
+{0x8050,0xb9},\r
+{0x8051,0xf6},\r
+{0x8052,0x78},\r
+{0x8053,0xbc},\r
+{0x8054,0xe6},\r
+{0x8055,0x78},\r
+{0x8056,0xba},\r
+{0x8057,0xf6},\r
+{0x8058,0x78},\r
+{0x8059,0xbf},\r
+{0x805a,0x76},\r
+{0x805b,0x33},\r
+{0x805c,0xe4},\r
+{0x805d,0x08},\r
+{0x805e,0xf6},\r
+{0x805f,0x78},\r
+{0x8060,0xb8},\r
+{0x8061,0x76},\r
+{0x8062,0x01},\r
+{0x8063,0x75},\r
+{0x8064,0x4a},\r
+{0x8065,0x02},\r
+{0x8066,0x78},\r
+{0x8067,0xb6},\r
+{0x8068,0xf6},\r
+{0x8069,0x08},\r
+{0x806a,0xf6},\r
+{0x806b,0x74},\r
+{0x806c,0xff},\r
+{0x806d,0x78},\r
+{0x806e,0xc1},\r
+{0x806f,0xf6},\r
+{0x8070,0x08},\r
+{0x8071,0xf6},\r
+{0x8072,0x75},\r
+{0x8073,0x1f},\r
+{0x8074,0x01},\r
+{0x8075,0x78},\r
+{0x8076,0xbc},\r
+{0x8077,0xe6},\r
+{0x8078,0x75},\r
+{0x8079,0xf0},\r
+{0x807a,0x05},\r
+{0x807b,0xa4},\r
+{0x807c,0xf5},\r
+{0x807d,0x4b},\r
+{0x807e,0x12},\r
+{0x807f,0x0a},\r
+{0x8080,0xff},\r
+{0x8081,0xc2},\r
+{0x8082,0x37},\r
+{0x8083,0x22},\r
+{0x8084,0x78},\r
+{0x8085,0xb8},\r
+{0x8086,0xe6},\r
+{0x8087,0xd3},\r
+{0x8088,0x94},\r
+{0x8089,0x00},\r
+{0x808a,0x40},\r
+{0x808b,0x02},\r
+{0x808c,0x16},\r
+{0x808d,0x22},\r
+{0x808e,0xe5},\r
+{0x808f,0x1f},\r
+{0x8090,0xb4},\r
+{0x8091,0x05},\r
+{0x8092,0x23},\r
+{0x8093,0xe4},\r
+{0x8094,0xf5},\r
+{0x8095,0x1f},\r
+{0x8096,0xc2},\r
+{0x8097,0x01},\r
+{0x8098,0x78},\r
+{0x8099,0xb6},\r
+{0x809a,0xe6},\r
+{0x809b,0xfe},\r
+{0x809c,0x08},\r
+{0x809d,0xe6},\r
+{0x809e,0xff},\r
+{0x809f,0x78},\r
+{0x80a0,0x4e},\r
+{0x80a1,0xa6},\r
+{0x80a2,0x06},\r
+{0x80a3,0x08},\r
+{0x80a4,0xa6},\r
+{0x80a5,0x07},\r
+{0x80a6,0xa2},\r
+{0x80a7,0x37},\r
+{0x80a8,0xe4},\r
+{0x80a9,0x33},\r
+{0x80aa,0xf5},\r
+{0x80ab,0x3c},\r
+{0x80ac,0x90},\r
+{0x80ad,0x30},\r
+{0x80ae,0x28},\r
+{0x80af,0xf0},\r
+{0x80b0,0x75},\r
+{0x80b1,0x1e},\r
+{0x80b2,0x10},\r
+{0x80b3,0xd2},\r
+{0x80b4,0x35},\r
+{0x80b5,0x22},\r
+{0x80b6,0xe5},\r
+{0x80b7,0x4b},\r
+{0x80b8,0x75},\r
+{0x80b9,0xf0},\r
+{0x80ba,0x05},\r
+{0x80bb,0x84},\r
+{0x80bc,0x78},\r
+{0x80bd,0xbc},\r
+{0x80be,0xf6},\r
+{0x80bf,0x90},\r
+{0x80c0,0x0e},\r
+{0x80c1,0x8c},\r
+{0x80c2,0xe4},\r
+{0x80c3,0x93},\r
+{0x80c4,0xff},\r
+{0x80c5,0x25},\r
+{0x80c6,0xe0},\r
+{0x80c7,0x24},\r
+{0x80c8,0x0a},\r
+{0x80c9,0xf8},\r
+{0x80ca,0xe6},\r
+{0x80cb,0xfc},\r
+{0x80cc,0x08},\r
+{0x80cd,0xe6},\r
+{0x80ce,0xfd},\r
+{0x80cf,0x78},\r
+{0x80d0,0xbc},\r
+{0x80d1,0xe6},\r
+{0x80d2,0x25},\r
+{0x80d3,0xe0},\r
+{0x80d4,0x24},\r
+{0x80d5,0x4e},\r
+{0x80d6,0xf8},\r
+{0x80d7,0xa6},\r
+{0x80d8,0x04},\r
+{0x80d9,0x08},\r
+{0x80da,0xa6},\r
+{0x80db,0x05},\r
+{0x80dc,0xef},\r
+{0x80dd,0x12},\r
+{0x80de,0x0f},\r
+{0x80df,0x0b},\r
+{0x80e0,0xd3},\r
+{0x80e1,0x78},\r
+{0x80e2,0xb7},\r
+{0x80e3,0x96},\r
+{0x80e4,0xee},\r
+{0x80e5,0x18},\r
+{0x80e6,0x96},\r
+{0x80e7,0x40},\r
+{0x80e8,0x0d},\r
+{0x80e9,0x78},\r
+{0x80ea,0xbc},\r
+{0x80eb,0xe6},\r
+{0x80ec,0x78},\r
+{0x80ed,0xb9},\r
+{0x80ee,0xf6},\r
+{0x80ef,0x78},\r
+{0x80f0,0xb6},\r
+{0x80f1,0xa6},\r
+{0x80f2,0x06},\r
+{0x80f3,0x08},\r
+{0x80f4,0xa6},\r
+{0x80f5,0x07},\r
+{0x80f6,0x90},\r
+{0x80f7,0x0e},\r
+{0x80f8,0x8c},\r
+{0x80f9,0xe4},\r
+{0x80fa,0x93},\r
+{0x80fb,0x12},\r
+{0x80fc,0x0f},\r
+{0x80fd,0x0b},\r
+{0x80fe,0xc3},\r
+{0x80ff,0x78},\r
+{0x8100,0xc2},\r
+{0x8101,0x96},\r
+{0x8102,0xee},\r
+{0x8103,0x18},\r
+{0x8104,0x96},\r
+{0x8105,0x50},\r
+{0x8106,0x0d},\r
+{0x8107,0x78},\r
+{0x8108,0xbc},\r
+{0x8109,0xe6},\r
+{0x810a,0x78},\r
+{0x810b,0xba},\r
+{0x810c,0xf6},\r
+{0x810d,0x78},\r
+{0x810e,0xc1},\r
+{0x810f,0xa6},\r
+{0x8110,0x06},\r
+{0x8111,0x08},\r
+{0x8112,0xa6},\r
+{0x8113,0x07},\r
+{0x8114,0x78},\r
+{0x8115,0xb6},\r
+{0x8116,0xe6},\r
+{0x8117,0xfe},\r
+{0x8118,0x08},\r
+{0x8119,0xe6},\r
+{0x811a,0xc3},\r
+{0x811b,0x78},\r
+{0x811c,0xc2},\r
+{0x811d,0x96},\r
+{0x811e,0xff},\r
+{0x811f,0xee},\r
+{0x8120,0x18},\r
+{0x8121,0x96},\r
+{0x8122,0x78},\r
+{0x8123,0xc3},\r
+{0x8124,0xf6},\r
+{0x8125,0x08},\r
+{0x8126,0xa6},\r
+{0x8127,0x07},\r
+{0x8128,0x90},\r
+{0x8129,0x0e},\r
+{0x812a,0x95},\r
+{0x812b,0xe4},\r
+{0x812c,0x18},\r
+{0x812d,0x12},\r
+{0x812e,0x0e},\r
+{0x812f,0xe9},\r
+{0x8130,0x40},\r
+{0x8131,0x02},\r
+{0x8132,0xd2},\r
+{0x8133,0x37},\r
+{0x8134,0x78},\r
+{0x8135,0xbc},\r
+{0x8136,0xe6},\r
+{0x8137,0x08},\r
+{0x8138,0x26},\r
+{0x8139,0x08},\r
+{0x813a,0xf6},\r
+{0x813b,0xe5},\r
+{0x813c,0x1f},\r
+{0x813d,0x64},\r
+{0x813e,0x01},\r
+{0x813f,0x70},\r
+{0x8140,0x4a},\r
+{0x8141,0xe6},\r
+{0x8142,0xc3},\r
+{0x8143,0x78},\r
+{0x8144,0xc0},\r
+{0x8145,0x12},\r
+{0x8146,0x0e},\r
+{0x8147,0xdf},\r
+{0x8148,0x40},\r
+{0x8149,0x05},\r
+{0x814a,0x12},\r
+{0x814b,0x0e},\r
+{0x814c,0xda},\r
+{0x814d,0x40},\r
+{0x814e,0x39},\r
+{0x814f,0x12},\r
+{0x8150,0x0f},\r
+{0x8151,0x02},\r
+{0x8152,0x40},\r
+{0x8153,0x04},\r
+{0x8154,0x7f},\r
+{0x8155,0xfe},\r
+{0x8156,0x80},\r
+{0x8157,0x02},\r
+{0x8158,0x7f},\r
+{0x8159,0x02},\r
+{0x815a,0x78},\r
+{0x815b,0xbd},\r
+{0x815c,0xa6},\r
+{0x815d,0x07},\r
+{0x815e,0x78},\r
+{0x815f,0xb9},\r
+{0x8160,0xe6},\r
+{0x8161,0x24},\r
+{0x8162,0x03},\r
+{0x8163,0x78},\r
+{0x8164,0xbf},\r
+{0x8165,0xf6},\r
+{0x8166,0x78},\r
+{0x8167,0xb9},\r
+{0x8168,0xe6},\r
+{0x8169,0x24},\r
+{0x816a,0xfd},\r
+{0x816b,0x78},\r
+{0x816c,0xc0},\r
+{0x816d,0xf6},\r
+{0x816e,0x12},\r
+{0x816f,0x0f},\r
+{0x8170,0x02},\r
+{0x8171,0x40},\r
+{0x8172,0x06},\r
+{0x8173,0x78},\r
+{0x8174,0xc0},\r
+{0x8175,0xe6},\r
+{0x8176,0xff},\r
+{0x8177,0x80},\r
+{0x8178,0x04},\r
+{0x8179,0x78},\r
+{0x817a,0xbf},\r
+{0x817b,0xe6},\r
+{0x817c,0xff},\r
+{0x817d,0x78},\r
+{0x817e,0xbe},\r
+{0x817f,0xa6},\r
+{0x8180,0x07},\r
+{0x8181,0x75},\r
+{0x8182,0x1f},\r
+{0x8183,0x02},\r
+{0x8184,0x78},\r
+{0x8185,0xb8},\r
+{0x8186,0x76},\r
+{0x8187,0x01},\r
+{0x8188,0x02},\r
+{0x8189,0x02},\r
+{0x818a,0x4a},\r
+{0x818b,0xe5},\r
+{0x818c,0x1f},\r
+{0x818d,0x64},\r
+{0x818e,0x02},\r
+{0x818f,0x60},\r
+{0x8190,0x03},\r
+{0x8191,0x02},\r
+{0x8192,0x02},\r
+{0x8193,0x2a},\r
+{0x8194,0x78},\r
+{0x8195,0xbe},\r
+{0x8196,0xe6},\r
+{0x8197,0xff},\r
+{0x8198,0xc3},\r
+{0x8199,0x78},\r
+{0x819a,0xc0},\r
+{0x819b,0x12},\r
+{0x819c,0x0e},\r
+{0x819d,0xe0},\r
+{0x819e,0x40},\r
+{0x819f,0x08},\r
+{0x81a0,0x12},\r
+{0x81a1,0x0e},\r
+{0x81a2,0xda},\r
+{0x81a3,0x50},\r
+{0x81a4,0x03},\r
+{0x81a5,0x02},\r
+{0x81a6,0x02},\r
+{0x81a7,0x28},\r
+{0x81a8,0x12},\r
+{0x81a9,0x0f},\r
+{0x81aa,0x02},\r
+{0x81ab,0x40},\r
+{0x81ac,0x04},\r
+{0x81ad,0x7f},\r
+{0x81ae,0xff},\r
+{0x81af,0x80},\r
+{0x81b0,0x02},\r
+{0x81b1,0x7f},\r
+{0x81b2,0x01},\r
+{0x81b3,0x78},\r
+{0x81b4,0xbd},\r
+{0x81b5,0xa6},\r
+{0x81b6,0x07},\r
+{0x81b7,0x78},\r
+{0x81b8,0xb9},\r
+{0x81b9,0xe6},\r
+{0x81ba,0x04},\r
+{0x81bb,0x78},\r
+{0x81bc,0xbf},\r
+{0x81bd,0xf6},\r
+{0x81be,0x78},\r
+{0x81bf,0xb9},\r
+{0x81c0,0xe6},\r
+{0x81c1,0x14},\r
+{0x81c2,0x78},\r
+{0x81c3,0xc0},\r
+{0x81c4,0xf6},\r
+{0x81c5,0x18},\r
+{0x81c6,0x12},\r
+{0x81c7,0x0f},\r
+{0x81c8,0x04},\r
+{0x81c9,0x40},\r
+{0x81ca,0x04},\r
+{0x81cb,0xe6},\r
+{0x81cc,0xff},\r
+{0x81cd,0x80},\r
+{0x81ce,0x02},\r
+{0x81cf,0x7f},\r
+{0x81d0,0x00},\r
+{0x81d1,0x78},\r
+{0x81d2,0xbf},\r
+{0x81d3,0xa6},\r
+{0x81d4,0x07},\r
+{0x81d5,0xd3},\r
+{0x81d6,0x08},\r
+{0x81d7,0xe6},\r
+{0x81d8,0x64},\r
+{0x81d9,0x80},\r
+{0x81da,0x94},\r
+{0x81db,0x80},\r
+{0x81dc,0x40},\r
+{0x81dd,0x04},\r
+{0x81de,0xe6},\r
+{0x81df,0xff},\r
+{0x81e0,0x80},\r
+{0x81e1,0x02},\r
+{0x81e2,0x7f},\r
+{0x81e3,0x00},\r
+{0x81e4,0x78},\r
+{0x81e5,0xc0},\r
+{0x81e6,0xa6},\r
+{0x81e7,0x07},\r
+{0x81e8,0xc3},\r
+{0x81e9,0x18},\r
+{0x81ea,0xe6},\r
+{0x81eb,0x64},\r
+{0x81ec,0x80},\r
+{0x81ed,0x94},\r
+{0x81ee,0xb3},\r
+{0x81ef,0x50},\r
+{0x81f0,0x04},\r
+{0x81f1,0xe6},\r
+{0x81f2,0xff},\r
+{0x81f3,0x80},\r
+{0x81f4,0x02},\r
+{0x81f5,0x7f},\r
+{0x81f6,0x33},\r
+{0x81f7,0x78},\r
+{0x81f8,0xbf},\r
+{0x81f9,0xa6},\r
+{0x81fa,0x07},\r
+{0x81fb,0xc3},\r
+{0x81fc,0x08},\r
+{0x81fd,0xe6},\r
+{0x81fe,0x64},\r
+{0x81ff,0x80},\r
+{0x8200,0x94},\r
+{0x8201,0xb3},\r
+{0x8202,0x50},\r
+{0x8203,0x04},\r
+{0x8204,0xe6},\r
+{0x8205,0xff},\r
+{0x8206,0x80},\r
+{0x8207,0x02},\r
+{0x8208,0x7f},\r
+{0x8209,0x33},\r
+{0x820a,0x78},\r
+{0x820b,0xc0},\r
+{0x820c,0xa6},\r
+{0x820d,0x07},\r
+{0x820e,0x12},\r
+{0x820f,0x0f},\r
+{0x8210,0x02},\r
+{0x8211,0x40},\r
+{0x8212,0x06},\r
+{0x8213,0x78},\r
+{0x8214,0xc0},\r
+{0x8215,0xe6},\r
+{0x8216,0xff},\r
+{0x8217,0x80},\r
+{0x8218,0x04},\r
+{0x8219,0x78},\r
+{0x821a,0xbf},\r
+{0x821b,0xe6},\r
+{0x821c,0xff},\r
+{0x821d,0x78},\r
+{0x821e,0xbe},\r
+{0x821f,0xa6},\r
+{0x8220,0x07},\r
+{0x8221,0x75},\r
+{0x8222,0x1f},\r
+{0x8223,0x03},\r
+{0x8224,0x78},\r
+{0x8225,0xb8},\r
+{0x8226,0x76},\r
+{0x8227,0x01},\r
+{0x8228,0x80},\r
+{0x8229,0x20},\r
+{0x822a,0xe5},\r
+{0x822b,0x1f},\r
+{0x822c,0x64},\r
+{0x822d,0x03},\r
+{0x822e,0x70},\r
+{0x822f,0x26},\r
+{0x8230,0x78},\r
+{0x8231,0xbe},\r
+{0x8232,0xe6},\r
+{0x8233,0xff},\r
+{0x8234,0xc3},\r
+{0x8235,0x78},\r
+{0x8236,0xc0},\r
+{0x8237,0x12},\r
+{0x8238,0x0e},\r
+{0x8239,0xe0},\r
+{0x823a,0x40},\r
+{0x823b,0x05},\r
+{0x823c,0x12},\r
+{0x823d,0x0e},\r
+{0x823e,0xda},\r
+{0x823f,0x40},\r
+{0x8240,0x09},\r
+{0x8241,0x78},\r
+{0x8242,0xb9},\r
+{0x8243,0xe6},\r
+{0x8244,0x78},\r
+{0x8245,0xbe},\r
+{0x8246,0xf6},\r
+{0x8247,0x75},\r
+{0x8248,0x1f},\r
+{0x8249,0x04},\r
+{0x824a,0x78},\r
+{0x824b,0xbe},\r
+{0x824c,0xe6},\r
+{0x824d,0x75},\r
+{0x824e,0xf0},\r
+{0x824f,0x05},\r
+{0x8250,0xa4},\r
+{0x8251,0xf5},\r
+{0x8252,0x4b},\r
+{0x8253,0x02},\r
+{0x8254,0x0a},\r
+{0x8255,0xff},\r
+{0x8256,0xe5},\r
+{0x8257,0x1f},\r
+{0x8258,0xb4},\r
+{0x8259,0x04},\r
+{0x825a,0x10},\r
+{0x825b,0x90},\r
+{0x825c,0x0e},\r
+{0x825d,0x94},\r
+{0x825e,0xe4},\r
+{0x825f,0x78},\r
+{0x8260,0xc3},\r
+{0x8261,0x12},\r
+{0x8262,0x0e},\r
+{0x8263,0xe9},\r
+{0x8264,0x40},\r
+{0x8265,0x02},\r
+{0x8266,0xd2},\r
+{0x8267,0x37},\r
+{0x8268,0x75},\r
+{0x8269,0x1f},\r
+{0x826a,0x05},\r
+{0x826b,0x22},\r
+{0x826c,0x30},\r
+{0x826d,0x01},\r
+{0x826e,0x03},\r
+{0x826f,0x02},\r
+{0x8270,0x04},\r
+{0x8271,0xc0},\r
+{0x8272,0x30},\r
+{0x8273,0x02},\r
+{0x8274,0x03},\r
+{0x8275,0x02},\r
+{0x8276,0x04},\r
+{0x8277,0xc0},\r
+{0x8278,0x90},\r
+{0x8279,0x51},\r
+{0x827a,0xa5},\r
+{0x827b,0xe0},\r
+{0x827c,0x78},\r
+{0x827d,0x93},\r
+{0x827e,0xf6},\r
+{0x827f,0xa3},\r
+{0x8280,0xe0},\r
+{0x8281,0x08},\r
+{0x8282,0xf6},\r
+{0x8283,0xa3},\r
+{0x8284,0xe0},\r
+{0x8285,0x08},\r
+{0x8286,0xf6},\r
+{0x8287,0xe5},\r
+{0x8288,0x1f},\r
+{0x8289,0x70},\r
+{0x828a,0x3c},\r
+{0x828b,0x75},\r
+{0x828c,0x1e},\r
+{0x828d,0x20},\r
+{0x828e,0xd2},\r
+{0x828f,0x35},\r
+{0x8290,0x12},\r
+{0x8291,0x0c},\r
+{0x8292,0x7a},\r
+{0x8293,0x78},\r
+{0x8294,0x7e},\r
+{0x8295,0xa6},\r
+{0x8296,0x06},\r
+{0x8297,0x08},\r
+{0x8298,0xa6},\r
+{0x8299,0x07},\r
+{0x829a,0x78},\r
+{0x829b,0x8b},\r
+{0x829c,0xa6},\r
+{0x829d,0x09},\r
+{0x829e,0x18},\r
+{0x829f,0x76},\r
+{0x82a0,0x01},\r
+{0x82a1,0x12},\r
+{0x82a2,0x0c},\r
+{0x82a3,0x5b},\r
+{0x82a4,0x78},\r
+{0x82a5,0x4e},\r
+{0x82a6,0xa6},\r
+{0x82a7,0x06},\r
+{0x82a8,0x08},\r
+{0x82a9,0xa6},\r
+{0x82aa,0x07},\r
+{0x82ab,0x78},\r
+{0x82ac,0x8b},\r
+{0x82ad,0xe6},\r
+{0x82ae,0x78},\r
+{0x82af,0x6e},\r
+{0x82b0,0xf6},\r
+{0x82b1,0x75},\r
+{0x82b2,0x1f},\r
+{0x82b3,0x01},\r
+{0x82b4,0x78},\r
+{0x82b5,0x93},\r
+{0x82b6,0xe6},\r
+{0x82b7,0x78},\r
+{0x82b8,0x90},\r
+{0x82b9,0xf6},\r
+{0x82ba,0x78},\r
+{0x82bb,0x94},\r
+{0x82bc,0xe6},\r
+{0x82bd,0x78},\r
+{0x82be,0x91},\r
+{0x82bf,0xf6},\r
+{0x82c0,0x78},\r
+{0x82c1,0x95},\r
+{0x82c2,0xe6},\r
+{0x82c3,0x78},\r
+{0x82c4,0x92},\r
+{0x82c5,0xf6},\r
+{0x82c6,0x22},\r
+{0x82c7,0x79},\r
+{0x82c8,0x90},\r
+{0x82c9,0xe7},\r
+{0x82ca,0xd3},\r
+{0x82cb,0x78},\r
+{0x82cc,0x93},\r
+{0x82cd,0x96},\r
+{0x82ce,0x40},\r
+{0x82cf,0x05},\r
+{0x82d0,0xe7},\r
+{0x82d1,0x96},\r
+{0x82d2,0xff},\r
+{0x82d3,0x80},\r
+{0x82d4,0x08},\r
+{0x82d5,0xc3},\r
+{0x82d6,0x79},\r
+{0x82d7,0x93},\r
+{0x82d8,0xe7},\r
+{0x82d9,0x78},\r
+{0x82da,0x90},\r
+{0x82db,0x96},\r
+{0x82dc,0xff},\r
+{0x82dd,0x78},\r
+{0x82de,0x88},\r
+{0x82df,0x76},\r
+{0x82e0,0x00},\r
+{0x82e1,0x08},\r
+{0x82e2,0xa6},\r
+{0x82e3,0x07},\r
+{0x82e4,0x79},\r
+{0x82e5,0x91},\r
+{0x82e6,0xe7},\r
+{0x82e7,0xd3},\r
+{0x82e8,0x78},\r
+{0x82e9,0x94},\r
+{0x82ea,0x96},\r
+{0x82eb,0x40},\r
+{0x82ec,0x05},\r
+{0x82ed,0xe7},\r
+{0x82ee,0x96},\r
+{0x82ef,0xff},\r
+{0x82f0,0x80},\r
+{0x82f1,0x08},\r
+{0x82f2,0xc3},\r
+{0x82f3,0x79},\r
+{0x82f4,0x94},\r
+{0x82f5,0xe7},\r
+{0x82f6,0x78},\r
+{0x82f7,0x91},\r
+{0x82f8,0x96},\r
+{0x82f9,0xff},\r
+{0x82fa,0x12},\r
+{0x82fb,0x0c},\r
+{0x82fc,0x8e},\r
+{0x82fd,0x79},\r
+{0x82fe,0x92},\r
+{0x82ff,0xe7},\r
+{0x8300,0xd3},\r
+{0x8301,0x78},\r
+{0x8302,0x95},\r
+{0x8303,0x96},\r
+{0x8304,0x40},\r
+{0x8305,0x05},\r
+{0x8306,0xe7},\r
+{0x8307,0x96},\r
+{0x8308,0xff},\r
+{0x8309,0x80},\r
+{0x830a,0x08},\r
+{0x830b,0xc3},\r
+{0x830c,0x79},\r
+{0x830d,0x95},\r
+{0x830e,0xe7},\r
+{0x830f,0x78},\r
+{0x8310,0x92},\r
+{0x8311,0x96},\r
+{0x8312,0xff},\r
+{0x8313,0x12},\r
+{0x8314,0x0c},\r
+{0x8315,0x8e},\r
+{0x8316,0x12},\r
+{0x8317,0x0c},\r
+{0x8318,0x5b},\r
+{0x8319,0x78},\r
+{0x831a,0x8a},\r
+{0x831b,0xe6},\r
+{0x831c,0x25},\r
+{0x831d,0xe0},\r
+{0x831e,0x24},\r
+{0x831f,0x4e},\r
+{0x8320,0xf8},\r
+{0x8321,0xa6},\r
+{0x8322,0x06},\r
+{0x8323,0x08},\r
+{0x8324,0xa6},\r
+{0x8325,0x07},\r
+{0x8326,0x78},\r
+{0x8327,0x8a},\r
+{0x8328,0xe6},\r
+{0x8329,0x24},\r
+{0x832a,0x6e},\r
+{0x832b,0xf8},\r
+{0x832c,0xa6},\r
+{0x832d,0x09},\r
+{0x832e,0x78},\r
+{0x832f,0x8a},\r
+{0x8330,0xe6},\r
+{0x8331,0x24},\r
+{0x8332,0x01},\r
+{0x8333,0xff},\r
+{0x8334,0xe4},\r
+{0x8335,0x33},\r
+{0x8336,0xfe},\r
+{0x8337,0xd3},\r
+{0x8338,0xef},\r
+{0x8339,0x94},\r
+{0x833a,0x0f},\r
+{0x833b,0xee},\r
+{0x833c,0x64},\r
+{0x833d,0x80},\r
+{0x833e,0x94},\r
+{0x833f,0x80},\r
+{0x8340,0x40},\r
+{0x8341,0x04},\r
+{0x8342,0x7f},\r
+{0x8343,0x00},\r
+{0x8344,0x80},\r
+{0x8345,0x05},\r
+{0x8346,0x78},\r
+{0x8347,0x8a},\r
+{0x8348,0xe6},\r
+{0x8349,0x04},\r
+{0x834a,0xff},\r
+{0x834b,0x78},\r
+{0x834c,0x8a},\r
+{0x834d,0xa6},\r
+{0x834e,0x07},\r
+{0x834f,0xe5},\r
+{0x8350,0x1f},\r
+{0x8351,0xb4},\r
+{0x8352,0x01},\r
+{0x8353,0x0a},\r
+{0x8354,0xe6},\r
+{0x8355,0x60},\r
+{0x8356,0x03},\r
+{0x8357,0x02},\r
+{0x8358,0x04},\r
+{0x8359,0xc0},\r
+{0x835a,0x75},\r
+{0x835b,0x1f},\r
+{0x835c,0x02},\r
+{0x835d,0x22},\r
+{0x835e,0x12},\r
+{0x835f,0x0c},\r
+{0x8360,0x7a},\r
+{0x8361,0x78},\r
+{0x8362,0x80},\r
+{0x8363,0xa6},\r
+{0x8364,0x06},\r
+{0x8365,0x08},\r
+{0x8366,0xa6},\r
+{0x8367,0x07},\r
+{0x8368,0x12},\r
+{0x8369,0x0c},\r
+{0x836a,0x7a},\r
+{0x836b,0x78},\r
+{0x836c,0x82},\r
+{0x836d,0xa6},\r
+{0x836e,0x06},\r
+{0x836f,0x08},\r
+{0x8370,0xa6},\r
+{0x8371,0x07},\r
+{0x8372,0x78},\r
+{0x8373,0x6e},\r
+{0x8374,0xe6},\r
+{0x8375,0x78},\r
+{0x8376,0x8c},\r
+{0x8377,0xf6},\r
+{0x8378,0x78},\r
+{0x8379,0x6e},\r
+{0x837a,0xe6},\r
+{0x837b,0x78},\r
+{0x837c,0x8d},\r
+{0x837d,0xf6},\r
+{0x837e,0x7f},\r
+{0x837f,0x01},\r
+{0x8380,0xef},\r
+{0x8381,0x25},\r
+{0x8382,0xe0},\r
+{0x8383,0x24},\r
+{0x8384,0x4f},\r
+{0x8385,0xf9},\r
+{0x8386,0xc3},\r
+{0x8387,0x78},\r
+{0x8388,0x81},\r
+{0x8389,0xe6},\r
+{0x838a,0x97},\r
+{0x838b,0x18},\r
+{0x838c,0xe6},\r
+{0x838d,0x19},\r
+{0x838e,0x97},\r
+{0x838f,0x50},\r
+{0x8390,0x0a},\r
+{0x8391,0x12},\r
+{0x8392,0x0c},\r
+{0x8393,0x82},\r
+{0x8394,0x78},\r
+{0x8395,0x80},\r
+{0x8396,0xa6},\r
+{0x8397,0x04},\r
+{0x8398,0x08},\r
+{0x8399,0xa6},\r
+{0x839a,0x05},\r
+{0x839b,0x74},\r
+{0x839c,0x6e},\r
+{0x839d,0x2f},\r
+{0x839e,0xf9},\r
+{0x839f,0x78},\r
+{0x83a0,0x8c},\r
+{0x83a1,0xe6},\r
+{0x83a2,0xc3},\r
+{0x83a3,0x97},\r
+{0x83a4,0x50},\r
+{0x83a5,0x08},\r
+{0x83a6,0x74},\r
+{0x83a7,0x6e},\r
+{0x83a8,0x2f},\r
+{0x83a9,0xf8},\r
+{0x83aa,0xe6},\r
+{0x83ab,0x78},\r
+{0x83ac,0x8c},\r
+{0x83ad,0xf6},\r
+{0x83ae,0xef},\r
+{0x83af,0x25},\r
+{0x83b0,0xe0},\r
+{0x83b1,0x24},\r
+{0x83b2,0x4f},\r
+{0x83b3,0xf9},\r
+{0x83b4,0xd3},\r
+{0x83b5,0x78},\r
+{0x83b6,0x83},\r
+{0x83b7,0xe6},\r
+{0x83b8,0x97},\r
+{0x83b9,0x18},\r
+{0x83ba,0xe6},\r
+{0x83bb,0x19},\r
+{0x83bc,0x97},\r
+{0x83bd,0x40},\r
+{0x83be,0x0a},\r
+{0x83bf,0x12},\r
+{0x83c0,0x0c},\r
+{0x83c1,0x82},\r
+{0x83c2,0x78},\r
+{0x83c3,0x82},\r
+{0x83c4,0xa6},\r
+{0x83c5,0x04},\r
+{0x83c6,0x08},\r
+{0x83c7,0xa6},\r
+{0x83c8,0x05},\r
+{0x83c9,0x74},\r
+{0x83ca,0x6e},\r
+{0x83cb,0x2f},\r
+{0x83cc,0xf9},\r
+{0x83cd,0x78},\r
+{0x83ce,0x8d},\r
+{0x83cf,0xe6},\r
+{0x83d0,0xd3},\r
+{0x83d1,0x97},\r
+{0x83d2,0x40},\r
+{0x83d3,0x08},\r
+{0x83d4,0x74},\r
+{0x83d5,0x6e},\r
+{0x83d6,0x2f},\r
+{0x83d7,0xf8},\r
+{0x83d8,0xe6},\r
+{0x83d9,0x78},\r
+{0x83da,0x8d},\r
+{0x83db,0xf6},\r
+{0x83dc,0x0f},\r
+{0x83dd,0xef},\r
+{0x83de,0x64},\r
+{0x83df,0x10},\r
+{0x83e0,0x70},\r
+{0x83e1,0x9e},\r
+{0x83e2,0xc3},\r
+{0x83e3,0x79},\r
+{0x83e4,0x81},\r
+{0x83e5,0xe7},\r
+{0x83e6,0x78},\r
+{0x83e7,0x83},\r
+{0x83e8,0x96},\r
+{0x83e9,0xff},\r
+{0x83ea,0x19},\r
+{0x83eb,0xe7},\r
+{0x83ec,0x18},\r
+{0x83ed,0x96},\r
+{0x83ee,0x78},\r
+{0x83ef,0x84},\r
+{0x83f0,0xf6},\r
+{0x83f1,0x08},\r
+{0x83f2,0xa6},\r
+{0x83f3,0x07},\r
+{0x83f4,0xc3},\r
+{0x83f5,0x79},\r
+{0x83f6,0x8c},\r
+{0x83f7,0xe7},\r
+{0x83f8,0x78},\r
+{0x83f9,0x8d},\r
+{0x83fa,0x96},\r
+{0x83fb,0x08},\r
+{0x83fc,0xf6},\r
+{0x83fd,0xd3},\r
+{0x83fe,0x79},\r
+{0x83ff,0x81},\r
+{0x8400,0xe7},\r
+{0x8401,0x78},\r
+{0x8402,0x7f},\r
+{0x8403,0x96},\r
+{0x8404,0x19},\r
+{0x8405,0xe7},\r
+{0x8406,0x18},\r
+{0x8407,0x96},\r
+{0x8408,0x40},\r
+{0x8409,0x05},\r
+{0x840a,0x09},\r
+{0x840b,0xe7},\r
+{0x840c,0x08},\r
+{0x840d,0x80},\r
+{0x840e,0x06},\r
+{0x840f,0xc3},\r
+{0x8410,0x79},\r
+{0x8411,0x7f},\r
+{0x8412,0xe7},\r
+{0x8413,0x78},\r
+{0x8414,0x81},\r
+{0x8415,0x96},\r
+{0x8416,0xff},\r
+{0x8417,0x19},\r
+{0x8418,0xe7},\r
+{0x8419,0x18},\r
+{0x841a,0x96},\r
+{0x841b,0xfe},\r
+{0x841c,0x78},\r
+{0x841d,0x86},\r
+{0x841e,0xa6},\r
+{0x841f,0x06},\r
+{0x8420,0x08},\r
+{0x8421,0xa6},\r
+{0x8422,0x07},\r
+{0x8423,0x79},\r
+{0x8424,0x8c},\r
+{0x8425,0xe7},\r
+{0x8426,0xd3},\r
+{0x8427,0x78},\r
+{0x8428,0x8b},\r
+{0x8429,0x96},\r
+{0x842a,0x40},\r
+{0x842b,0x05},\r
+{0x842c,0xe7},\r
+{0x842d,0x96},\r
+{0x842e,0xff},\r
+{0x842f,0x80},\r
+{0x8430,0x08},\r
+{0x8431,0xc3},\r
+{0x8432,0x79},\r
+{0x8433,0x8b},\r
+{0x8434,0xe7},\r
+{0x8435,0x78},\r
+{0x8436,0x8c},\r
+{0x8437,0x96},\r
+{0x8438,0xff},\r
+{0x8439,0x78},\r
+{0x843a,0x8f},\r
+{0x843b,0xa6},\r
+{0x843c,0x07},\r
+{0x843d,0xe5},\r
+{0x843e,0x1f},\r
+{0x843f,0x64},\r
+{0x8440,0x02},\r
+{0x8441,0x70},\r
+{0x8442,0x69},\r
+{0x8443,0x90},\r
+{0x8444,0x0e},\r
+{0x8445,0x91},\r
+{0x8446,0x93},\r
+{0x8447,0xff},\r
+{0x8448,0x18},\r
+{0x8449,0xe6},\r
+{0x844a,0xc3},\r
+{0x844b,0x9f},\r
+{0x844c,0x50},\r
+{0x844d,0x72},\r
+{0x844e,0x12},\r
+{0x844f,0x0c},\r
+{0x8450,0x4a},\r
+{0x8451,0x12},\r
+{0x8452,0x0c},\r
+{0x8453,0x2f},\r
+{0x8454,0x90},\r
+{0x8455,0x0e},\r
+{0x8456,0x8e},\r
+{0x8457,0x12},\r
+{0x8458,0x0c},\r
+{0x8459,0x38},\r
+{0x845a,0x78},\r
+{0x845b,0x80},\r
+{0x845c,0x12},\r
+{0x845d,0x0c},\r
+{0x845e,0x6b},\r
+{0x845f,0x7b},\r
+{0x8460,0x04},\r
+{0x8461,0x12},\r
+{0x8462,0x0c},\r
+{0x8463,0x1d},\r
+{0x8464,0xc3},\r
+{0x8465,0x12},\r
+{0x8466,0x06},\r
+{0x8467,0x45},\r
+{0x8468,0x50},\r
+{0x8469,0x56},\r
+{0x846a,0x90},\r
+{0x846b,0x0e},\r
+{0x846c,0x92},\r
+{0x846d,0xe4},\r
+{0x846e,0x93},\r
+{0x846f,0xff},\r
+{0x8470,0x78},\r
+{0x8471,0x8f},\r
+{0x8472,0xe6},\r
+{0x8473,0x9f},\r
+{0x8474,0x40},\r
+{0x8475,0x02},\r
+{0x8476,0x80},\r
+{0x8477,0x11},\r
+{0x8478,0x90},\r
+{0x8479,0x0e},\r
+{0x847a,0x90},\r
+{0x847b,0xe4},\r
+{0x847c,0x93},\r
+{0x847d,0xff},\r
+{0x847e,0xd3},\r
+{0x847f,0x78},\r
+{0x8480,0x89},\r
+{0x8481,0xe6},\r
+{0x8482,0x9f},\r
+{0x8483,0x18},\r
+{0x8484,0xe6},\r
+{0x8485,0x94},\r
+{0x8486,0x00},\r
+{0x8487,0x40},\r
+{0x8488,0x03},\r
+{0x8489,0x75},\r
+{0x848a,0x1f},\r
+{0x848b,0x05},\r
+{0x848c,0x12},\r
+{0x848d,0x0c},\r
+{0x848e,0x4a},\r
+{0x848f,0x12},\r
+{0x8490,0x0c},\r
+{0x8491,0x2f},\r
+{0x8492,0x90},\r
+{0x8493,0x0e},\r
+{0x8494,0x8f},\r
+{0x8495,0x12},\r
+{0x8496,0x0c},\r
+{0x8497,0x38},\r
+{0x8498,0x78},\r
+{0x8499,0x7e},\r
+{0x849a,0x12},\r
+{0x849b,0x0c},\r
+{0x849c,0x6b},\r
+{0x849d,0x7b},\r
+{0x849e,0x40},\r
+{0x849f,0x12},\r
+{0x84a0,0x0c},\r
+{0x84a1,0x1d},\r
+{0x84a2,0xd3},\r
+{0x84a3,0x12},\r
+{0x84a4,0x06},\r
+{0x84a5,0x45},\r
+{0x84a6,0x40},\r
+{0x84a7,0x18},\r
+{0x84a8,0x75},\r
+{0x84a9,0x1f},\r
+{0x84aa,0x05},\r
+{0x84ab,0x22},\r
+{0x84ac,0xe5},\r
+{0x84ad,0x1f},\r
+{0x84ae,0xb4},\r
+{0x84af,0x05},\r
+{0x84b0,0x0f},\r
+{0x84b1,0xd2},\r
+{0x84b2,0x01},\r
+{0x84b3,0xc2},\r
+{0x84b4,0x02},\r
+{0x84b5,0xe4},\r
+{0x84b6,0xf5},\r
+{0x84b7,0x1f},\r
+{0x84b8,0xf5},\r
+{0x84b9,0x1e},\r
+{0x84ba,0xd2},\r
+{0x84bb,0x35},\r
+{0x84bc,0xd2},\r
+{0x84bd,0x33},\r
+{0x84be,0xd2},\r
+{0x84bf,0x36},\r
+{0x84c0,0x22},\r
+{0x84c1,0xef},\r
+{0x84c2,0x8d},\r
+{0x84c3,0xf0},\r
+{0x84c4,0xa4},\r
+{0x84c5,0xa8},\r
+{0x84c6,0xf0},\r
+{0x84c7,0xcf},\r
+{0x84c8,0x8c},\r
+{0x84c9,0xf0},\r
+{0x84ca,0xa4},\r
+{0x84cb,0x28},\r
+{0x84cc,0xce},\r
+{0x84cd,0x8d},\r
+{0x84ce,0xf0},\r
+{0x84cf,0xa4},\r
+{0x84d0,0x2e},\r
+{0x84d1,0xfe},\r
+{0x84d2,0x22},\r
+{0x84d3,0xbc},\r
+{0x84d4,0x00},\r
+{0x84d5,0x0b},\r
+{0x84d6,0xbe},\r
+{0x84d7,0x00},\r
+{0x84d8,0x29},\r
+{0x84d9,0xef},\r
+{0x84da,0x8d},\r
+{0x84db,0xf0},\r
+{0x84dc,0x84},\r
+{0x84dd,0xff},\r
+{0x84de,0xad},\r
+{0x84df,0xf0},\r
+{0x84e0,0x22},\r
+{0x84e1,0xe4},\r
+{0x84e2,0xcc},\r
+{0x84e3,0xf8},\r
+{0x84e4,0x75},\r
+{0x84e5,0xf0},\r
+{0x84e6,0x08},\r
+{0x84e7,0xef},\r
+{0x84e8,0x2f},\r
+{0x84e9,0xff},\r
+{0x84ea,0xee},\r
+{0x84eb,0x33},\r
+{0x84ec,0xfe},\r
+{0x84ed,0xec},\r
+{0x84ee,0x33},\r
+{0x84ef,0xfc},\r
+{0x84f0,0xee},\r
+{0x84f1,0x9d},\r
+{0x84f2,0xec},\r
+{0x84f3,0x98},\r
+{0x84f4,0x40},\r
+{0x84f5,0x05},\r
+{0x84f6,0xfc},\r
+{0x84f7,0xee},\r
+{0x84f8,0x9d},\r
+{0x84f9,0xfe},\r
+{0x84fa,0x0f},\r
+{0x84fb,0xd5},\r
+{0x84fc,0xf0},\r
+{0x84fd,0xe9},\r
+{0x84fe,0xe4},\r
+{0x84ff,0xce},\r
+{0x8500,0xfd},\r
+{0x8501,0x22},\r
+{0x8502,0xed},\r
+{0x8503,0xf8},\r
+{0x8504,0xf5},\r
+{0x8505,0xf0},\r
+{0x8506,0xee},\r
+{0x8507,0x84},\r
+{0x8508,0x20},\r
+{0x8509,0xd2},\r
+{0x850a,0x1c},\r
+{0x850b,0xfe},\r
+{0x850c,0xad},\r
+{0x850d,0xf0},\r
+{0x850e,0x75},\r
+{0x850f,0xf0},\r
+{0x8510,0x08},\r
+{0x8511,0xef},\r
+{0x8512,0x2f},\r
+{0x8513,0xff},\r
+{0x8514,0xed},\r
+{0x8515,0x33},\r
+{0x8516,0xfd},\r
+{0x8517,0x40},\r
+{0x8518,0x07},\r
+{0x8519,0x98},\r
+{0x851a,0x50},\r
+{0x851b,0x06},\r
+{0x851c,0xd5},\r
+{0x851d,0xf0},\r
+{0x851e,0xf2},\r
+{0x851f,0x22},\r
+{0x8520,0xc3},\r
+{0x8521,0x98},\r
+{0x8522,0xfd},\r
+{0x8523,0x0f},\r
+{0x8524,0xd5},\r
+{0x8525,0xf0},\r
+{0x8526,0xea},\r
+{0x8527,0x22},\r
+{0x8528,0xe8},\r
+{0x8529,0x8f},\r
+{0x852a,0xf0},\r
+{0x852b,0xa4},\r
+{0x852c,0xcc},\r
+{0x852d,0x8b},\r
+{0x852e,0xf0},\r
+{0x852f,0xa4},\r
+{0x8530,0x2c},\r
+{0x8531,0xfc},\r
+{0x8532,0xe9},\r
+{0x8533,0x8e},\r
+{0x8534,0xf0},\r
+{0x8535,0xa4},\r
+{0x8536,0x2c},\r
+{0x8537,0xfc},\r
+{0x8538,0x8a},\r
+{0x8539,0xf0},\r
+{0x853a,0xed},\r
+{0x853b,0xa4},\r
+{0x853c,0x2c},\r
+{0x853d,0xfc},\r
+{0x853e,0xea},\r
+{0x853f,0x8e},\r
+{0x8540,0xf0},\r
+{0x8541,0xa4},\r
+{0x8542,0xcd},\r
+{0x8543,0xa8},\r
+{0x8544,0xf0},\r
+{0x8545,0x8b},\r
+{0x8546,0xf0},\r
+{0x8547,0xa4},\r
+{0x8548,0x2d},\r
+{0x8549,0xcc},\r
+{0x854a,0x38},\r
+{0x854b,0x25},\r
+{0x854c,0xf0},\r
+{0x854d,0xfd},\r
+{0x854e,0xe9},\r
+{0x854f,0x8f},\r
+{0x8550,0xf0},\r
+{0x8551,0xa4},\r
+{0x8552,0x2c},\r
+{0x8553,0xcd},\r
+{0x8554,0x35},\r
+{0x8555,0xf0},\r
+{0x8556,0xfc},\r
+{0x8557,0xeb},\r
+{0x8558,0x8e},\r
+{0x8559,0xf0},\r
+{0x855a,0xa4},\r
+{0x855b,0xfe},\r
+{0x855c,0xa9},\r
+{0x855d,0xf0},\r
+{0x855e,0xeb},\r
+{0x855f,0x8f},\r
+{0x8560,0xf0},\r
+{0x8561,0xa4},\r
+{0x8562,0xcf},\r
+{0x8563,0xc5},\r
+{0x8564,0xf0},\r
+{0x8565,0x2e},\r
+{0x8566,0xcd},\r
+{0x8567,0x39},\r
+{0x8568,0xfe},\r
+{0x8569,0xe4},\r
+{0x856a,0x3c},\r
+{0x856b,0xfc},\r
+{0x856c,0xea},\r
+{0x856d,0xa4},\r
+{0x856e,0x2d},\r
+{0x856f,0xce},\r
+{0x8570,0x35},\r
+{0x8571,0xf0},\r
+{0x8572,0xfd},\r
+{0x8573,0xe4},\r
+{0x8574,0x3c},\r
+{0x8575,0xfc},\r
+{0x8576,0x22},\r
+{0x8577,0x75},\r
+{0x8578,0xf0},\r
+{0x8579,0x08},\r
+{0x857a,0x75},\r
+{0x857b,0x82},\r
+{0x857c,0x00},\r
+{0x857d,0xef},\r
+{0x857e,0x2f},\r
+{0x857f,0xff},\r
+{0x8580,0xee},\r
+{0x8581,0x33},\r
+{0x8582,0xfe},\r
+{0x8583,0xcd},\r
+{0x8584,0x33},\r
+{0x8585,0xcd},\r
+{0x8586,0xcc},\r
+{0x8587,0x33},\r
+{0x8588,0xcc},\r
+{0x8589,0xc5},\r
+{0x858a,0x82},\r
+{0x858b,0x33},\r
+{0x858c,0xc5},\r
+{0x858d,0x82},\r
+{0x858e,0x9b},\r
+{0x858f,0xed},\r
+{0x8590,0x9a},\r
+{0x8591,0xec},\r
+{0x8592,0x99},\r
+{0x8593,0xe5},\r
+{0x8594,0x82},\r
+{0x8595,0x98},\r
+{0x8596,0x40},\r
+{0x8597,0x0c},\r
+{0x8598,0xf5},\r
+{0x8599,0x82},\r
+{0x859a,0xee},\r
+{0x859b,0x9b},\r
+{0x859c,0xfe},\r
+{0x859d,0xed},\r
+{0x859e,0x9a},\r
+{0x859f,0xfd},\r
+{0x85a0,0xec},\r
+{0x85a1,0x99},\r
+{0x85a2,0xfc},\r
+{0x85a3,0x0f},\r
+{0x85a4,0xd5},\r
+{0x85a5,0xf0},\r
+{0x85a6,0xd6},\r
+{0x85a7,0xe4},\r
+{0x85a8,0xce},\r
+{0x85a9,0xfb},\r
+{0x85aa,0xe4},\r
+{0x85ab,0xcd},\r
+{0x85ac,0xfa},\r
+{0x85ad,0xe4},\r
+{0x85ae,0xcc},\r
+{0x85af,0xf9},\r
+{0x85b0,0xa8},\r
+{0x85b1,0x82},\r
+{0x85b2,0x22},\r
+{0x85b3,0xb8},\r
+{0x85b4,0x00},\r
+{0x85b5,0xc1},\r
+{0x85b6,0xb9},\r
+{0x85b7,0x00},\r
+{0x85b8,0x59},\r
+{0x85b9,0xba},\r
+{0x85ba,0x00},\r
+{0x85bb,0x2d},\r
+{0x85bc,0xec},\r
+{0x85bd,0x8b},\r
+{0x85be,0xf0},\r
+{0x85bf,0x84},\r
+{0x85c0,0xcf},\r
+{0x85c1,0xce},\r
+{0x85c2,0xcd},\r
+{0x85c3,0xfc},\r
+{0x85c4,0xe5},\r
+{0x85c5,0xf0},\r
+{0x85c6,0xcb},\r
+{0x85c7,0xf9},\r
+{0x85c8,0x78},\r
+{0x85c9,0x18},\r
+{0x85ca,0xef},\r
+{0x85cb,0x2f},\r
+{0x85cc,0xff},\r
+{0x85cd,0xee},\r
+{0x85ce,0x33},\r
+{0x85cf,0xfe},\r
+{0x85d0,0xed},\r
+{0x85d1,0x33},\r
+{0x85d2,0xfd},\r
+{0x85d3,0xec},\r
+{0x85d4,0x33},\r
+{0x85d5,0xfc},\r
+{0x85d6,0xeb},\r
+{0x85d7,0x33},\r
+{0x85d8,0xfb},\r
+{0x85d9,0x10},\r
+{0x85da,0xd7},\r
+{0x85db,0x03},\r
+{0x85dc,0x99},\r
+{0x85dd,0x40},\r
+{0x85de,0x04},\r
+{0x85df,0xeb},\r
+{0x85e0,0x99},\r
+{0x85e1,0xfb},\r
+{0x85e2,0x0f},\r
+{0x85e3,0xd8},\r
+{0x85e4,0xe5},\r
+{0x85e5,0xe4},\r
+{0x85e6,0xf9},\r
+{0x85e7,0xfa},\r
+{0x85e8,0x22},\r
+{0x85e9,0x78},\r
+{0x85ea,0x18},\r
+{0x85eb,0xef},\r
+{0x85ec,0x2f},\r
+{0x85ed,0xff},\r
+{0x85ee,0xee},\r
+{0x85ef,0x33},\r
+{0x85f0,0xfe},\r
+{0x85f1,0xed},\r
+{0x85f2,0x33},\r
+{0x85f3,0xfd},\r
+{0x85f4,0xec},\r
+{0x85f5,0x33},\r
+{0x85f6,0xfc},\r
+{0x85f7,0xc9},\r
+{0x85f8,0x33},\r
+{0x85f9,0xc9},\r
+{0x85fa,0x10},\r
+{0x85fb,0xd7},\r
+{0x85fc,0x05},\r
+{0x85fd,0x9b},\r
+{0x85fe,0xe9},\r
+{0x85ff,0x9a},\r
+{0x8600,0x40},\r
+{0x8601,0x07},\r
+{0x8602,0xec},\r
+{0x8603,0x9b},\r
+{0x8604,0xfc},\r
+{0x8605,0xe9},\r
+{0x8606,0x9a},\r
+{0x8607,0xf9},\r
+{0x8608,0x0f},\r
+{0x8609,0xd8},\r
+{0x860a,0xe0},\r
+{0x860b,0xe4},\r
+{0x860c,0xc9},\r
+{0x860d,0xfa},\r
+{0x860e,0xe4},\r
+{0x860f,0xcc},\r
+{0x8610,0xfb},\r
+{0x8611,0x22},\r
+{0x8612,0x75},\r
+{0x8613,0xf0},\r
+{0x8614,0x10},\r
+{0x8615,0xef},\r
+{0x8616,0x2f},\r
+{0x8617,0xff},\r
+{0x8618,0xee},\r
+{0x8619,0x33},\r
+{0x861a,0xfe},\r
+{0x861b,0xed},\r
+{0x861c,0x33},\r
+{0x861d,0xfd},\r
+{0x861e,0xcc},\r
+{0x861f,0x33},\r
+{0x8620,0xcc},\r
+{0x8621,0xc8},\r
+{0x8622,0x33},\r
+{0x8623,0xc8},\r
+{0x8624,0x10},\r
+{0x8625,0xd7},\r
+{0x8626,0x07},\r
+{0x8627,0x9b},\r
+{0x8628,0xec},\r
+{0x8629,0x9a},\r
+{0x862a,0xe8},\r
+{0x862b,0x99},\r
+{0x862c,0x40},\r
+{0x862d,0x0a},\r
+{0x862e,0xed},\r
+{0x862f,0x9b},\r
+{0x8630,0xfd},\r
+{0x8631,0xec},\r
+{0x8632,0x9a},\r
+{0x8633,0xfc},\r
+{0x8634,0xe8},\r
+{0x8635,0x99},\r
+{0x8636,0xf8},\r
+{0x8637,0x0f},\r
+{0x8638,0xd5},\r
+{0x8639,0xf0},\r
+{0x863a,0xda},\r
+{0x863b,0xe4},\r
+{0x863c,0xcd},\r
+{0x863d,0xfb},\r
+{0x863e,0xe4},\r
+{0x863f,0xcc},\r
+{0x8640,0xfa},\r
+{0x8641,0xe4},\r
+{0x8642,0xc8},\r
+{0x8643,0xf9},\r
+{0x8644,0x22},\r
+{0x8645,0xeb},\r
+{0x8646,0x9f},\r
+{0x8647,0xf5},\r
+{0x8648,0xf0},\r
+{0x8649,0xea},\r
+{0x864a,0x9e},\r
+{0x864b,0x42},\r
+{0x864c,0xf0},\r
+{0x864d,0xe9},\r
+{0x864e,0x9d},\r
+{0x864f,0x42},\r
+{0x8650,0xf0},\r
+{0x8651,0xe8},\r
+{0x8652,0x9c},\r
+{0x8653,0x45},\r
+{0x8654,0xf0},\r
+{0x8655,0x22},\r
+{0x8656,0xe8},\r
+{0x8657,0x60},\r
+{0x8658,0x0f},\r
+{0x8659,0xec},\r
+{0x865a,0xc3},\r
+{0x865b,0x13},\r
+{0x865c,0xfc},\r
+{0x865d,0xed},\r
+{0x865e,0x13},\r
+{0x865f,0xfd},\r
+{0x8660,0xee},\r
+{0x8661,0x13},\r
+{0x8662,0xfe},\r
+{0x8663,0xef},\r
+{0x8664,0x13},\r
+{0x8665,0xff},\r
+{0x8666,0xd8},\r
+{0x8667,0xf1},\r
+{0x8668,0x22},\r
+{0x8669,0xe8},\r
+{0x866a,0x60},\r
+{0x866b,0x0f},\r
+{0x866c,0xef},\r
+{0x866d,0xc3},\r
+{0x866e,0x33},\r
+{0x866f,0xff},\r
+{0x8670,0xee},\r
+{0x8671,0x33},\r
+{0x8672,0xfe},\r
+{0x8673,0xed},\r
+{0x8674,0x33},\r
+{0x8675,0xfd},\r
+{0x8676,0xec},\r
+{0x8677,0x33},\r
+{0x8678,0xfc},\r
+{0x8679,0xd8},\r
+{0x867a,0xf1},\r
+{0x867b,0x22},\r
+{0x867c,0xe4},\r
+{0x867d,0x93},\r
+{0x867e,0xfc},\r
+{0x867f,0x74},\r
+{0x8680,0x01},\r
+{0x8681,0x93},\r
+{0x8682,0xfd},\r
+{0x8683,0x74},\r
+{0x8684,0x02},\r
+{0x8685,0x93},\r
+{0x8686,0xfe},\r
+{0x8687,0x74},\r
+{0x8688,0x03},\r
+{0x8689,0x93},\r
+{0x868a,0xff},\r
+{0x868b,0x22},\r
+{0x868c,0xe6},\r
+{0x868d,0xfb},\r
+{0x868e,0x08},\r
+{0x868f,0xe6},\r
+{0x8690,0xf9},\r
+{0x8691,0x08},\r
+{0x8692,0xe6},\r
+{0x8693,0xfa},\r
+{0x8694,0x08},\r
+{0x8695,0xe6},\r
+{0x8696,0xcb},\r
+{0x8697,0xf8},\r
+{0x8698,0x22},\r
+{0x8699,0xec},\r
+{0x869a,0xf6},\r
+{0x869b,0x08},\r
+{0x869c,0xed},\r
+{0x869d,0xf6},\r
+{0x869e,0x08},\r
+{0x869f,0xee},\r
+{0x86a0,0xf6},\r
+{0x86a1,0x08},\r
+{0x86a2,0xef},\r
+{0x86a3,0xf6},\r
+{0x86a4,0x22},\r
+{0x86a5,0xa4},\r
+{0x86a6,0x25},\r
+{0x86a7,0x82},\r
+{0x86a8,0xf5},\r
+{0x86a9,0x82},\r
+{0x86aa,0xe5},\r
+{0x86ab,0xf0},\r
+{0x86ac,0x35},\r
+{0x86ad,0x83},\r
+{0x86ae,0xf5},\r
+{0x86af,0x83},\r
+{0x86b0,0x22},\r
+{0x86b1,0xd0},\r
+{0x86b2,0x83},\r
+{0x86b3,0xd0},\r
+{0x86b4,0x82},\r
+{0x86b5,0xf8},\r
+{0x86b6,0xe4},\r
+{0x86b7,0x93},\r
+{0x86b8,0x70},\r
+{0x86b9,0x12},\r
+{0x86ba,0x74},\r
+{0x86bb,0x01},\r
+{0x86bc,0x93},\r
+{0x86bd,0x70},\r
+{0x86be,0x0d},\r
+{0x86bf,0xa3},\r
+{0x86c0,0xa3},\r
+{0x86c1,0x93},\r
+{0x86c2,0xf8},\r
+{0x86c3,0x74},\r
+{0x86c4,0x01},\r
+{0x86c5,0x93},\r
+{0x86c6,0xf5},\r
+{0x86c7,0x82},\r
+{0x86c8,0x88},\r
+{0x86c9,0x83},\r
+{0x86ca,0xe4},\r
+{0x86cb,0x73},\r
+{0x86cc,0x74},\r
+{0x86cd,0x02},\r
+{0x86ce,0x93},\r
+{0x86cf,0x68},\r
+{0x86d0,0x60},\r
+{0x86d1,0xef},\r
+{0x86d2,0xa3},\r
+{0x86d3,0xa3},\r
+{0x86d4,0xa3},\r
+{0x86d5,0x80},\r
+{0x86d6,0xdf},\r
+{0x86d7,0x90},\r
+{0x86d8,0x38},\r
+{0x86d9,0x04},\r
+{0x86da,0x78},\r
+{0x86db,0x52},\r
+{0x86dc,0x12},\r
+{0x86dd,0x0b},\r
+{0x86de,0xfd},\r
+{0x86df,0x90},\r
+{0x86e0,0x38},\r
+{0x86e1,0x00},\r
+{0x86e2,0xe0},\r
+{0x86e3,0xfe},\r
+{0x86e4,0xa3},\r
+{0x86e5,0xe0},\r
+{0x86e6,0xfd},\r
+{0x86e7,0xed},\r
+{0x86e8,0xff},\r
+{0x86e9,0xc3},\r
+{0x86ea,0x12},\r
+{0x86eb,0x0b},\r
+{0x86ec,0x9e},\r
+{0x86ed,0x90},\r
+{0x86ee,0x38},\r
+{0x86ef,0x10},\r
+{0x86f0,0x12},\r
+{0x86f1,0x0b},\r
+{0x86f2,0x92},\r
+{0x86f3,0x90},\r
+{0x86f4,0x38},\r
+{0x86f5,0x06},\r
+{0x86f6,0x78},\r
+{0x86f7,0x54},\r
+{0x86f8,0x12},\r
+{0x86f9,0x0b},\r
+{0x86fa,0xfd},\r
+{0x86fb,0x90},\r
+{0x86fc,0x38},\r
+{0x86fd,0x02},\r
+{0x86fe,0xe0},\r
+{0x86ff,0xfe},\r
+{0x8700,0xa3},\r
+{0x8701,0xe0},\r
+{0x8702,0xfd},\r
+{0x8703,0xed},\r
+{0x8704,0xff},\r
+{0x8705,0xc3},\r
+{0x8706,0x12},\r
+{0x8707,0x0b},\r
+{0x8708,0x9e},\r
+{0x8709,0x90},\r
+{0x870a,0x38},\r
+{0x870b,0x12},\r
+{0x870c,0x12},\r
+{0x870d,0x0b},\r
+{0x870e,0x92},\r
+{0x870f,0xa3},\r
+{0x8710,0xe0},\r
+{0x8711,0xb4},\r
+{0x8712,0x31},\r
+{0x8713,0x07},\r
+{0x8714,0x78},\r
+{0x8715,0x52},\r
+{0x8716,0x79},\r
+{0x8717,0x52},\r
+{0x8718,0x12},\r
+{0x8719,0x0c},\r
+{0x871a,0x13},\r
+{0x871b,0x90},\r
+{0x871c,0x38},\r
+{0x871d,0x14},\r
+{0x871e,0xe0},\r
+{0x871f,0xb4},\r
+{0x8720,0x71},\r
+{0x8721,0x15},\r
+{0x8722,0x78},\r
+{0x8723,0x52},\r
+{0x8724,0xe6},\r
+{0x8725,0xfe},\r
+{0x8726,0x08},\r
+{0x8727,0xe6},\r
+{0x8728,0x78},\r
+{0x8729,0x02},\r
+{0x872a,0xce},\r
+{0x872b,0xc3},\r
+{0x872c,0x13},\r
+{0x872d,0xce},\r
+{0x872e,0x13},\r
+{0x872f,0xd8},\r
+{0x8730,0xf9},\r
+{0x8731,0x79},\r
+{0x8732,0x53},\r
+{0x8733,0xf7},\r
+{0x8734,0xee},\r
+{0x8735,0x19},\r
+{0x8736,0xf7},\r
+{0x8737,0x90},\r
+{0x8738,0x38},\r
+{0x8739,0x15},\r
+{0x873a,0xe0},\r
+{0x873b,0xb4},\r
+{0x873c,0x31},\r
+{0x873d,0x07},\r
+{0x873e,0x78},\r
+{0x873f,0x54},\r
+{0x8740,0x79},\r
+{0x8741,0x54},\r
+{0x8742,0x12},\r
+{0x8743,0x0c},\r
+{0x8744,0x13},\r
+{0x8745,0x90},\r
+{0x8746,0x38},\r
+{0x8747,0x15},\r
+{0x8748,0xe0},\r
+{0x8749,0xb4},\r
+{0x874a,0x71},\r
+{0x874b,0x15},\r
+{0x874c,0x78},\r
+{0x874d,0x54},\r
+{0x874e,0xe6},\r
+{0x874f,0xfe},\r
+{0x8750,0x08},\r
+{0x8751,0xe6},\r
+{0x8752,0x78},\r
+{0x8753,0x02},\r
+{0x8754,0xce},\r
+{0x8755,0xc3},\r
+{0x8756,0x13},\r
+{0x8757,0xce},\r
+{0x8758,0x13},\r
+{0x8759,0xd8},\r
+{0x875a,0xf9},\r
+{0x875b,0x79},\r
+{0x875c,0x55},\r
+{0x875d,0xf7},\r
+{0x875e,0xee},\r
+{0x875f,0x19},\r
+{0x8760,0xf7},\r
+{0x8761,0x79},\r
+{0x8762,0x52},\r
+{0x8763,0x12},\r
+{0x8764,0x0b},\r
+{0x8765,0xd9},\r
+{0x8766,0x09},\r
+{0x8767,0x12},\r
+{0x8768,0x0b},\r
+{0x8769,0xd9},\r
+{0x876a,0xaf},\r
+{0x876b,0x47},\r
+{0x876c,0x12},\r
+{0x876d,0x0b},\r
+{0x876e,0xb2},\r
+{0x876f,0xe5},\r
+{0x8770,0x44},\r
+{0x8771,0xfb},\r
+{0x8772,0x7a},\r
+{0x8773,0x00},\r
+{0x8774,0xfd},\r
+{0x8775,0x7c},\r
+{0x8776,0x00},\r
+{0x8777,0x12},\r
+{0x8778,0x04},\r
+{0x8779,0xd3},\r
+{0x877a,0x78},\r
+{0x877b,0x5a},\r
+{0x877c,0xa6},\r
+{0x877d,0x06},\r
+{0x877e,0x08},\r
+{0x877f,0xa6},\r
+{0x8780,0x07},\r
+{0x8781,0xaf},\r
+{0x8782,0x45},\r
+{0x8783,0x12},\r
+{0x8784,0x0b},\r
+{0x8785,0xb2},\r
+{0x8786,0xad},\r
+{0x8787,0x03},\r
+{0x8788,0x7c},\r
+{0x8789,0x00},\r
+{0x878a,0x12},\r
+{0x878b,0x04},\r
+{0x878c,0xd3},\r
+{0x878d,0x78},\r
+{0x878e,0x56},\r
+{0x878f,0xa6},\r
+{0x8790,0x06},\r
+{0x8791,0x08},\r
+{0x8792,0xa6},\r
+{0x8793,0x07},\r
+{0x8794,0xaf},\r
+{0x8795,0x48},\r
+{0x8796,0x78},\r
+{0x8797,0x54},\r
+{0x8798,0x12},\r
+{0x8799,0x0b},\r
+{0x879a,0xb4},\r
+{0x879b,0xe5},\r
+{0x879c,0x43},\r
+{0x879d,0xfb},\r
+{0x879e,0xfd},\r
+{0x879f,0x7c},\r
+{0x87a0,0x00},\r
+{0x87a1,0x12},\r
+{0x87a2,0x04},\r
+{0x87a3,0xd3},\r
+{0x87a4,0x78},\r
+{0x87a5,0x5c},\r
+{0x87a6,0xa6},\r
+{0x87a7,0x06},\r
+{0x87a8,0x08},\r
+{0x87a9,0xa6},\r
+{0x87aa,0x07},\r
+{0x87ab,0xaf},\r
+{0x87ac,0x46},\r
+{0x87ad,0x7e},\r
+{0x87ae,0x00},\r
+{0x87af,0x78},\r
+{0x87b0,0x54},\r
+{0x87b1,0x12},\r
+{0x87b2,0x0b},\r
+{0x87b3,0xb6},\r
+{0x87b4,0xad},\r
+{0x87b5,0x03},\r
+{0x87b6,0x7c},\r
+{0x87b7,0x00},\r
+{0x87b8,0x12},\r
+{0x87b9,0x04},\r
+{0x87ba,0xd3},\r
+{0x87bb,0x78},\r
+{0x87bc,0x58},\r
+{0x87bd,0xa6},\r
+{0x87be,0x06},\r
+{0x87bf,0x08},\r
+{0x87c0,0xa6},\r
+{0x87c1,0x07},\r
+{0x87c2,0xc3},\r
+{0x87c3,0x78},\r
+{0x87c4,0x5b},\r
+{0x87c5,0xe6},\r
+{0x87c6,0x94},\r
+{0x87c7,0x08},\r
+{0x87c8,0x18},\r
+{0x87c9,0xe6},\r
+{0x87ca,0x94},\r
+{0x87cb,0x00},\r
+{0x87cc,0x50},\r
+{0x87cd,0x05},\r
+{0x87ce,0x76},\r
+{0x87cf,0x00},\r
+{0x87d0,0x08},\r
+{0x87d1,0x76},\r
+{0x87d2,0x08},\r
+{0x87d3,0xc3},\r
+{0x87d4,0x78},\r
+{0x87d5,0x5d},\r
+{0x87d6,0xe6},\r
+{0x87d7,0x94},\r
+{0x87d8,0x08},\r
+{0x87d9,0x18},\r
+{0x87da,0xe6},\r
+{0x87db,0x94},\r
+{0x87dc,0x00},\r
+{0x87dd,0x50},\r
+{0x87de,0x05},\r
+{0x87df,0x76},\r
+{0x87e0,0x00},\r
+{0x87e1,0x08},\r
+{0x87e2,0x76},\r
+{0x87e3,0x08},\r
+{0x87e4,0x78},\r
+{0x87e5,0x5a},\r
+{0x87e6,0x12},\r
+{0x87e7,0x0b},\r
+{0x87e8,0xc6},\r
+{0x87e9,0xff},\r
+{0x87ea,0xd3},\r
+{0x87eb,0x78},\r
+{0x87ec,0x57},\r
+{0x87ed,0xe6},\r
+{0x87ee,0x9f},\r
+{0x87ef,0x18},\r
+{0x87f0,0xe6},\r
+{0x87f1,0x9e},\r
+{0x87f2,0x40},\r
+{0x87f3,0x0e},\r
+{0x87f4,0x78},\r
+{0x87f5,0x5a},\r
+{0x87f6,0xe6},\r
+{0x87f7,0x13},\r
+{0x87f8,0xfe},\r
+{0x87f9,0x08},\r
+{0x87fa,0xe6},\r
+{0x87fb,0x78},\r
+{0x87fc,0x57},\r
+{0x87fd,0x12},\r
+{0x87fe,0x0c},\r
+{0x87ff,0x08},\r
+{0x8800,0x80},\r
+{0x8801,0x04},\r
+{0x8802,0x7e},\r
+{0x8803,0x00},\r
+{0x8804,0x7f},\r
+{0x8805,0x00},\r
+{0x8806,0x78},\r
+{0x8807,0x5e},\r
+{0x8808,0x12},\r
+{0x8809,0x0b},\r
+{0x880a,0xbe},\r
+{0x880b,0xff},\r
+{0x880c,0xd3},\r
+{0x880d,0x78},\r
+{0x880e,0x59},\r
+{0x880f,0xe6},\r
+{0x8810,0x9f},\r
+{0x8811,0x18},\r
+{0x8812,0xe6},\r
+{0x8813,0x9e},\r
+{0x8814,0x40},\r
+{0x8815,0x0e},\r
+{0x8816,0x78},\r
+{0x8817,0x5c},\r
+{0x8818,0xe6},\r
+{0x8819,0x13},\r
+{0x881a,0xfe},\r
+{0x881b,0x08},\r
+{0x881c,0xe6},\r
+{0x881d,0x78},\r
+{0x881e,0x59},\r
+{0x881f,0x12},\r
+{0x8820,0x0c},\r
+{0x8821,0x08},\r
+{0x8822,0x80},\r
+{0x8823,0x04},\r
+{0x8824,0x7e},\r
+{0x8825,0x00},\r
+{0x8826,0x7f},\r
+{0x8827,0x00},\r
+{0x8828,0xe4},\r
+{0x8829,0xfc},\r
+{0x882a,0xfd},\r
+{0x882b,0x78},\r
+{0x882c,0x62},\r
+{0x882d,0x12},\r
+{0x882e,0x06},\r
+{0x882f,0x99},\r
+{0x8830,0x78},\r
+{0x8831,0x5a},\r
+{0x8832,0x12},\r
+{0x8833,0x0b},\r
+{0x8834,0xc6},\r
+{0x8835,0x78},\r
+{0x8836,0x57},\r
+{0x8837,0x26},\r
+{0x8838,0xff},\r
+{0x8839,0xee},\r
+{0x883a,0x18},\r
+{0x883b,0x36},\r
+{0x883c,0xfe},\r
+{0x883d,0x78},\r
+{0x883e,0x66},\r
+{0x883f,0x12},\r
+{0x8840,0x0b},\r
+{0x8841,0xbe},\r
+{0x8842,0x78},\r
+{0x8843,0x59},\r
+{0x8844,0x26},\r
+{0x8845,0xff},\r
+{0x8846,0xee},\r
+{0x8847,0x18},\r
+{0x8848,0x36},\r
+{0x8849,0xfe},\r
+{0x884a,0xe4},\r
+{0x884b,0xfc},\r
+{0x884c,0xfd},\r
+{0x884d,0x78},\r
+{0x884e,0x6a},\r
+{0x884f,0x12},\r
+{0x8850,0x06},\r
+{0x8851,0x99},\r
+{0x8852,0x12},\r
+{0x8853,0x0b},\r
+{0x8854,0xce},\r
+{0x8855,0x78},\r
+{0x8856,0x66},\r
+{0x8857,0x12},\r
+{0x8858,0x06},\r
+{0x8859,0x8c},\r
+{0x885a,0xd3},\r
+{0x885b,0x12},\r
+{0x885c,0x06},\r
+{0x885d,0x45},\r
+{0x885e,0x40},\r
+{0x885f,0x08},\r
+{0x8860,0x12},\r
+{0x8861,0x0b},\r
+{0x8862,0xce},\r
+{0x8863,0x78},\r
+{0x8864,0x66},\r
+{0x8865,0x12},\r
+{0x8866,0x06},\r
+{0x8867,0x99},\r
+{0x8868,0x78},\r
+{0x8869,0x54},\r
+{0x886a,0x12},\r
+{0x886b,0x0b},\r
+{0x886c,0xd0},\r
+{0x886d,0x78},\r
+{0x886e,0x6a},\r
+{0x886f,0x12},\r
+{0x8870,0x06},\r
+{0x8871,0x8c},\r
+{0x8872,0xd3},\r
+{0x8873,0x12},\r
+{0x8874,0x06},\r
+{0x8875,0x45},\r
+{0x8876,0x40},\r
+{0x8877,0x0a},\r
+{0x8878,0x78},\r
+{0x8879,0x54},\r
+{0x887a,0x12},\r
+{0x887b,0x0b},\r
+{0x887c,0xd0},\r
+{0x887d,0x78},\r
+{0x887e,0x6a},\r
+{0x887f,0x12},\r
+{0x8880,0x06},\r
+{0x8881,0x99},\r
+{0x8882,0x78},\r
+{0x8883,0x61},\r
+{0x8884,0xe6},\r
+{0x8885,0x90},\r
+{0x8886,0x60},\r
+{0x8887,0x01},\r
+{0x8888,0xf0},\r
+{0x8889,0x78},\r
+{0x888a,0x65},\r
+{0x888b,0xe6},\r
+{0x888c,0xa3},\r
+{0x888d,0xf0},\r
+{0x888e,0x78},\r
+{0x888f,0x69},\r
+{0x8890,0xe6},\r
+{0x8891,0xa3},\r
+{0x8892,0xf0},\r
+{0x8893,0x78},\r
+{0x8894,0x55},\r
+{0x8895,0xe6},\r
+{0x8896,0xa3},\r
+{0x8897,0xf0},\r
+{0x8898,0x7d},\r
+{0x8899,0x01},\r
+{0x889a,0x78},\r
+{0x889b,0x61},\r
+{0x889c,0x12},\r
+{0x889d,0x0b},\r
+{0x889e,0xe9},\r
+{0x889f,0x24},\r
+{0x88a0,0x01},\r
+{0x88a1,0x12},\r
+{0x88a2,0x0b},\r
+{0x88a3,0xa6},\r
+{0x88a4,0x78},\r
+{0x88a5,0x65},\r
+{0x88a6,0x12},\r
+{0x88a7,0x0b},\r
+{0x88a8,0xe9},\r
+{0x88a9,0x24},\r
+{0x88aa,0x02},\r
+{0x88ab,0x12},\r
+{0x88ac,0x0b},\r
+{0x88ad,0xa6},\r
+{0x88ae,0x78},\r
+{0x88af,0x69},\r
+{0x88b0,0x12},\r
+{0x88b1,0x0b},\r
+{0x88b2,0xe9},\r
+{0x88b3,0x24},\r
+{0x88b4,0x03},\r
+{0x88b5,0x12},\r
+{0x88b6,0x0b},\r
+{0x88b7,0xa6},\r
+{0x88b8,0x78},\r
+{0x88b9,0x6d},\r
+{0x88ba,0x12},\r
+{0x88bb,0x0b},\r
+{0x88bc,0xe9},\r
+{0x88bd,0x24},\r
+{0x88be,0x04},\r
+{0x88bf,0x12},\r
+{0x88c0,0x0b},\r
+{0x88c1,0xa6},\r
+{0x88c2,0x0d},\r
+{0x88c3,0xbd},\r
+{0x88c4,0x05},\r
+{0x88c5,0xd4},\r
+{0x88c6,0xc2},\r
+{0x88c7,0x0e},\r
+{0x88c8,0xc2},\r
+{0x88c9,0x06},\r
+{0x88ca,0x22},\r
+{0x88cb,0x85},\r
+{0x88cc,0x08},\r
+{0x88cd,0x41},\r
+{0x88ce,0x90},\r
+{0x88cf,0x30},\r
+{0x88d0,0x24},\r
+{0x88d1,0xe0},\r
+{0x88d2,0xf5},\r
+{0x88d3,0x3d},\r
+{0x88d4,0xa3},\r
+{0x88d5,0xe0},\r
+{0x88d6,0xf5},\r
+{0x88d7,0x3e},\r
+{0x88d8,0xa3},\r
+{0x88d9,0xe0},\r
+{0x88da,0xf5},\r
+{0x88db,0x3f},\r
+{0x88dc,0xa3},\r
+{0x88dd,0xe0},\r
+{0x88de,0xf5},\r
+{0x88df,0x40},\r
+{0x88e0,0xa3},\r
+{0x88e1,0xe0},\r
+{0x88e2,0xf5},\r
+{0x88e3,0x3c},\r
+{0x88e4,0xd2},\r
+{0x88e5,0x34},\r
+{0x88e6,0xe5},\r
+{0x88e7,0x41},\r
+{0x88e8,0x12},\r
+{0x88e9,0x06},\r
+{0x88ea,0xb1},\r
+{0x88eb,0x09},\r
+{0x88ec,0x31},\r
+{0x88ed,0x03},\r
+{0x88ee,0x09},\r
+{0x88ef,0x35},\r
+{0x88f0,0x04},\r
+{0x88f1,0x09},\r
+{0x88f2,0x3b},\r
+{0x88f3,0x05},\r
+{0x88f4,0x09},\r
+{0x88f5,0x3e},\r
+{0x88f6,0x06},\r
+{0x88f7,0x09},\r
+{0x88f8,0x41},\r
+{0x88f9,0x07},\r
+{0x88fa,0x09},\r
+{0x88fb,0x4a},\r
+{0x88fc,0x08},\r
+{0x88fd,0x09},\r
+{0x88fe,0x5b},\r
+{0x88ff,0x12},\r
+{0x8900,0x09},\r
+{0x8901,0x73},\r
+{0x8902,0x18},\r
+{0x8903,0x09},\r
+{0x8904,0x89},\r
+{0x8905,0x19},\r
+{0x8906,0x09},\r
+{0x8907,0x5e},\r
+{0x8908,0x1a},\r
+{0x8909,0x09},\r
+{0x890a,0x6a},\r
+{0x890b,0x1b},\r
+{0x890c,0x09},\r
+{0x890d,0xad},\r
+{0x890e,0x80},\r
+{0x890f,0x09},\r
+{0x8910,0xb2},\r
+{0x8911,0x81},\r
+{0x8912,0x0a},\r
+{0x8913,0x1d},\r
+{0x8914,0x8f},\r
+{0x8915,0x0a},\r
+{0x8916,0x09},\r
+{0x8917,0x90},\r
+{0x8918,0x0a},\r
+{0x8919,0x1d},\r
+{0x891a,0x91},\r
+{0x891b,0x0a},\r
+{0x891c,0x1d},\r
+{0x891d,0x92},\r
+{0x891e,0x0a},\r
+{0x891f,0x1d},\r
+{0x8920,0x93},\r
+{0x8921,0x0a},\r
+{0x8922,0x1d},\r
+{0x8923,0x94},\r
+{0x8924,0x0a},\r
+{0x8925,0x1d},\r
+{0x8926,0x98},\r
+{0x8927,0x0a},\r
+{0x8928,0x17},\r
+{0x8929,0x9f},\r
+{0x892a,0x0a},\r
+{0x892b,0x1a},\r
+{0x892c,0xec},\r
+{0x892d,0x00},\r
+{0x892e,0x00},\r
+{0x892f,0x0a},\r
+{0x8930,0x38},\r
+{0x8931,0x12},\r
+{0x8932,0x0f},\r
+{0x8933,0x74},\r
+{0x8934,0x22},\r
+{0x8935,0x12},\r
+{0x8936,0x0f},\r
+{0x8937,0x74},\r
+{0x8938,0xd2},\r
+{0x8939,0x03},\r
+{0x893a,0x22},\r
+{0x893b,0xd2},\r
+{0x893c,0x03},\r
+{0x893d,0x22},\r
+{0x893e,0xc2},\r
+{0x893f,0x03},\r
+{0x8940,0x22},\r
+{0x8941,0xa2},\r
+{0x8942,0x37},\r
+{0x8943,0xe4},\r
+{0x8944,0x33},\r
+{0x8945,0xf5},\r
+{0x8946,0x3c},\r
+{0x8947,0x02},\r
+{0x8948,0x0a},\r
+{0x8949,0x1d},\r
+{0x894a,0xc2},\r
+{0x894b,0x01},\r
+{0x894c,0xc2},\r
+{0x894d,0x02},\r
+{0x894e,0xc2},\r
+{0x894f,0x03},\r
+{0x8950,0x12},\r
+{0x8951,0x0d},\r
+{0x8952,0x0d},\r
+{0x8953,0x75},\r
+{0x8954,0x1e},\r
+{0x8955,0x70},\r
+{0x8956,0xd2},\r
+{0x8957,0x35},\r
+{0x8958,0x02},\r
+{0x8959,0x0a},\r
+{0x895a,0x1d},\r
+{0x895b,0x02},\r
+{0x895c,0x0a},\r
+{0x895d,0x04},\r
+{0x895e,0x85},\r
+{0x895f,0x40},\r
+{0x8960,0x4a},\r
+{0x8961,0x85},\r
+{0x8962,0x3c},\r
+{0x8963,0x4b},\r
+{0x8964,0x12},\r
+{0x8965,0x0a},\r
+{0x8966,0xff},\r
+{0x8967,0x02},\r
+{0x8968,0x0a},\r
+{0x8969,0x1d},\r
+{0x896a,0x85},\r
+{0x896b,0x4a},\r
+{0x896c,0x40},\r
+{0x896d,0x85},\r
+{0x896e,0x4b},\r
+{0x896f,0x3c},\r
+{0x8970,0x02},\r
+{0x8971,0x0a},\r
+{0x8972,0x1d},\r
+{0x8973,0xe4},\r
+{0x8974,0xf5},\r
+{0x8975,0x22},\r
+{0x8976,0xf5},\r
+{0x8977,0x23},\r
+{0x8978,0x85},\r
+{0x8979,0x40},\r
+{0x897a,0x31},\r
+{0x897b,0x85},\r
+{0x897c,0x3f},\r
+{0x897d,0x30},\r
+{0x897e,0x85},\r
+{0x897f,0x3e},\r
+{0x8980,0x2f},\r
+{0x8981,0x85},\r
+{0x8982,0x3d},\r
+{0x8983,0x2e},\r
+{0x8984,0x12},\r
+{0x8985,0x0f},\r
+{0x8986,0x46},\r
+{0x8987,0x80},\r
+{0x8988,0x1f},\r
+{0x8989,0x75},\r
+{0x898a,0x22},\r
+{0x898b,0x00},\r
+{0x898c,0x75},\r
+{0x898d,0x23},\r
+{0x898e,0x01},\r
+{0x898f,0x74},\r
+{0x8990,0xff},\r
+{0x8991,0xf5},\r
+{0x8992,0x2d},\r
+{0x8993,0xf5},\r
+{0x8994,0x2c},\r
+{0x8995,0xf5},\r
+{0x8996,0x2b},\r
+{0x8997,0xf5},\r
+{0x8998,0x2a},\r
+{0x8999,0x12},\r
+{0x899a,0x0f},\r
+{0x899b,0x46},\r
+{0x899c,0x85},\r
+{0x899d,0x2d},\r
+{0x899e,0x40},\r
+{0x899f,0x85},\r
+{0x89a0,0x2c},\r
+{0x89a1,0x3f},\r
+{0x89a2,0x85},\r
+{0x89a3,0x2b},\r
+{0x89a4,0x3e},\r
+{0x89a5,0x85},\r
+{0x89a6,0x2a},\r
+{0x89a7,0x3d},\r
+{0x89a8,0xe4},\r
+{0x89a9,0xf5},\r
+{0x89aa,0x3c},\r
+{0x89ab,0x80},\r
+{0x89ac,0x70},\r
+{0x89ad,0x12},\r
+{0x89ae,0x0f},\r
+{0x89af,0x16},\r
+{0x89b0,0x80},\r
+{0x89b1,0x6b},\r
+{0x89b2,0x85},\r
+{0x89b3,0x3d},\r
+{0x89b4,0x45},\r
+{0x89b5,0x85},\r
+{0x89b6,0x3e},\r
+{0x89b7,0x46},\r
+{0x89b8,0xe5},\r
+{0x89b9,0x47},\r
+{0x89ba,0xc3},\r
+{0x89bb,0x13},\r
+{0x89bc,0xff},\r
+{0x89bd,0xe5},\r
+{0x89be,0x45},\r
+{0x89bf,0xc3},\r
+{0x89c0,0x9f},\r
+{0x89c1,0x50},\r
+{0x89c2,0x02},\r
+{0x89c3,0x8f},\r
+{0x89c4,0x45},\r
+{0x89c5,0xe5},\r
+{0x89c6,0x48},\r
+{0x89c7,0xc3},\r
+{0x89c8,0x13},\r
+{0x89c9,0xff},\r
+{0x89ca,0xe5},\r
+{0x89cb,0x46},\r
+{0x89cc,0xc3},\r
+{0x89cd,0x9f},\r
+{0x89ce,0x50},\r
+{0x89cf,0x02},\r
+{0x89d0,0x8f},\r
+{0x89d1,0x46},\r
+{0x89d2,0xe5},\r
+{0x89d3,0x47},\r
+{0x89d4,0xc3},\r
+{0x89d5,0x13},\r
+{0x89d6,0xff},\r
+{0x89d7,0xfd},\r
+{0x89d8,0xe5},\r
+{0x89d9,0x45},\r
+{0x89da,0x2d},\r
+{0x89db,0xfd},\r
+{0x89dc,0xe4},\r
+{0x89dd,0x33},\r
+{0x89de,0xfc},\r
+{0x89df,0xe5},\r
+{0x89e0,0x44},\r
+{0x89e1,0x12},\r
+{0x89e2,0x0f},\r
+{0x89e3,0x90},\r
+{0x89e4,0x40},\r
+{0x89e5,0x05},\r
+{0x89e6,0xe5},\r
+{0x89e7,0x44},\r
+{0x89e8,0x9f},\r
+{0x89e9,0xf5},\r
+{0x89ea,0x45},\r
+{0x89eb,0xe5},\r
+{0x89ec,0x48},\r
+{0x89ed,0xc3},\r
+{0x89ee,0x13},\r
+{0x89ef,0xff},\r
+{0x89f0,0xfd},\r
+{0x89f1,0xe5},\r
+{0x89f2,0x46},\r
+{0x89f3,0x2d},\r
+{0x89f4,0xfd},\r
+{0x89f5,0xe4},\r
+{0x89f6,0x33},\r
+{0x89f7,0xfc},\r
+{0x89f8,0xe5},\r
+{0x89f9,0x43},\r
+{0x89fa,0x12},\r
+{0x89fb,0x0f},\r
+{0x89fc,0x90},\r
+{0x89fd,0x40},\r
+{0x89fe,0x05},\r
+{0x89ff,0xe5},\r
+{0x8a00,0x43},\r
+{0x8a01,0x9f},\r
+{0x8a02,0xf5},\r
+{0x8a03,0x46},\r
+{0x8a04,0x12},\r
+{0x8a05,0x06},\r
+{0x8a06,0xd7},\r
+{0x8a07,0x80},\r
+{0x8a08,0x14},\r
+{0x8a09,0x85},\r
+{0x8a0a,0x40},\r
+{0x8a0b,0x48},\r
+{0x8a0c,0x85},\r
+{0x8a0d,0x3f},\r
+{0x8a0e,0x47},\r
+{0x8a0f,0x85},\r
+{0x8a10,0x3e},\r
+{0x8a11,0x46},\r
+{0x8a12,0x85},\r
+{0x8a13,0x3d},\r
+{0x8a14,0x45},\r
+{0x8a15,0x80},\r
+{0x8a16,0x06},\r
+{0x8a17,0x02},\r
+{0x8a18,0x06},\r
+{0x8a19,0xd7},\r
+{0x8a1a,0x12},\r
+{0x8a1b,0x0d},\r
+{0x8a1c,0x7e},\r
+{0x8a1d,0x90},\r
+{0x8a1e,0x30},\r
+{0x8a1f,0x24},\r
+{0x8a20,0xe5},\r
+{0x8a21,0x3d},\r
+{0x8a22,0xf0},\r
+{0x8a23,0xa3},\r
+{0x8a24,0xe5},\r
+{0x8a25,0x3e},\r
+{0x8a26,0xf0},\r
+{0x8a27,0xa3},\r
+{0x8a28,0xe5},\r
+{0x8a29,0x3f},\r
+{0x8a2a,0xf0},\r
+{0x8a2b,0xa3},\r
+{0x8a2c,0xe5},\r
+{0x8a2d,0x40},\r
+{0x8a2e,0xf0},\r
+{0x8a2f,0xa3},\r
+{0x8a30,0xe5},\r
+{0x8a31,0x3c},\r
+{0x8a32,0xf0},\r
+{0x8a33,0x90},\r
+{0x8a34,0x30},\r
+{0x8a35,0x23},\r
+{0x8a36,0xe4},\r
+{0x8a37,0xf0},\r
+{0x8a38,0x22},\r
+{0x8a39,0xc0},\r
+{0x8a3a,0xe0},\r
+{0x8a3b,0xc0},\r
+{0x8a3c,0x83},\r
+{0x8a3d,0xc0},\r
+{0x8a3e,0x82},\r
+{0x8a3f,0xc0},\r
+{0x8a40,0xd0},\r
+{0x8a41,0x90},\r
+{0x8a42,0x3f},\r
+{0x8a43,0x0c},\r
+{0x8a44,0xe0},\r
+{0x8a45,0xf5},\r
+{0x8a46,0x32},\r
+{0x8a47,0xe5},\r
+{0x8a48,0x32},\r
+{0x8a49,0x30},\r
+{0x8a4a,0xe3},\r
+{0x8a4b,0x74},\r
+{0x8a4c,0x30},\r
+{0x8a4d,0x36},\r
+{0x8a4e,0x66},\r
+{0x8a4f,0x90},\r
+{0x8a50,0x60},\r
+{0x8a51,0x19},\r
+{0x8a52,0xe0},\r
+{0x8a53,0xf5},\r
+{0x8a54,0x0a},\r
+{0x8a55,0xa3},\r
+{0x8a56,0xe0},\r
+{0x8a57,0xf5},\r
+{0x8a58,0x0b},\r
+{0x8a59,0x90},\r
+{0x8a5a,0x60},\r
+{0x8a5b,0x1d},\r
+{0x8a5c,0xe0},\r
+{0x8a5d,0xf5},\r
+{0x8a5e,0x14},\r
+{0x8a5f,0xa3},\r
+{0x8a60,0xe0},\r
+{0x8a61,0xf5},\r
+{0x8a62,0x15},\r
+{0x8a63,0x90},\r
+{0x8a64,0x60},\r
+{0x8a65,0x21},\r
+{0x8a66,0xe0},\r
+{0x8a67,0xf5},\r
+{0x8a68,0x0c},\r
+{0x8a69,0xa3},\r
+{0x8a6a,0xe0},\r
+{0x8a6b,0xf5},\r
+{0x8a6c,0x0d},\r
+{0x8a6d,0x90},\r
+{0x8a6e,0x60},\r
+{0x8a6f,0x29},\r
+{0x8a70,0xe0},\r
+{0x8a71,0xf5},\r
+{0x8a72,0x0e},\r
+{0x8a73,0xa3},\r
+{0x8a74,0xe0},\r
+{0x8a75,0xf5},\r
+{0x8a76,0x0f},\r
+{0x8a77,0x90},\r
+{0x8a78,0x60},\r
+{0x8a79,0x31},\r
+{0x8a7a,0xe0},\r
+{0x8a7b,0xf5},\r
+{0x8a7c,0x10},\r
+{0x8a7d,0xa3},\r
+{0x8a7e,0xe0},\r
+{0x8a7f,0xf5},\r
+{0x8a80,0x11},\r
+{0x8a81,0x90},\r
+{0x8a82,0x60},\r
+{0x8a83,0x39},\r
+{0x8a84,0xe0},\r
+{0x8a85,0xf5},\r
+{0x8a86,0x12},\r
+{0x8a87,0xa3},\r
+{0x8a88,0xe0},\r
+{0x8a89,0xf5},\r
+{0x8a8a,0x13},\r
+{0x8a8b,0x30},\r
+{0x8a8c,0x01},\r
+{0x8a8d,0x06},\r
+{0x8a8e,0x30},\r
+{0x8a8f,0x33},\r
+{0x8a90,0x03},\r
+{0x8a91,0xd3},\r
+{0x8a92,0x80},\r
+{0x8a93,0x01},\r
+{0x8a94,0xc3},\r
+{0x8a95,0x92},\r
+{0x8a96,0x09},\r
+{0x8a97,0x30},\r
+{0x8a98,0x02},\r
+{0x8a99,0x06},\r
+{0x8a9a,0x30},\r
+{0x8a9b,0x33},\r
+{0x8a9c,0x03},\r
+{0x8a9d,0xd3},\r
+{0x8a9e,0x80},\r
+{0x8a9f,0x01},\r
+{0x8aa0,0xc3},\r
+{0x8aa1,0x92},\r
+{0x8aa2,0x0a},\r
+{0x8aa3,0x30},\r
+{0x8aa4,0x33},\r
+{0x8aa5,0x0c},\r
+{0x8aa6,0x30},\r
+{0x8aa7,0x03},\r
+{0x8aa8,0x09},\r
+{0x8aa9,0x20},\r
+{0x8aaa,0x02},\r
+{0x8aab,0x06},\r
+{0x8aac,0x20},\r
+{0x8aad,0x01},\r
+{0x8aae,0x03},\r
+{0x8aaf,0xd3},\r
+{0x8ab0,0x80},\r
+{0x8ab1,0x01},\r
+{0x8ab2,0xc3},\r
+{0x8ab3,0x92},\r
+{0x8ab4,0x0b},\r
+{0x8ab5,0x90},\r
+{0x8ab6,0x30},\r
+{0x8ab7,0x01},\r
+{0x8ab8,0xe0},\r
+{0x8ab9,0x44},\r
+{0x8aba,0x40},\r
+{0x8abb,0xf0},\r
+{0x8abc,0xe0},\r
+{0x8abd,0x54},\r
+{0x8abe,0xbf},\r
+{0x8abf,0xf0},\r
+{0x8ac0,0xe5},\r
+{0x8ac1,0x32},\r
+{0x8ac2,0x30},\r
+{0x8ac3,0xe1},\r
+{0x8ac4,0x14},\r
+{0x8ac5,0x30},\r
+{0x8ac6,0x34},\r
+{0x8ac7,0x11},\r
+{0x8ac8,0x90},\r
+{0x8ac9,0x30},\r
+{0x8aca,0x22},\r
+{0x8acb,0xe0},\r
+{0x8acc,0xf5},\r
+{0x8acd,0x08},\r
+{0x8ace,0xe4},\r
+{0x8acf,0xf0},\r
+{0x8ad0,0x30},\r
+{0x8ad1,0x00},\r
+{0x8ad2,0x03},\r
+{0x8ad3,0xd3},\r
+{0x8ad4,0x80},\r
+{0x8ad5,0x01},\r
+{0x8ad6,0xc3},\r
+{0x8ad7,0x92},\r
+{0x8ad8,0x08},\r
+{0x8ad9,0xe5},\r
+{0x8ada,0x32},\r
+{0x8adb,0x30},\r
+{0x8adc,0xe5},\r
+{0x8add,0x12},\r
+{0x8ade,0x90},\r
+{0x8adf,0x56},\r
+{0x8ae0,0xa1},\r
+{0x8ae1,0xe0},\r
+{0x8ae2,0xf5},\r
+{0x8ae3,0x09},\r
+{0x8ae4,0x30},\r
+{0x8ae5,0x31},\r
+{0x8ae6,0x09},\r
+{0x8ae7,0x30},\r
+{0x8ae8,0x05},\r
+{0x8ae9,0x03},\r
+{0x8aea,0xd3},\r
+{0x8aeb,0x80},\r
+{0x8aec,0x01},\r
+{0x8aed,0xc3},\r
+{0x8aee,0x92},\r
+{0x8aef,0x0d},\r
+{0x8af0,0x90},\r
+{0x8af1,0x3f},\r
+{0x8af2,0x0c},\r
+{0x8af3,0xe5},\r
+{0x8af4,0x32},\r
+{0x8af5,0xf0},\r
+{0x8af6,0xd0},\r
+{0x8af7,0xd0},\r
+{0x8af8,0xd0},\r
+{0x8af9,0x82},\r
+{0x8afa,0xd0},\r
+{0x8afb,0x83},\r
+{0x8afc,0xd0},\r
+{0x8afd,0xe0},\r
+{0x8afe,0x32},\r
+{0x8aff,0x90},\r
+{0x8b00,0x0e},\r
+{0x8b01,0x7e},\r
+{0x8b02,0xe4},\r
+{0x8b03,0x93},\r
+{0x8b04,0xfe},\r
+{0x8b05,0x74},\r
+{0x8b06,0x01},\r
+{0x8b07,0x93},\r
+{0x8b08,0xff},\r
+{0x8b09,0xc3},\r
+{0x8b0a,0x90},\r
+{0x8b0b,0x0e},\r
+{0x8b0c,0x7c},\r
+{0x8b0d,0x74},\r
+{0x8b0e,0x01},\r
+{0x8b0f,0x93},\r
+{0x8b10,0x9f},\r
+{0x8b11,0xff},\r
+{0x8b12,0xe4},\r
+{0x8b13,0x93},\r
+{0x8b14,0x9e},\r
+{0x8b15,0xfe},\r
+{0x8b16,0xe4},\r
+{0x8b17,0x8f},\r
+{0x8b18,0x3b},\r
+{0x8b19,0x8e},\r
+{0x8b1a,0x3a},\r
+{0x8b1b,0xf5},\r
+{0x8b1c,0x39},\r
+{0x8b1d,0xf5},\r
+{0x8b1e,0x38},\r
+{0x8b1f,0xab},\r
+{0x8b20,0x3b},\r
+{0x8b21,0xaa},\r
+{0x8b22,0x3a},\r
+{0x8b23,0xa9},\r
+{0x8b24,0x39},\r
+{0x8b25,0xa8},\r
+{0x8b26,0x38},\r
+{0x8b27,0xaf},\r
+{0x8b28,0x4b},\r
+{0x8b29,0xfc},\r
+{0x8b2a,0xfd},\r
+{0x8b2b,0xfe},\r
+{0x8b2c,0x12},\r
+{0x8b2d,0x05},\r
+{0x8b2e,0x28},\r
+{0x8b2f,0x12},\r
+{0x8b30,0x0d},\r
+{0x8b31,0xe1},\r
+{0x8b32,0xe4},\r
+{0x8b33,0x7b},\r
+{0x8b34,0xff},\r
+{0x8b35,0xfa},\r
+{0x8b36,0xf9},\r
+{0x8b37,0xf8},\r
+{0x8b38,0x12},\r
+{0x8b39,0x05},\r
+{0x8b3a,0xb3},\r
+{0x8b3b,0x12},\r
+{0x8b3c,0x0d},\r
+{0x8b3d,0xe1},\r
+{0x8b3e,0x90},\r
+{0x8b3f,0x0e},\r
+{0x8b40,0x69},\r
+{0x8b41,0xe4},\r
+{0x8b42,0x12},\r
+{0x8b43,0x0d},\r
+{0x8b44,0xf6},\r
+{0x8b45,0x12},\r
+{0x8b46,0x0d},\r
+{0x8b47,0xe1},\r
+{0x8b48,0xe4},\r
+{0x8b49,0x85},\r
+{0x8b4a,0x4a},\r
+{0x8b4b,0x37},\r
+{0x8b4c,0xf5},\r
+{0x8b4d,0x36},\r
+{0x8b4e,0xf5},\r
+{0x8b4f,0x35},\r
+{0x8b50,0xf5},\r
+{0x8b51,0x34},\r
+{0x8b52,0xaf},\r
+{0x8b53,0x37},\r
+{0x8b54,0xae},\r
+{0x8b55,0x36},\r
+{0x8b56,0xad},\r
+{0x8b57,0x35},\r
+{0x8b58,0xac},\r
+{0x8b59,0x34},\r
+{0x8b5a,0xa3},\r
+{0x8b5b,0x12},\r
+{0x8b5c,0x0d},\r
+{0x8b5d,0xf6},\r
+{0x8b5e,0x8f},\r
+{0x8b5f,0x37},\r
+{0x8b60,0x8e},\r
+{0x8b61,0x36},\r
+{0x8b62,0x8d},\r
+{0x8b63,0x35},\r
+{0x8b64,0x8c},\r
+{0x8b65,0x34},\r
+{0x8b66,0xe5},\r
+{0x8b67,0x3b},\r
+{0x8b68,0x45},\r
+{0x8b69,0x37},\r
+{0x8b6a,0xf5},\r
+{0x8b6b,0x3b},\r
+{0x8b6c,0xe5},\r
+{0x8b6d,0x3a},\r
+{0x8b6e,0x45},\r
+{0x8b6f,0x36},\r
+{0x8b70,0xf5},\r
+{0x8b71,0x3a},\r
+{0x8b72,0xe5},\r
+{0x8b73,0x39},\r
+{0x8b74,0x45},\r
+{0x8b75,0x35},\r
+{0x8b76,0xf5},\r
+{0x8b77,0x39},\r
+{0x8b78,0xe5},\r
+{0x8b79,0x38},\r
+{0x8b7a,0x45},\r
+{0x8b7b,0x34},\r
+{0x8b7c,0xf5},\r
+{0x8b7d,0x38},\r
+{0x8b7e,0xe4},\r
+{0x8b7f,0xf5},\r
+{0x8b80,0x22},\r
+{0x8b81,0xf5},\r
+{0x8b82,0x23},\r
+{0x8b83,0x85},\r
+{0x8b84,0x3b},\r
+{0x8b85,0x31},\r
+{0x8b86,0x85},\r
+{0x8b87,0x3a},\r
+{0x8b88,0x30},\r
+{0x8b89,0x85},\r
+{0x8b8a,0x39},\r
+{0x8b8b,0x2f},\r
+{0x8b8c,0x85},\r
+{0x8b8d,0x38},\r
+{0x8b8e,0x2e},\r
+{0x8b8f,0x02},\r
+{0x8b90,0x0f},\r
+{0x8b91,0x46},\r
+{0x8b92,0xe0},\r
+{0x8b93,0xa3},\r
+{0x8b94,0xe0},\r
+{0x8b95,0x75},\r
+{0x8b96,0xf0},\r
+{0x8b97,0x02},\r
+{0x8b98,0xa4},\r
+{0x8b99,0xff},\r
+{0x8b9a,0xae},\r
+{0x8b9b,0xf0},\r
+{0x8b9c,0xc3},\r
+{0x8b9d,0x08},\r
+{0x8b9e,0xe6},\r
+{0x8b9f,0x9f},\r
+{0x8ba0,0xf6},\r
+{0x8ba1,0x18},\r
+{0x8ba2,0xe6},\r
+{0x8ba3,0x9e},\r
+{0x8ba4,0xf6},\r
+{0x8ba5,0x22},\r
+{0x8ba6,0xff},\r
+{0x8ba7,0xe5},\r
+{0x8ba8,0xf0},\r
+{0x8ba9,0x34},\r
+{0x8baa,0x60},\r
+{0x8bab,0x8f},\r
+{0x8bac,0x82},\r
+{0x8bad,0xf5},\r
+{0x8bae,0x83},\r
+{0x8baf,0xec},\r
+{0x8bb0,0xf0},\r
+{0x8bb1,0x22},\r
+{0x8bb2,0x78},\r
+{0x8bb3,0x52},\r
+{0x8bb4,0x7e},\r
+{0x8bb5,0x00},\r
+{0x8bb6,0xe6},\r
+{0x8bb7,0xfc},\r
+{0x8bb8,0x08},\r
+{0x8bb9,0xe6},\r
+{0x8bba,0xfd},\r
+{0x8bbb,0x02},\r
+{0x8bbc,0x04},\r
+{0x8bbd,0xc1},\r
+{0x8bbe,0xe4},\r
+{0x8bbf,0xfc},\r
+{0x8bc0,0xfd},\r
+{0x8bc1,0x12},\r
+{0x8bc2,0x06},\r
+{0x8bc3,0x99},\r
+{0x8bc4,0x78},\r
+{0x8bc5,0x5c},\r
+{0x8bc6,0xe6},\r
+{0x8bc7,0xc3},\r
+{0x8bc8,0x13},\r
+{0x8bc9,0xfe},\r
+{0x8bca,0x08},\r
+{0x8bcb,0xe6},\r
+{0x8bcc,0x13},\r
+{0x8bcd,0x22},\r
+{0x8bce,0x78},\r
+{0x8bcf,0x52},\r
+{0x8bd0,0xe6},\r
+{0x8bd1,0xfe},\r
+{0x8bd2,0x08},\r
+{0x8bd3,0xe6},\r
+{0x8bd4,0xff},\r
+{0x8bd5,0xe4},\r
+{0x8bd6,0xfc},\r
+{0x8bd7,0xfd},\r
+{0x8bd8,0x22},\r
+{0x8bd9,0xe7},\r
+{0x8bda,0xc4},\r
+{0x8bdb,0xf8},\r
+{0x8bdc,0x54},\r
+{0x8bdd,0xf0},\r
+{0x8bde,0xc8},\r
+{0x8bdf,0x68},\r
+{0x8be0,0xf7},\r
+{0x8be1,0x09},\r
+{0x8be2,0xe7},\r
+{0x8be3,0xc4},\r
+{0x8be4,0x54},\r
+{0x8be5,0x0f},\r
+{0x8be6,0x48},\r
+{0x8be7,0xf7},\r
+{0x8be8,0x22},\r
+{0x8be9,0xe6},\r
+{0x8bea,0xfc},\r
+{0x8beb,0xed},\r
+{0x8bec,0x75},\r
+{0x8bed,0xf0},\r
+{0x8bee,0x04},\r
+{0x8bef,0xa4},\r
+{0x8bf0,0x22},\r
+{0x8bf1,0x12},\r
+{0x8bf2,0x06},\r
+{0x8bf3,0x7c},\r
+{0x8bf4,0x8f},\r
+{0x8bf5,0x48},\r
+{0x8bf6,0x8e},\r
+{0x8bf7,0x47},\r
+{0x8bf8,0x8d},\r
+{0x8bf9,0x46},\r
+{0x8bfa,0x8c},\r
+{0x8bfb,0x45},\r
+{0x8bfc,0x22},\r
+{0x8bfd,0xe0},\r
+{0x8bfe,0xfe},\r
+{0x8bff,0xa3},\r
+{0x8c00,0xe0},\r
+{0x8c01,0xfd},\r
+{0x8c02,0xee},\r
+{0x8c03,0xf6},\r
+{0x8c04,0xed},\r
+{0x8c05,0x08},\r
+{0x8c06,0xf6},\r
+{0x8c07,0x22},\r
+{0x8c08,0x13},\r
+{0x8c09,0xff},\r
+{0x8c0a,0xc3},\r
+{0x8c0b,0xe6},\r
+{0x8c0c,0x9f},\r
+{0x8c0d,0xff},\r
+{0x8c0e,0x18},\r
+{0x8c0f,0xe6},\r
+{0x8c10,0x9e},\r
+{0x8c11,0xfe},\r
+{0x8c12,0x22},\r
+{0x8c13,0xe6},\r
+{0x8c14,0xc3},\r
+{0x8c15,0x13},\r
+{0x8c16,0xf7},\r
+{0x8c17,0x08},\r
+{0x8c18,0xe6},\r
+{0x8c19,0x13},\r
+{0x8c1a,0x09},\r
+{0x8c1b,0xf7},\r
+{0x8c1c,0x22},\r
+{0x8c1d,0xad},\r
+{0x8c1e,0x39},\r
+{0x8c1f,0xac},\r
+{0x8c20,0x38},\r
+{0x8c21,0xfa},\r
+{0x8c22,0xf9},\r
+{0x8c23,0xf8},\r
+{0x8c24,0x12},\r
+{0x8c25,0x05},\r
+{0x8c26,0x28},\r
+{0x8c27,0x8f},\r
+{0x8c28,0x3b},\r
+{0x8c29,0x8e},\r
+{0x8c2a,0x3a},\r
+{0x8c2b,0x8d},\r
+{0x8c2c,0x39},\r
+{0x8c2d,0x8c},\r
+{0x8c2e,0x38},\r
+{0x8c2f,0xab},\r
+{0x8c30,0x37},\r
+{0x8c31,0xaa},\r
+{0x8c32,0x36},\r
+{0x8c33,0xa9},\r
+{0x8c34,0x35},\r
+{0x8c35,0xa8},\r
+{0x8c36,0x34},\r
+{0x8c37,0x22},\r
+{0x8c38,0x93},\r
+{0x8c39,0xff},\r
+{0x8c3a,0xe4},\r
+{0x8c3b,0xfc},\r
+{0x8c3c,0xfd},\r
+{0x8c3d,0xfe},\r
+{0x8c3e,0x12},\r
+{0x8c3f,0x05},\r
+{0x8c40,0x28},\r
+{0x8c41,0x8f},\r
+{0x8c42,0x37},\r
+{0x8c43,0x8e},\r
+{0x8c44,0x36},\r
+{0x8c45,0x8d},\r
+{0x8c46,0x35},\r
+{0x8c47,0x8c},\r
+{0x8c48,0x34},\r
+{0x8c49,0x22},\r
+{0x8c4a,0x78},\r
+{0x8c4b,0x84},\r
+{0x8c4c,0xe6},\r
+{0x8c4d,0xfe},\r
+{0x8c4e,0x08},\r
+{0x8c4f,0xe6},\r
+{0x8c50,0xff},\r
+{0x8c51,0xe4},\r
+{0x8c52,0x8f},\r
+{0x8c53,0x37},\r
+{0x8c54,0x8e},\r
+{0x8c55,0x36},\r
+{0x8c56,0xf5},\r
+{0x8c57,0x35},\r
+{0x8c58,0xf5},\r
+{0x8c59,0x34},\r
+{0x8c5a,0x22},\r
+{0x8c5b,0x90},\r
+{0x8c5c,0x0e},\r
+{0x8c5d,0x8c},\r
+{0x8c5e,0xe4},\r
+{0x8c5f,0x93},\r
+{0x8c60,0x25},\r
+{0x8c61,0xe0},\r
+{0x8c62,0x24},\r
+{0x8c63,0x0a},\r
+{0x8c64,0xf8},\r
+{0x8c65,0xe6},\r
+{0x8c66,0xfe},\r
+{0x8c67,0x08},\r
+{0x8c68,0xe6},\r
+{0x8c69,0xff},\r
+{0x8c6a,0x22},\r
+{0x8c6b,0xe6},\r
+{0x8c6c,0xfe},\r
+{0x8c6d,0x08},\r
+{0x8c6e,0xe6},\r
+{0x8c6f,0xff},\r
+{0x8c70,0xe4},\r
+{0x8c71,0x8f},\r
+{0x8c72,0x3b},\r
+{0x8c73,0x8e},\r
+{0x8c74,0x3a},\r
+{0x8c75,0xf5},\r
+{0x8c76,0x39},\r
+{0x8c77,0xf5},\r
+{0x8c78,0x38},\r
+{0x8c79,0x22},\r
+{0x8c7a,0x78},\r
+{0x8c7b,0x4e},\r
+{0x8c7c,0xe6},\r
+{0x8c7d,0xfe},\r
+{0x8c7e,0x08},\r
+{0x8c7f,0xe6},\r
+{0x8c80,0xff},\r
+{0x8c81,0x22},\r
+{0x8c82,0xef},\r
+{0x8c83,0x25},\r
+{0x8c84,0xe0},\r
+{0x8c85,0x24},\r
+{0x8c86,0x4e},\r
+{0x8c87,0xf8},\r
+{0x8c88,0xe6},\r
+{0x8c89,0xfc},\r
+{0x8c8a,0x08},\r
+{0x8c8b,0xe6},\r
+{0x8c8c,0xfd},\r
+{0x8c8d,0x22},\r
+{0x8c8e,0x78},\r
+{0x8c8f,0x89},\r
+{0x8c90,0xef},\r
+{0x8c91,0x26},\r
+{0x8c92,0xf6},\r
+{0x8c93,0x18},\r
+{0x8c94,0xe4},\r
+{0x8c95,0x36},\r
+{0x8c96,0xf6},\r
+{0x8c97,0x22},\r
+{0x8c98,0x75},\r
+{0x8c99,0x89},\r
+{0x8c9a,0x03},\r
+{0x8c9b,0x75},\r
+{0x8c9c,0xa8},\r
+{0x8c9d,0x01},\r
+{0x8c9e,0x75},\r
+{0x8c9f,0xb8},\r
+{0x8ca0,0x04},\r
+{0x8ca1,0x75},\r
+{0x8ca2,0x34},\r
+{0x8ca3,0xff},\r
+{0x8ca4,0x75},\r
+{0x8ca5,0x35},\r
+{0x8ca6,0x0e},\r
+{0x8ca7,0x75},\r
+{0x8ca8,0x36},\r
+{0x8ca9,0x15},\r
+{0x8caa,0x75},\r
+{0x8cab,0x37},\r
+{0x8cac,0x0d},\r
+{0x8cad,0x12},\r
+{0x8cae,0x0e},\r
+{0x8caf,0x9a},\r
+{0x8cb0,0x12},\r
+{0x8cb1,0x00},\r
+{0x8cb2,0x09},\r
+{0x8cb3,0x12},\r
+{0x8cb4,0x0f},\r
+{0x8cb5,0x16},\r
+{0x8cb6,0x12},\r
+{0x8cb7,0x00},\r
+{0x8cb8,0x06},\r
+{0x8cb9,0xd2},\r
+{0x8cba,0x00},\r
+{0x8cbb,0xd2},\r
+{0x8cbc,0x34},\r
+{0x8cbd,0xd2},\r
+{0x8cbe,0xaf},\r
+{0x8cbf,0x75},\r
+{0x8cc0,0x34},\r
+{0x8cc1,0xff},\r
+{0x8cc2,0x75},\r
+{0x8cc3,0x35},\r
+{0x8cc4,0x0e},\r
+{0x8cc5,0x75},\r
+{0x8cc6,0x36},\r
+{0x8cc7,0x49},\r
+{0x8cc8,0x75},\r
+{0x8cc9,0x37},\r
+{0x8cca,0x03},\r
+{0x8ccb,0x12},\r
+{0x8ccc,0x0e},\r
+{0x8ccd,0x9a},\r
+{0x8cce,0x30},\r
+{0x8ccf,0x08},\r
+{0x8cd0,0x09},\r
+{0x8cd1,0xc2},\r
+{0x8cd2,0x34},\r
+{0x8cd3,0x12},\r
+{0x8cd4,0x08},\r
+{0x8cd5,0xcb},\r
+{0x8cd6,0xc2},\r
+{0x8cd7,0x08},\r
+{0x8cd8,0xd2},\r
+{0x8cd9,0x34},\r
+{0x8cda,0x30},\r
+{0x8cdb,0x0b},\r
+{0x8cdc,0x09},\r
+{0x8cdd,0xc2},\r
+{0x8cde,0x36},\r
+{0x8cdf,0x12},\r
+{0x8ce0,0x02},\r
+{0x8ce1,0x6c},\r
+{0x8ce2,0xc2},\r
+{0x8ce3,0x0b},\r
+{0x8ce4,0xd2},\r
+{0x8ce5,0x36},\r
+{0x8ce6,0x30},\r
+{0x8ce7,0x09},\r
+{0x8ce8,0x09},\r
+{0x8ce9,0xc2},\r
+{0x8cea,0x36},\r
+{0x8ceb,0x12},\r
+{0x8cec,0x00},\r
+{0x8ced,0x0e},\r
+{0x8cee,0xc2},\r
+{0x8cef,0x09},\r
+{0x8cf0,0xd2},\r
+{0x8cf1,0x36},\r
+{0x8cf2,0x30},\r
+{0x8cf3,0x0e},\r
+{0x8cf4,0x03},\r
+{0x8cf5,0x12},\r
+{0x8cf6,0x06},\r
+{0x8cf7,0xd7},\r
+{0x8cf8,0x30},\r
+{0x8cf9,0x35},\r
+{0x8cfa,0xd3},\r
+{0x8cfb,0x90},\r
+{0x8cfc,0x30},\r
+{0x8cfd,0x29},\r
+{0x8cfe,0xe5},\r
+{0x8cff,0x1e},\r
+{0x8d00,0xf0},\r
+{0x8d01,0xb4},\r
+{0x8d02,0x10},\r
+{0x8d03,0x05},\r
+{0x8d04,0x90},\r
+{0x8d05,0x30},\r
+{0x8d06,0x23},\r
+{0x8d07,0xe4},\r
+{0x8d08,0xf0},\r
+{0x8d09,0xc2},\r
+{0x8d0a,0x35},\r
+{0x8d0b,0x80},\r
+{0x8d0c,0xc1},\r
+{0x8d0d,0xe4},\r
+{0x8d0e,0xf5},\r
+{0x8d0f,0x4b},\r
+{0x8d10,0x90},\r
+{0x8d11,0x0e},\r
+{0x8d12,0x7a},\r
+{0x8d13,0x93},\r
+{0x8d14,0xff},\r
+{0x8d15,0xe4},\r
+{0x8d16,0x8f},\r
+{0x8d17,0x37},\r
+{0x8d18,0xf5},\r
+{0x8d19,0x36},\r
+{0x8d1a,0xf5},\r
+{0x8d1b,0x35},\r
+{0x8d1c,0xf5},\r
+{0x8d1d,0x34},\r
+{0x8d1e,0xaf},\r
+{0x8d1f,0x37},\r
+{0x8d20,0xae},\r
+{0x8d21,0x36},\r
+{0x8d22,0xad},\r
+{0x8d23,0x35},\r
+{0x8d24,0xac},\r
+{0x8d25,0x34},\r
+{0x8d26,0x90},\r
+{0x8d27,0x0e},\r
+{0x8d28,0x6a},\r
+{0x8d29,0x12},\r
+{0x8d2a,0x0d},\r
+{0x8d2b,0xf6},\r
+{0x8d2c,0x8f},\r
+{0x8d2d,0x37},\r
+{0x8d2e,0x8e},\r
+{0x8d2f,0x36},\r
+{0x8d30,0x8d},\r
+{0x8d31,0x35},\r
+{0x8d32,0x8c},\r
+{0x8d33,0x34},\r
+{0x8d34,0x90},\r
+{0x8d35,0x0e},\r
+{0x8d36,0x72},\r
+{0x8d37,0x12},\r
+{0x8d38,0x06},\r
+{0x8d39,0x7c},\r
+{0x8d3a,0xef},\r
+{0x8d3b,0x45},\r
+{0x8d3c,0x37},\r
+{0x8d3d,0xf5},\r
+{0x8d3e,0x37},\r
+{0x8d3f,0xee},\r
+{0x8d40,0x45},\r
+{0x8d41,0x36},\r
+{0x8d42,0xf5},\r
+{0x8d43,0x36},\r
+{0x8d44,0xed},\r
+{0x8d45,0x45},\r
+{0x8d46,0x35},\r
+{0x8d47,0xf5},\r
+{0x8d48,0x35},\r
+{0x8d49,0xec},\r
+{0x8d4a,0x45},\r
+{0x8d4b,0x34},\r
+{0x8d4c,0xf5},\r
+{0x8d4d,0x34},\r
+{0x8d4e,0xe4},\r
+{0x8d4f,0xf5},\r
+{0x8d50,0x22},\r
+{0x8d51,0xf5},\r
+{0x8d52,0x23},\r
+{0x8d53,0x85},\r
+{0x8d54,0x37},\r
+{0x8d55,0x31},\r
+{0x8d56,0x85},\r
+{0x8d57,0x36},\r
+{0x8d58,0x30},\r
+{0x8d59,0x85},\r
+{0x8d5a,0x35},\r
+{0x8d5b,0x2f},\r
+{0x8d5c,0x85},\r
+{0x8d5d,0x34},\r
+{0x8d5e,0x2e},\r
+{0x8d5f,0x12},\r
+{0x8d60,0x0f},\r
+{0x8d61,0x46},\r
+{0x8d62,0xe4},\r
+{0x8d63,0xf5},\r
+{0x8d64,0x22},\r
+{0x8d65,0xf5},\r
+{0x8d66,0x23},\r
+{0x8d67,0x90},\r
+{0x8d68,0x0e},\r
+{0x8d69,0x72},\r
+{0x8d6a,0x12},\r
+{0x8d6b,0x0d},\r
+{0x8d6c,0xea},\r
+{0x8d6d,0x12},\r
+{0x8d6e,0x0f},\r
+{0x8d6f,0x46},\r
+{0x8d70,0xe4},\r
+{0x8d71,0xf5},\r
+{0x8d72,0x22},\r
+{0x8d73,0xf5},\r
+{0x8d74,0x23},\r
+{0x8d75,0x90},\r
+{0x8d76,0x0e},\r
+{0x8d77,0x6e},\r
+{0x8d78,0x12},\r
+{0x8d79,0x0d},\r
+{0x8d7a,0xea},\r
+{0x8d7b,0x02},\r
+{0x8d7c,0x0f},\r
+{0x8d7d,0x46},\r
+{0x8d7e,0xe5},\r
+{0x8d7f,0x40},\r
+{0x8d80,0x24},\r
+{0x8d81,0xf2},\r
+{0x8d82,0xf5},\r
+{0x8d83,0x37},\r
+{0x8d84,0xe5},\r
+{0x8d85,0x3f},\r
+{0x8d86,0x34},\r
+{0x8d87,0x43},\r
+{0x8d88,0xf5},\r
+{0x8d89,0x36},\r
+{0x8d8a,0xe5},\r
+{0x8d8b,0x3e},\r
+{0x8d8c,0x34},\r
+{0x8d8d,0xa2},\r
+{0x8d8e,0xf5},\r
+{0x8d8f,0x35},\r
+{0x8d90,0xe5},\r
+{0x8d91,0x3d},\r
+{0x8d92,0x34},\r
+{0x8d93,0x28},\r
+{0x8d94,0xf5},\r
+{0x8d95,0x34},\r
+{0x8d96,0xe5},\r
+{0x8d97,0x37},\r
+{0x8d98,0xff},\r
+{0x8d99,0xe4},\r
+{0x8d9a,0xfe},\r
+{0x8d9b,0xfd},\r
+{0x8d9c,0xfc},\r
+{0x8d9d,0x78},\r
+{0x8d9e,0x18},\r
+{0x8d9f,0x12},\r
+{0x8da0,0x06},\r
+{0x8da1,0x69},\r
+{0x8da2,0x8f},\r
+{0x8da3,0x40},\r
+{0x8da4,0x8e},\r
+{0x8da5,0x3f},\r
+{0x8da6,0x8d},\r
+{0x8da7,0x3e},\r
+{0x8da8,0x8c},\r
+{0x8da9,0x3d},\r
+{0x8daa,0xe5},\r
+{0x8dab,0x37},\r
+{0x8dac,0x54},\r
+{0x8dad,0xa0},\r
+{0x8dae,0xff},\r
+{0x8daf,0xe5},\r
+{0x8db0,0x36},\r
+{0x8db1,0xfe},\r
+{0x8db2,0xe4},\r
+{0x8db3,0xfd},\r
+{0x8db4,0xfc},\r
+{0x8db5,0x78},\r
+{0x8db6,0x07},\r
+{0x8db7,0x12},\r
+{0x8db8,0x06},\r
+{0x8db9,0x56},\r
+{0x8dba,0x78},\r
+{0x8dbb,0x10},\r
+{0x8dbc,0x12},\r
+{0x8dbd,0x0f},\r
+{0x8dbe,0x9a},\r
+{0x8dbf,0xe4},\r
+{0x8dc0,0xff},\r
+{0x8dc1,0xfe},\r
+{0x8dc2,0xe5},\r
+{0x8dc3,0x35},\r
+{0x8dc4,0xfd},\r
+{0x8dc5,0xe4},\r
+{0x8dc6,0xfc},\r
+{0x8dc7,0x78},\r
+{0x8dc8,0x0e},\r
+{0x8dc9,0x12},\r
+{0x8dca,0x06},\r
+{0x8dcb,0x56},\r
+{0x8dcc,0x12},\r
+{0x8dcd,0x0f},\r
+{0x8dce,0x9d},\r
+{0x8dcf,0xe4},\r
+{0x8dd0,0xff},\r
+{0x8dd1,0xfe},\r
+{0x8dd2,0xfd},\r
+{0x8dd3,0xe5},\r
+{0x8dd4,0x34},\r
+{0x8dd5,0xfc},\r
+{0x8dd6,0x78},\r
+{0x8dd7,0x18},\r
+{0x8dd8,0x12},\r
+{0x8dd9,0x06},\r
+{0x8dda,0x56},\r
+{0x8ddb,0x78},\r
+{0x8ddc,0x08},\r
+{0x8ddd,0x12},\r
+{0x8dde,0x0f},\r
+{0x8ddf,0x9a},\r
+{0x8de0,0x22},\r
+{0x8de1,0x8f},\r
+{0x8de2,0x3b},\r
+{0x8de3,0x8e},\r
+{0x8de4,0x3a},\r
+{0x8de5,0x8d},\r
+{0x8de6,0x39},\r
+{0x8de7,0x8c},\r
+{0x8de8,0x38},\r
+{0x8de9,0x22},\r
+{0x8dea,0x12},\r
+{0x8deb,0x06},\r
+{0x8dec,0x7c},\r
+{0x8ded,0x8f},\r
+{0x8dee,0x31},\r
+{0x8def,0x8e},\r
+{0x8df0,0x30},\r
+{0x8df1,0x8d},\r
+{0x8df2,0x2f},\r
+{0x8df3,0x8c},\r
+{0x8df4,0x2e},\r
+{0x8df5,0x22},\r
+{0x8df6,0x93},\r
+{0x8df7,0xf9},\r
+{0x8df8,0xf8},\r
+{0x8df9,0x02},\r
+{0x8dfa,0x06},\r
+{0x8dfb,0x69},\r
+{0x8dfc,0x00},\r
+{0x8dfd,0x00},\r
+{0x8dfe,0x00},\r
+{0x8dff,0x00},\r
+{0x8e00,0x12},\r
+{0x8e01,0x01},\r
+{0x8e02,0x17},\r
+{0x8e03,0x08},\r
+{0x8e04,0x31},\r
+{0x8e05,0x15},\r
+{0x8e06,0x53},\r
+{0x8e07,0x54},\r
+{0x8e08,0x44},\r
+{0x8e09,0x20},\r
+{0x8e0a,0x20},\r
+{0x8e0b,0x20},\r
+{0x8e0c,0x20},\r
+{0x8e0d,0x20},\r
+{0x8e0e,0x13},\r
+{0x8e0f,0x01},\r
+{0x8e10,0x10},\r
+{0x8e11,0x01},\r
+{0x8e12,0x56},\r
+{0x8e13,0x40},\r
+{0x8e14,0x1a},\r
+{0x8e15,0x30},\r
+{0x8e16,0x29},\r
+{0x8e17,0x7e},\r
+{0x8e18,0x00},\r
+{0x8e19,0x30},\r
+{0x8e1a,0x04},\r
+{0x8e1b,0x20},\r
+{0x8e1c,0xdf},\r
+{0x8e1d,0x30},\r
+{0x8e1e,0x05},\r
+{0x8e1f,0x40},\r
+{0x8e20,0xbf},\r
+{0x8e21,0x50},\r
+{0x8e22,0x03},\r
+{0x8e23,0x00},\r
+{0x8e24,0xfd},\r
+{0x8e25,0x50},\r
+{0x8e26,0x27},\r
+{0x8e27,0x01},\r
+{0x8e28,0xfe},\r
+{0x8e29,0x60},\r
+{0x8e2a,0x00},\r
+{0x8e2b,0x11},\r
+{0x8e2c,0x00},\r
+{0x8e2d,0x3f},\r
+{0x8e2e,0x05},\r
+{0x8e2f,0x30},\r
+{0x8e30,0x00},\r
+{0x8e31,0x3f},\r
+{0x8e32,0x06},\r
+{0x8e33,0x22},\r
+{0x8e34,0x00},\r
+{0x8e35,0x3f},\r
+{0x8e36,0x01},\r
+{0x8e37,0x2a},\r
+{0x8e38,0x00},\r
+{0x8e39,0x3f},\r
+{0x8e3a,0x02},\r
+{0x8e3b,0x00},\r
+{0x8e3c,0x00},\r
+{0x8e3d,0x36},\r
+{0x8e3e,0x06},\r
+{0x8e3f,0x07},\r
+{0x8e40,0x00},\r
+{0x8e41,0x3f},\r
+{0x8e42,0x0b},\r
+{0x8e43,0x0f},\r
+{0x8e44,0xf0},\r
+{0x8e45,0x00},\r
+{0x8e46,0x00},\r
+{0x8e47,0x00},\r
+{0x8e48,0x00},\r
+{0x8e49,0x30},\r
+{0x8e4a,0x01},\r
+{0x8e4b,0x40},\r
+{0x8e4c,0xbf},\r
+{0x8e4d,0x30},\r
+{0x8e4e,0x01},\r
+{0x8e4f,0x00},\r
+{0x8e50,0xbf},\r
+{0x8e51,0x30},\r
+{0x8e52,0x29},\r
+{0x8e53,0x70},\r
+{0x8e54,0x00},\r
+{0x8e55,0x3a},\r
+{0x8e56,0x00},\r
+{0x8e57,0x00},\r
+{0x8e58,0xff},\r
+{0x8e59,0x3a},\r
+{0x8e5a,0x00},\r
+{0x8e5b,0x00},\r
+{0x8e5c,0xff},\r
+{0x8e5d,0x36},\r
+{0x8e5e,0x03},\r
+{0x8e5f,0x36},\r
+{0x8e60,0x02},\r
+{0x8e61,0x41},\r
+{0x8e62,0x44},\r
+{0x8e63,0x58},\r
+{0x8e64,0x20},\r
+{0x8e65,0x18},\r
+{0x8e66,0x10},\r
+{0x8e67,0x0a},\r
+{0x8e68,0x04},\r
+{0x8e69,0x04},\r
+{0x8e6a,0x00},\r
+{0x8e6b,0x03},\r
+{0x8e6c,0xff},\r
+{0x8e6d,0x64},\r
+{0x8e6e,0x00},\r
+{0x8e6f,0x00},\r
+{0x8e70,0x80},\r
+{0x8e71,0x00},\r
+{0x8e72,0x00},\r
+{0x8e73,0x00},\r
+{0x8e74,0x00},\r
+{0x8e75,0x00},\r
+{0x8e76,0x00},\r
+{0x8e77,0x02},\r
+{0x8e78,0x04},\r
+{0x8e79,0x06},\r
+{0x8e7a,0x06},\r
+{0x8e7b,0x00},\r
+{0x8e7c,0x02},\r
+{0x8e7d,0x60},//CC\r
+{0x8e7e,0x00},\r
+{0x8e7f,0x70},\r
+{0x8e80,0x50},\r
+{0x8e81,0x3c},\r
+{0x8e82,0x28},\r
+{0x8e83,0x1e},\r
+{0x8e84,0x10},\r
+{0x8e85,0x10},\r
+{0x8e86,0x50},\r
+{0x8e87,0x2d},\r
+{0x8e88,0x28},\r
+{0x8e89,0x16},\r
+{0x8e8a,0x10},\r
+{0x8e8b,0x10},\r
+{0x8e8c,0x02},\r
+{0x8e8d,0x00},\r
+{0x8e8e,0x10},\r
+{0x8e8f,0x0c},\r
+{0x8e90,0x10},\r
+{0x8e91,0x04},\r
+{0x8e92,0x0c},\r
+{0x8e93,0x6e},\r
+{0x8e94,0x0a},\r
+{0x8e95,0x05},\r
+{0x8e96,0x00},\r
+{0x8e97,0xa5},\r
+{0x8e98,0x5a},\r
+{0x8e99,0x00},\r
+{0x8e9a,0xae},\r
+{0x8e9b,0x35},\r
+{0x8e9c,0xaf},\r
+{0x8e9d,0x36},\r
+{0x8e9e,0xe4},\r
+{0x8e9f,0xfd},\r
+{0x8ea0,0xed},\r
+{0x8ea1,0xc3},\r
+{0x8ea2,0x95},\r
+{0x8ea3,0x37},\r
+{0x8ea4,0x50},\r
+{0x8ea5,0x33},\r
+{0x8ea6,0x12},\r
+{0x8ea7,0x0f},\r
+{0x8ea8,0xe2},\r
+{0x8ea9,0xe4},\r
+{0x8eaa,0x93},\r
+{0x8eab,0xf5},\r
+{0x8eac,0x38},\r
+{0x8ead,0x74},\r
+{0x8eae,0x01},\r
+{0x8eaf,0x93},\r
+{0x8eb0,0xf5},\r
+{0x8eb1,0x39},\r
+{0x8eb2,0x45},\r
+{0x8eb3,0x38},\r
+{0x8eb4,0x60},\r
+{0x8eb5,0x23},\r
+{0x8eb6,0x85},\r
+{0x8eb7,0x39},\r
+{0x8eb8,0x82},\r
+{0x8eb9,0x85},\r
+{0x8eba,0x38},\r
+{0x8ebb,0x83},\r
+{0x8ebc,0xe0},\r
+{0x8ebd,0xfc},\r
+{0x8ebe,0x12},\r
+{0x8ebf,0x0f},\r
+{0x8ec0,0xe2},\r
+{0x8ec1,0x74},\r
+{0x8ec2,0x03},\r
+{0x8ec3,0x93},\r
+{0x8ec4,0x52},\r
+{0x8ec5,0x04},\r
+{0x8ec6,0x12},\r
+{0x8ec7,0x0f},\r
+{0x8ec8,0xe2},\r
+{0x8ec9,0x74},\r
+{0x8eca,0x02},\r
+{0x8ecb,0x93},\r
+{0x8ecc,0x42},\r
+{0x8ecd,0x04},\r
+{0x8ece,0x85},\r
+{0x8ecf,0x39},\r
+{0x8ed0,0x82},\r
+{0x8ed1,0x85},\r
+{0x8ed2,0x38},\r
+{0x8ed3,0x83},\r
+{0x8ed4,0xec},\r
+{0x8ed5,0xf0},\r
+{0x8ed6,0x0d},\r
+{0x8ed7,0x80},\r
+{0x8ed8,0xc7},\r
+{0x8ed9,0x22},\r
+{0x8eda,0x78},\r
+{0x8edb,0xbe},\r
+{0x8edc,0xe6},\r
+{0x8edd,0xd3},\r
+{0x8ede,0x08},\r
+{0x8edf,0xff},\r
+{0x8ee0,0xe6},\r
+{0x8ee1,0x64},\r
+{0x8ee2,0x80},\r
+{0x8ee3,0xf8},\r
+{0x8ee4,0xef},\r
+{0x8ee5,0x64},\r
+{0x8ee6,0x80},\r
+{0x8ee7,0x98},\r
+{0x8ee8,0x22},\r
+{0x8ee9,0x93},\r
+{0x8eea,0xff},\r
+{0x8eeb,0x7e},\r
+{0x8eec,0x00},\r
+{0x8eed,0xe6},\r
+{0x8eee,0xfc},\r
+{0x8eef,0x08},\r
+{0x8ef0,0xe6},\r
+{0x8ef1,0xfd},\r
+{0x8ef2,0x12},\r
+{0x8ef3,0x04},\r
+{0x8ef4,0xc1},\r
+{0x8ef5,0x78},\r
+{0x8ef6,0xc1},\r
+{0x8ef7,0xe6},\r
+{0x8ef8,0xfc},\r
+{0x8ef9,0x08},\r
+{0x8efa,0xe6},\r
+{0x8efb,0xfd},\r
+{0x8efc,0xd3},\r
+{0x8efd,0xef},\r
+{0x8efe,0x9d},\r
+{0x8eff,0xee},\r
+{0x8f00,0x9c},\r
+{0x8f01,0x22},\r
+{0x8f02,0x78},\r
+{0x8f03,0xbd},\r
+{0x8f04,0xd3},\r
+{0x8f05,0xe6},\r
+{0x8f06,0x64},\r
+{0x8f07,0x80},\r
+{0x8f08,0x94},\r
+{0x8f09,0x80},\r
+{0x8f0a,0x22},\r
+{0x8f0b,0x25},\r
+{0x8f0c,0xe0},\r
+{0x8f0d,0x24},\r
+{0x8f0e,0x0a},\r
+{0x8f0f,0xf8},\r
+{0x8f10,0xe6},\r
+{0x8f11,0xfe},\r
+{0x8f12,0x08},\r
+{0x8f13,0xe6},\r
+{0x8f14,0xff},\r
+{0x8f15,0x22},\r
+{0x8f16,0xe5},\r
+{0x8f17,0x3c},\r
+{0x8f18,0xd3},\r
+{0x8f19,0x94},\r
+{0x8f1a,0x00},\r
+{0x8f1b,0x40},\r
+{0x8f1c,0x0b},\r
+{0x8f1d,0x90},\r
+{0x8f1e,0x0e},\r
+{0x8f1f,0x88},\r
+{0x8f20,0x12},\r
+{0x8f21,0x0b},\r
+{0x8f22,0xf1},\r
+{0x8f23,0x90},\r
+{0x8f24,0x0e},\r
+{0x8f25,0x86},\r
+{0x8f26,0x80},\r
+{0x8f27,0x09},\r
+{0x8f28,0x90},\r
+{0x8f29,0x0e},\r
+{0x8f2a,0x82},\r
+{0x8f2b,0x12},\r
+{0x8f2c,0x0b},\r
+{0x8f2d,0xf1},\r
+{0x8f2e,0x90},\r
+{0x8f2f,0x0e},\r
+{0x8f30,0x80},\r
+{0x8f31,0xe4},\r
+{0x8f32,0x93},\r
+{0x8f33,0xf5},\r
+{0x8f34,0x44},\r
+{0x8f35,0xa3},\r
+{0x8f36,0xe4},\r
+{0x8f37,0x93},\r
+{0x8f38,0xf5},\r
+{0x8f39,0x43},\r
+{0x8f3a,0xd2},\r
+{0x8f3b,0x06},\r
+{0x8f3c,0x30},\r
+{0x8f3d,0x06},\r
+{0x8f3e,0x03},\r
+{0x8f3f,0xd3},\r
+{0x8f40,0x80},\r
+{0x8f41,0x01},\r
+{0x8f42,0xc3},\r
+{0x8f43,0x92},\r
+{0x8f44,0x0e},\r
+{0x8f45,0x22},\r
+{0x8f46,0xa2},\r
+{0x8f47,0xaf},\r
+{0x8f48,0x92},\r
+{0x8f49,0x32},\r
+{0x8f4a,0xc2},\r
+{0x8f4b,0xaf},\r
+{0x8f4c,0xe5},\r
+{0x8f4d,0x23},\r
+{0x8f4e,0x45},\r
+{0x8f4f,0x22},\r
+{0x8f50,0x90},\r
+{0x8f51,0x0e},\r
+{0x8f52,0x5d},\r
+{0x8f53,0x60},\r
+{0x8f54,0x0e},\r
+{0x8f55,0x12},\r
+{0x8f56,0x0f},\r
+{0x8f57,0xcb},\r
+{0x8f58,0xe0},\r
+{0x8f59,0xf5},\r
+{0x8f5a,0x2c},\r
+{0x8f5b,0x12},\r
+{0x8f5c,0x0f},\r
+{0x8f5d,0xc8},\r
+{0x8f5e,0xe0},\r
+{0x8f5f,0xf5},\r
+{0x8f60,0x2d},\r
+{0x8f61,0x80},\r
+{0x8f62,0x0c},\r
+{0x8f63,0x12},\r
+{0x8f64,0x0f},\r
+{0x8f65,0xcb},\r
+{0x8f66,0xe5},\r
+{0x8f67,0x30},\r
+{0x8f68,0xf0},\r
+{0x8f69,0x12},\r
+{0x8f6a,0x0f},\r
+{0x8f6b,0xc8},\r
+{0x8f6c,0xe5},\r
+{0x8f6d,0x31},\r
+{0x8f6e,0xf0},\r
+{0x8f6f,0xa2},\r
+{0x8f70,0x32},\r
+{0x8f71,0x92},\r
+{0x8f72,0xaf},\r
+{0x8f73,0x22},\r
+{0x8f74,0xd2},\r
+{0x8f75,0x01},\r
+{0x8f76,0xc2},\r
+{0x8f77,0x02},\r
+{0x8f78,0xe4},\r
+{0x8f79,0xf5},\r
+{0x8f7a,0x1f},\r
+{0x8f7b,0xf5},\r
+{0x8f7c,0x1e},\r
+{0x8f7d,0xd2},\r
+{0x8f7e,0x35},\r
+{0x8f7f,0xd2},\r
+{0x8f80,0x33},\r
+{0x8f81,0xd2},\r
+{0x8f82,0x36},\r
+{0x8f83,0xd2},\r
+{0x8f84,0x01},\r
+{0x8f85,0xc2},\r
+{0x8f86,0x02},\r
+{0x8f87,0xf5},\r
+{0x8f88,0x1f},\r
+{0x8f89,0xf5},\r
+{0x8f8a,0x1e},\r
+{0x8f8b,0xd2},\r
+{0x8f8c,0x35},\r
+{0x8f8d,0xd2},\r
+{0x8f8e,0x33},\r
+{0x8f8f,0x22},\r
+{0x8f90,0xfb},\r
+{0x8f91,0xd3},\r
+{0x8f92,0xed},\r
+{0x8f93,0x9b},\r
+{0x8f94,0x74},\r
+{0x8f95,0x80},\r
+{0x8f96,0xf8},\r
+{0x8f97,0x6c},\r
+{0x8f98,0x98},\r
+{0x8f99,0x22},\r
+{0x8f9a,0x12},\r
+{0x8f9b,0x06},\r
+{0x8f9c,0x69},\r
+{0x8f9d,0xe5},\r
+{0x8f9e,0x40},\r
+{0x8f9f,0x2f},\r
+{0x8fa0,0xf5},\r
+{0x8fa1,0x40},\r
+{0x8fa2,0xe5},\r
+{0x8fa3,0x3f},\r
+{0x8fa4,0x3e},\r
+{0x8fa5,0xf5},\r
+{0x8fa6,0x3f},\r
+{0x8fa7,0xe5},\r
+{0x8fa8,0x3e},\r
+{0x8fa9,0x3d},\r
+{0x8faa,0xf5},\r
+{0x8fab,0x3e},\r
+{0x8fac,0xe5},\r
+{0x8fad,0x3d},\r
+{0x8fae,0x3c},\r
+{0x8faf,0xf5},\r
+{0x8fb0,0x3d},\r
+{0x8fb1,0x22},\r
+{0x8fb2,0xc0},\r
+{0x8fb3,0xe0},\r
+{0x8fb4,0xc0},\r
+{0x8fb5,0x83},\r
+{0x8fb6,0xc0},\r
+{0x8fb7,0x82},\r
+{0x8fb8,0x90},\r
+{0x8fb9,0x3f},\r
+{0x8fba,0x0d},\r
+{0x8fbb,0xe0},\r
+{0x8fbc,0xf5},\r
+{0x8fbd,0x33},\r
+{0x8fbe,0xe5},\r
+{0x8fbf,0x33},\r
+{0x8fc0,0xf0},\r
+{0x8fc1,0xd0},\r
+{0x8fc2,0x82},\r
+{0x8fc3,0xd0},\r
+{0x8fc4,0x83},\r
+{0x8fc5,0xd0},\r
+{0x8fc6,0xe0},\r
+{0x8fc7,0x32},\r
+{0x8fc8,0x90},\r
+{0x8fc9,0x0e},\r
+{0x8fca,0x5f},\r
+{0x8fcb,0xe4},\r
+{0x8fcc,0x93},\r
+{0x8fcd,0xfe},\r
+{0x8fce,0x74},\r
+{0x8fcf,0x01},\r
+{0x8fd0,0x93},\r
+{0x8fd1,0xf5},\r
+{0x8fd2,0x82},\r
+{0x8fd3,0x8e},\r
+{0x8fd4,0x83},\r
+{0x8fd5,0x22},\r
+{0x8fd6,0x78},\r
+{0x8fd7,0x7f},\r
+{0x8fd8,0xe4},\r
+{0x8fd9,0xf6},\r
+{0x8fda,0xd8},\r
+{0x8fdb,0xfd},\r
+{0x8fdc,0x75},\r
+{0x8fdd,0x81},\r
+{0x8fde,0xcd},\r
+{0x8fdf,0x02},\r
+{0x8fe0,0x0c},\r
+{0x8fe1,0x98},\r
+{0x8fe2,0x8f},\r
+{0x8fe3,0x82},\r
+{0x8fe4,0x8e},\r
+{0x8fe5,0x83},\r
+{0x8fe6,0x75},\r
+{0x8fe7,0xf0},\r
+{0x8fe8,0x04},\r
+{0x8fe9,0xed},\r
+{0x8fea,0x02},\r
+{0x8feb,0x06},\r
+{0x8fec,0xa5},\r
+{0x3022,0x00},\r
+{0x3023,0x00},\r
+{0x3024,0x00},\r
+{0x3025,0x00},\r
+{0x3026,0x00},\r
+{0x3027,0x00},\r
+{0x3028,0x00},\r
+{0x3029,0x7F},\r
+{0x3000,0x00},\r
+#elif 1 // ddl@rock-chips.com : 2012/12/10 Continues Focus from OVT\r
+{0x3000,0x20},\r
+{0x8000,0x02},\r
+{0x8001,0x0f},\r
+{0x8002,0xd6},\r
+{0x8003,0x02},\r
+{0x8004,0x0a},\r
+{0x8005,0x39},\r
+{0x8006,0xc2},\r
+{0x8007,0x01},\r
+{0x8008,0x22},\r
+{0x8009,0x22},\r
+{0x800a,0x00},\r
+{0x800b,0x02},\r
+{0x800c,0x0f},\r
+{0x800d,0xb2},\r
+{0x800e,0xe5},\r
+{0x800f,0x1f},\r
+{0x8010,0x70},\r
+{0x8011,0x72},\r
+{0x8012,0xf5},\r
+{0x8013,0x1e},\r
+{0x8014,0xd2},\r
+{0x8015,0x35},\r
+{0x8016,0xff},\r
+{0x8017,0xef},\r
+{0x8018,0x25},\r
+{0x8019,0xe0},\r
+{0x801a,0x24},\r
+{0x801b,0x4e},\r
+{0x801c,0xf8},\r
+{0x801d,0xe4},\r
+{0x801e,0xf6},\r
+{0x801f,0x08},\r
+{0x8020,0xf6},\r
+{0x8021,0x0f},\r
+{0x8022,0xbf},\r
+{0x8023,0x34},\r
+{0x8024,0xf2},\r
+{0x8025,0x90},\r
+{0x8026,0x0e},\r
+{0x8027,0x93},\r
+{0x8028,0xe4},\r
+{0x8029,0x93},\r
+{0x802a,0xff},\r
+{0x802b,0xe5},\r
+{0x802c,0x4b},\r
+{0x802d,0xc3},\r
+{0x802e,0x9f},\r
+{0x802f,0x50},\r
+{0x8030,0x04},\r
+{0x8031,0x7f},\r
+{0x8032,0x05},\r
+{0x8033,0x80},\r
+{0x8034,0x02},\r
+{0x8035,0x7f},\r
+{0x8036,0xfb},\r
+{0x8037,0x78},\r
+{0x8038,0xbd},\r
+{0x8039,0xa6},\r
+{0x803a,0x07},\r
+{0x803b,0x12},\r
+{0x803c,0x0f},\r
+{0x803d,0x04},\r
+{0x803e,0x40},\r
+{0x803f,0x04},\r
+{0x8040,0x7f},\r
+{0x8041,0x03},\r
+{0x8042,0x80},\r
+{0x8043,0x02},\r
+{0x8044,0x7f},\r
+{0x8045,0x30},\r
+{0x8046,0x78},\r
+{0x8047,0xbc},\r
+{0x8048,0xa6},\r
+{0x8049,0x07},\r
+{0x804a,0xe6},\r
+{0x804b,0x18},\r
+{0x804c,0xf6},\r
+{0x804d,0x08},\r
+{0x804e,0xe6},\r
+{0x804f,0x78},\r
+{0x8050,0xb9},\r
+{0x8051,0xf6},\r
+{0x8052,0x78},\r
+{0x8053,0xbc},\r
+{0x8054,0xe6},\r
+{0x8055,0x78},\r
+{0x8056,0xba},\r
+{0x8057,0xf6},\r
+{0x8058,0x78},\r
+{0x8059,0xbf},\r
+{0x805a,0x76},\r
+{0x805b,0x33},\r
+{0x805c,0xe4},\r
+{0x805d,0x08},\r
+{0x805e,0xf6},\r
+{0x805f,0x78},\r
+{0x8060,0xb8},\r
+{0x8061,0x76},\r
+{0x8062,0x01},\r
+{0x8063,0x75},\r
+{0x8064,0x4a},\r
+{0x8065,0x02},\r
+{0x8066,0x78},\r
+{0x8067,0xb6},\r
+{0x8068,0xf6},\r
+{0x8069,0x08},\r
+{0x806a,0xf6},\r
+{0x806b,0x74},\r
+{0x806c,0xff},\r
+{0x806d,0x78},\r
+{0x806e,0xc1},\r
+{0x806f,0xf6},\r
+{0x8070,0x08},\r
+{0x8071,0xf6},\r
+{0x8072,0x75},\r
+{0x8073,0x1f},\r
+{0x8074,0x01},\r
+{0x8075,0x78},\r
+{0x8076,0xbc},\r
+{0x8077,0xe6},\r
+{0x8078,0x75},\r
+{0x8079,0xf0},\r
+{0x807a,0x05},\r
+{0x807b,0xa4},\r
+{0x807c,0xf5},\r
+{0x807d,0x4b},\r
+{0x807e,0x12},\r
+{0x807f,0x0a},\r
+{0x8080,0xff},\r
+{0x8081,0xc2},\r
+{0x8082,0x37},\r
+{0x8083,0x22},\r
+{0x8084,0x78},\r
+{0x8085,0xb8},\r
+{0x8086,0xe6},\r
+{0x8087,0xd3},\r
+{0x8088,0x94},\r
+{0x8089,0x00},\r
+{0x808a,0x40},\r
+{0x808b,0x02},\r
+{0x808c,0x16},\r
+{0x808d,0x22},\r
+{0x808e,0xe5},\r
+{0x808f,0x1f},\r
+{0x8090,0xb4},\r
+{0x8091,0x05},\r
+{0x8092,0x23},\r
+{0x8093,0xe4},\r
+{0x8094,0xf5},\r
+{0x8095,0x1f},\r
+{0x8096,0xc2},\r
+{0x8097,0x01},\r
+{0x8098,0x78},\r
+{0x8099,0xb6},\r
+{0x809a,0xe6},\r
+{0x809b,0xfe},\r
+{0x809c,0x08},\r
+{0x809d,0xe6},\r
+{0x809e,0xff},\r
+{0x809f,0x78},\r
+{0x80a0,0x4e},\r
+{0x80a1,0xa6},\r
+{0x80a2,0x06},\r
+{0x80a3,0x08},\r
+{0x80a4,0xa6},\r
+{0x80a5,0x07},\r
+{0x80a6,0xa2},\r
+{0x80a7,0x37},\r
+{0x80a8,0xe4},\r
+{0x80a9,0x33},\r
+{0x80aa,0xf5},\r
+{0x80ab,0x3c},\r
+{0x80ac,0x90},\r
+{0x80ad,0x30},\r
+{0x80ae,0x28},\r
+{0x80af,0xf0},\r
+{0x80b0,0x75},\r
+{0x80b1,0x1e},\r
+{0x80b2,0x10},\r
+{0x80b3,0xd2},\r
+{0x80b4,0x35},\r
+{0x80b5,0x22},\r
+{0x80b6,0xe5},\r
+{0x80b7,0x4b},\r
+{0x80b8,0x75},\r
+{0x80b9,0xf0},\r
+{0x80ba,0x05},\r
+{0x80bb,0x84},\r
+{0x80bc,0x78},\r
+{0x80bd,0xbc},\r
+{0x80be,0xf6},\r
+{0x80bf,0x90},\r
+{0x80c0,0x0e},\r
+{0x80c1,0x8c},\r
+{0x80c2,0xe4},\r
+{0x80c3,0x93},\r
+{0x80c4,0xff},\r
+{0x80c5,0x25},\r
+{0x80c6,0xe0},\r
+{0x80c7,0x24},\r
+{0x80c8,0x0a},\r
+{0x80c9,0xf8},\r
+{0x80ca,0xe6},\r
+{0x80cb,0xfc},\r
+{0x80cc,0x08},\r
+{0x80cd,0xe6},\r
+{0x80ce,0xfd},\r
+{0x80cf,0x78},\r
+{0x80d0,0xbc},\r
+{0x80d1,0xe6},\r
+{0x80d2,0x25},\r
+{0x80d3,0xe0},\r
+{0x80d4,0x24},\r
+{0x80d5,0x4e},\r
+{0x80d6,0xf8},\r
+{0x80d7,0xa6},\r
+{0x80d8,0x04},\r
+{0x80d9,0x08},\r
+{0x80da,0xa6},\r
+{0x80db,0x05},\r
+{0x80dc,0xef},\r
+{0x80dd,0x12},\r
+{0x80de,0x0f},\r
+{0x80df,0x0b},\r
+{0x80e0,0xd3},\r
+{0x80e1,0x78},\r
+{0x80e2,0xb7},\r
+{0x80e3,0x96},\r
+{0x80e4,0xee},\r
+{0x80e5,0x18},\r
+{0x80e6,0x96},\r
+{0x80e7,0x40},\r
+{0x80e8,0x0d},\r
+{0x80e9,0x78},\r
+{0x80ea,0xbc},\r
+{0x80eb,0xe6},\r
+{0x80ec,0x78},\r
+{0x80ed,0xb9},\r
+{0x80ee,0xf6},\r
+{0x80ef,0x78},\r
+{0x80f0,0xb6},\r
+{0x80f1,0xa6},\r
+{0x80f2,0x06},\r
+{0x80f3,0x08},\r
+{0x80f4,0xa6},\r
+{0x80f5,0x07},\r
+{0x80f6,0x90},\r
+{0x80f7,0x0e},\r
+{0x80f8,0x8c},\r
+{0x80f9,0xe4},\r
+{0x80fa,0x93},\r
+{0x80fb,0x12},\r
+{0x80fc,0x0f},\r
+{0x80fd,0x0b},\r
+{0x80fe,0xc3},\r
+{0x80ff,0x78},\r
+{0x8100,0xc2},\r
+{0x8101,0x96},\r
+{0x8102,0xee},\r
+{0x8103,0x18},\r
+{0x8104,0x96},\r
+{0x8105,0x50},\r
+{0x8106,0x0d},\r
+{0x8107,0x78},\r
+{0x8108,0xbc},\r
+{0x8109,0xe6},\r
+{0x810a,0x78},\r
+{0x810b,0xba},\r
+{0x810c,0xf6},\r
+{0x810d,0x78},\r
+{0x810e,0xc1},\r
+{0x810f,0xa6},\r
+{0x8110,0x06},\r
+{0x8111,0x08},\r
+{0x8112,0xa6},\r
+{0x8113,0x07},\r
+{0x8114,0x78},\r
+{0x8115,0xb6},\r
+{0x8116,0xe6},\r
+{0x8117,0xfe},\r
+{0x8118,0x08},\r
+{0x8119,0xe6},\r
+{0x811a,0xc3},\r
+{0x811b,0x78},\r
+{0x811c,0xc2},\r
+{0x811d,0x96},\r
+{0x811e,0xff},\r
+{0x811f,0xee},\r
+{0x8120,0x18},\r
+{0x8121,0x96},\r
+{0x8122,0x78},\r
+{0x8123,0xc3},\r
+{0x8124,0xf6},\r
+{0x8125,0x08},\r
+{0x8126,0xa6},\r
+{0x8127,0x07},\r
+{0x8128,0x90},\r
+{0x8129,0x0e},\r
+{0x812a,0x95},\r
+{0x812b,0xe4},\r
+{0x812c,0x18},\r
+{0x812d,0x12},\r
+{0x812e,0x0e},\r
+{0x812f,0xe9},\r
+{0x8130,0x40},\r
+{0x8131,0x02},\r
+{0x8132,0xd2},\r
+{0x8133,0x37},\r
+{0x8134,0x78},\r
+{0x8135,0xbc},\r
+{0x8136,0xe6},\r
+{0x8137,0x08},\r
+{0x8138,0x26},\r
+{0x8139,0x08},\r
+{0x813a,0xf6},\r
+{0x813b,0xe5},\r
+{0x813c,0x1f},\r
+{0x813d,0x64},\r
+{0x813e,0x01},\r
+{0x813f,0x70},\r
+{0x8140,0x4a},\r
+{0x8141,0xe6},\r
+{0x8142,0xc3},\r
+{0x8143,0x78},\r
+{0x8144,0xc0},\r
+{0x8145,0x12},\r
+{0x8146,0x0e},\r
+{0x8147,0xdf},\r
+{0x8148,0x40},\r
+{0x8149,0x05},\r
+{0x814a,0x12},\r
+{0x814b,0x0e},\r
+{0x814c,0xda},\r
+{0x814d,0x40},\r
+{0x814e,0x39},\r
+{0x814f,0x12},\r
+{0x8150,0x0f},\r
+{0x8151,0x02},\r
+{0x8152,0x40},\r
+{0x8153,0x04},\r
+{0x8154,0x7f},\r
+{0x8155,0xfe},\r
+{0x8156,0x80},\r
+{0x8157,0x02},\r
+{0x8158,0x7f},\r
+{0x8159,0x02},\r
+{0x815a,0x78},\r
+{0x815b,0xbd},\r
+{0x815c,0xa6},\r
+{0x815d,0x07},\r
+{0x815e,0x78},\r
+{0x815f,0xb9},\r
+{0x8160,0xe6},\r
+{0x8161,0x24},\r
+{0x8162,0x03},\r
+{0x8163,0x78},\r
+{0x8164,0xbf},\r
+{0x8165,0xf6},\r
+{0x8166,0x78},\r
+{0x8167,0xb9},\r
+{0x8168,0xe6},\r
+{0x8169,0x24},\r
+{0x816a,0xfd},\r
+{0x816b,0x78},\r
+{0x816c,0xc0},\r
+{0x816d,0xf6},\r
+{0x816e,0x12},\r
+{0x816f,0x0f},\r
+{0x8170,0x02},\r
+{0x8171,0x40},\r
+{0x8172,0x06},\r
+{0x8173,0x78},\r
+{0x8174,0xc0},\r
+{0x8175,0xe6},\r
+{0x8176,0xff},\r
+{0x8177,0x80},\r
+{0x8178,0x04},\r
+{0x8179,0x78},\r
+{0x817a,0xbf},\r
+{0x817b,0xe6},\r
+{0x817c,0xff},\r
+{0x817d,0x78},\r
+{0x817e,0xbe},\r
+{0x817f,0xa6},\r
+{0x8180,0x07},\r
+{0x8181,0x75},\r
+{0x8182,0x1f},\r
+{0x8183,0x02},\r
+{0x8184,0x78},\r
+{0x8185,0xb8},\r
+{0x8186,0x76},\r
+{0x8187,0x01},\r
+{0x8188,0x02},\r
+{0x8189,0x02},\r
+{0x818a,0x4a},\r
+{0x818b,0xe5},\r
+{0x818c,0x1f},\r
+{0x818d,0x64},\r
+{0x818e,0x02},\r
+{0x818f,0x60},\r
+{0x8190,0x03},\r
+{0x8191,0x02},\r
+{0x8192,0x02},\r
+{0x8193,0x2a},\r
+{0x8194,0x78},\r
+{0x8195,0xbe},\r
+{0x8196,0xe6},\r
+{0x8197,0xff},\r
+{0x8198,0xc3},\r
+{0x8199,0x78},\r
+{0x819a,0xc0},\r
+{0x819b,0x12},\r
+{0x819c,0x0e},\r
+{0x819d,0xe0},\r
+{0x819e,0x40},\r
+{0x819f,0x08},\r
+{0x81a0,0x12},\r
+{0x81a1,0x0e},\r
+{0x81a2,0xda},\r
+{0x81a3,0x50},\r
+{0x81a4,0x03},\r
+{0x81a5,0x02},\r
+{0x81a6,0x02},\r
+{0x81a7,0x28},\r
+{0x81a8,0x12},\r
+{0x81a9,0x0f},\r
+{0x81aa,0x02},\r
+{0x81ab,0x40},\r
+{0x81ac,0x04},\r
+{0x81ad,0x7f},\r
+{0x81ae,0xff},\r
+{0x81af,0x80},\r
+{0x81b0,0x02},\r
+{0x81b1,0x7f},\r
+{0x81b2,0x01},\r
+{0x81b3,0x78},\r
+{0x81b4,0xbd},\r
+{0x81b5,0xa6},\r
+{0x81b6,0x07},\r
+{0x81b7,0x78},\r
+{0x81b8,0xb9},\r
+{0x81b9,0xe6},\r
+{0x81ba,0x04},\r
+{0x81bb,0x78},\r
+{0x81bc,0xbf},\r
+{0x81bd,0xf6},\r
+{0x81be,0x78},\r
+{0x81bf,0xb9},\r
+{0x81c0,0xe6},\r
+{0x81c1,0x14},\r
+{0x81c2,0x78},\r
+{0x81c3,0xc0},\r
+{0x81c4,0xf6},\r
+{0x81c5,0x18},\r
+{0x81c6,0x12},\r
+{0x81c7,0x0f},\r
+{0x81c8,0x04},\r
+{0x81c9,0x40},\r
+{0x81ca,0x04},\r
+{0x81cb,0xe6},\r
+{0x81cc,0xff},\r
+{0x81cd,0x80},\r
+{0x81ce,0x02},\r
+{0x81cf,0x7f},\r
+{0x81d0,0x00},\r
+{0x81d1,0x78},\r
+{0x81d2,0xbf},\r
+{0x81d3,0xa6},\r
+{0x81d4,0x07},\r
+{0x81d5,0xd3},\r
+{0x81d6,0x08},\r
+{0x81d7,0xe6},\r
+{0x81d8,0x64},\r
+{0x81d9,0x80},\r
+{0x81da,0x94},\r
+{0x81db,0x80},\r
+{0x81dc,0x40},\r
+{0x81dd,0x04},\r
+{0x81de,0xe6},\r
+{0x81df,0xff},\r
+{0x81e0,0x80},\r
+{0x81e1,0x02},\r
+{0x81e2,0x7f},\r
+{0x81e3,0x00},\r
+{0x81e4,0x78},\r
+{0x81e5,0xc0},\r
+{0x81e6,0xa6},\r
+{0x81e7,0x07},\r
+{0x81e8,0xc3},\r
+{0x81e9,0x18},\r
+{0x81ea,0xe6},\r
+{0x81eb,0x64},\r
+{0x81ec,0x80},\r
+{0x81ed,0x94},\r
+{0x81ee,0xb3},\r
+{0x81ef,0x50},\r
+{0x81f0,0x04},\r
+{0x81f1,0xe6},\r
+{0x81f2,0xff},\r
+{0x81f3,0x80},\r
+{0x81f4,0x02},\r
+{0x81f5,0x7f},\r
+{0x81f6,0x33},\r
+{0x81f7,0x78},\r
+{0x81f8,0xbf},\r
+{0x81f9,0xa6},\r
+{0x81fa,0x07},\r
+{0x81fb,0xc3},\r
+{0x81fc,0x08},\r
+{0x81fd,0xe6},\r
+{0x81fe,0x64},\r
+{0x81ff,0x80},\r
+{0x8200,0x94},\r
+{0x8201,0xb3},\r
+{0x8202,0x50},\r
+{0x8203,0x04},\r
+{0x8204,0xe6},\r
+{0x8205,0xff},\r
+{0x8206,0x80},\r
+{0x8207,0x02},\r
+{0x8208,0x7f},\r
+{0x8209,0x33},\r
+{0x820a,0x78},\r
+{0x820b,0xc0},\r
+{0x820c,0xa6},\r
+{0x820d,0x07},\r
+{0x820e,0x12},\r
+{0x820f,0x0f},\r
+{0x8210,0x02},\r
+{0x8211,0x40},\r
+{0x8212,0x06},\r
+{0x8213,0x78},\r
+{0x8214,0xc0},\r
+{0x8215,0xe6},\r
+{0x8216,0xff},\r
+{0x8217,0x80},\r
+{0x8218,0x04},\r
+{0x8219,0x78},\r
+{0x821a,0xbf},\r
+{0x821b,0xe6},\r
+{0x821c,0xff},\r
+{0x821d,0x78},\r
+{0x821e,0xbe},\r
+{0x821f,0xa6},\r
+{0x8220,0x07},\r
+{0x8221,0x75},\r
+{0x8222,0x1f},\r
+{0x8223,0x03},\r
+{0x8224,0x78},\r
+{0x8225,0xb8},\r
+{0x8226,0x76},\r
+{0x8227,0x01},\r
+{0x8228,0x80},\r
+{0x8229,0x20},\r
+{0x822a,0xe5},\r
+{0x822b,0x1f},\r
+{0x822c,0x64},\r
+{0x822d,0x03},\r
+{0x822e,0x70},\r
+{0x822f,0x26},\r
+{0x8230,0x78},\r
+{0x8231,0xbe},\r
+{0x8232,0xe6},\r
+{0x8233,0xff},\r
+{0x8234,0xc3},\r
+{0x8235,0x78},\r
+{0x8236,0xc0},\r
+{0x8237,0x12},\r
+{0x8238,0x0e},\r
+{0x8239,0xe0},\r
+{0x823a,0x40},\r
+{0x823b,0x05},\r
+{0x823c,0x12},\r
+{0x823d,0x0e},\r
+{0x823e,0xda},\r
+{0x823f,0x40},\r
+{0x8240,0x09},\r
+{0x8241,0x78},\r
+{0x8242,0xb9},\r
+{0x8243,0xe6},\r
+{0x8244,0x78},\r
+{0x8245,0xbe},\r
+{0x8246,0xf6},\r
+{0x8247,0x75},\r
+{0x8248,0x1f},\r
+{0x8249,0x04},\r
+{0x824a,0x78},\r
+{0x824b,0xbe},\r
+{0x824c,0xe6},\r
+{0x824d,0x75},\r
+{0x824e,0xf0},\r
+{0x824f,0x05},\r
+{0x8250,0xa4},\r
+{0x8251,0xf5},\r
+{0x8252,0x4b},\r
+{0x8253,0x02},\r
+{0x8254,0x0a},\r
+{0x8255,0xff},\r
+{0x8256,0xe5},\r
+{0x8257,0x1f},\r
+{0x8258,0xb4},\r
+{0x8259,0x04},\r
+{0x825a,0x10},\r
+{0x825b,0x90},\r
+{0x825c,0x0e},\r
+{0x825d,0x94},\r
+{0x825e,0xe4},\r
+{0x825f,0x78},\r
+{0x8260,0xc3},\r
+{0x8261,0x12},\r
+{0x8262,0x0e},\r
+{0x8263,0xe9},\r
+{0x8264,0x40},\r
+{0x8265,0x02},\r
+{0x8266,0xd2},\r
+{0x8267,0x37},\r
+{0x8268,0x75},\r
+{0x8269,0x1f},\r
+{0x826a,0x05},\r
+{0x826b,0x22},\r
+{0x826c,0x30},\r
+{0x826d,0x01},\r
+{0x826e,0x03},\r
+{0x826f,0x02},\r
+{0x8270,0x04},\r
+{0x8271,0xc0},\r
+{0x8272,0x30},\r
+{0x8273,0x02},\r
+{0x8274,0x03},\r
+{0x8275,0x02},\r
+{0x8276,0x04},\r
+{0x8277,0xc0},\r
+{0x8278,0x90},\r
+{0x8279,0x51},\r
+{0x827a,0xa5},\r
+{0x827b,0xe0},\r
+{0x827c,0x78},\r
+{0x827d,0x93},\r
+{0x827e,0xf6},\r
+{0x827f,0xa3},\r
+{0x8280,0xe0},\r
+{0x8281,0x08},\r
+{0x8282,0xf6},\r
+{0x8283,0xa3},\r
+{0x8284,0xe0},\r
+{0x8285,0x08},\r
+{0x8286,0xf6},\r
+{0x8287,0xe5},\r
+{0x8288,0x1f},\r
+{0x8289,0x70},\r
+{0x828a,0x3c},\r
+{0x828b,0x75},\r
+{0x828c,0x1e},\r
+{0x828d,0x20},\r
+{0x828e,0xd2},\r
+{0x828f,0x35},\r
+{0x8290,0x12},\r
+{0x8291,0x0c},\r
+{0x8292,0x7a},\r
+{0x8293,0x78},\r
+{0x8294,0x7e},\r
+{0x8295,0xa6},\r
+{0x8296,0x06},\r
+{0x8297,0x08},\r
+{0x8298,0xa6},\r
+{0x8299,0x07},\r
+{0x829a,0x78},\r
+{0x829b,0x8b},\r
+{0x829c,0xa6},\r
+{0x829d,0x09},\r
+{0x829e,0x18},\r
+{0x829f,0x76},\r
+{0x82a0,0x01},\r
+{0x82a1,0x12},\r
+{0x82a2,0x0c},\r
+{0x82a3,0x5b},\r
+{0x82a4,0x78},\r
+{0x82a5,0x4e},\r
+{0x82a6,0xa6},\r
+{0x82a7,0x06},\r
+{0x82a8,0x08},\r
+{0x82a9,0xa6},\r
+{0x82aa,0x07},\r
+{0x82ab,0x78},\r
+{0x82ac,0x8b},\r
+{0x82ad,0xe6},\r
+{0x82ae,0x78},\r
+{0x82af,0x6e},\r
+{0x82b0,0xf6},\r
+{0x82b1,0x75},\r
+{0x82b2,0x1f},\r
+{0x82b3,0x01},\r
+{0x82b4,0x78},\r
+{0x82b5,0x93},\r
+{0x82b6,0xe6},\r
+{0x82b7,0x78},\r
+{0x82b8,0x90},\r
+{0x82b9,0xf6},\r
+{0x82ba,0x78},\r
+{0x82bb,0x94},\r
+{0x82bc,0xe6},\r
+{0x82bd,0x78},\r
+{0x82be,0x91},\r
+{0x82bf,0xf6},\r
+{0x82c0,0x78},\r
+{0x82c1,0x95},\r
+{0x82c2,0xe6},\r
+{0x82c3,0x78},\r
+{0x82c4,0x92},\r
+{0x82c5,0xf6},\r
+{0x82c6,0x22},\r
+{0x82c7,0x79},\r
+{0x82c8,0x90},\r
+{0x82c9,0xe7},\r
+{0x82ca,0xd3},\r
+{0x82cb,0x78},\r
+{0x82cc,0x93},\r
+{0x82cd,0x96},\r
+{0x82ce,0x40},\r
+{0x82cf,0x05},\r
+{0x82d0,0xe7},\r
+{0x82d1,0x96},\r
+{0x82d2,0xff},\r
+{0x82d3,0x80},\r
+{0x82d4,0x08},\r
+{0x82d5,0xc3},\r
+{0x82d6,0x79},\r
+{0x82d7,0x93},\r
+{0x82d8,0xe7},\r
+{0x82d9,0x78},\r
+{0x82da,0x90},\r
+{0x82db,0x96},\r
+{0x82dc,0xff},\r
+{0x82dd,0x78},\r
+{0x82de,0x88},\r
+{0x82df,0x76},\r
+{0x82e0,0x00},\r
+{0x82e1,0x08},\r
+{0x82e2,0xa6},\r
+{0x82e3,0x07},\r
+{0x82e4,0x79},\r
+{0x82e5,0x91},\r
+{0x82e6,0xe7},\r
+{0x82e7,0xd3},\r
+{0x82e8,0x78},\r
+{0x82e9,0x94},\r
+{0x82ea,0x96},\r
+{0x82eb,0x40},\r
+{0x82ec,0x05},\r
+{0x82ed,0xe7},\r
+{0x82ee,0x96},\r
+{0x82ef,0xff},\r
+{0x82f0,0x80},\r
+{0x82f1,0x08},\r
+{0x82f2,0xc3},\r
+{0x82f3,0x79},\r
+{0x82f4,0x94},\r
+{0x82f5,0xe7},\r
+{0x82f6,0x78},\r
+{0x82f7,0x91},\r
+{0x82f8,0x96},\r
+{0x82f9,0xff},\r
+{0x82fa,0x12},\r
+{0x82fb,0x0c},\r
+{0x82fc,0x8e},\r
+{0x82fd,0x79},\r
+{0x82fe,0x92},\r
+{0x82ff,0xe7},\r
+{0x8300,0xd3},\r
+{0x8301,0x78},\r
+{0x8302,0x95},\r
+{0x8303,0x96},\r
+{0x8304,0x40},\r
+{0x8305,0x05},\r
+{0x8306,0xe7},\r
+{0x8307,0x96},\r
+{0x8308,0xff},\r
+{0x8309,0x80},\r
+{0x830a,0x08},\r
+{0x830b,0xc3},\r
+{0x830c,0x79},\r
+{0x830d,0x95},\r
+{0x830e,0xe7},\r
+{0x830f,0x78},\r
+{0x8310,0x92},\r
+{0x8311,0x96},\r
+{0x8312,0xff},\r
+{0x8313,0x12},\r
+{0x8314,0x0c},\r
+{0x8315,0x8e},\r
+{0x8316,0x12},\r
+{0x8317,0x0c},\r
+{0x8318,0x5b},\r
+{0x8319,0x78},\r
+{0x831a,0x8a},\r
+{0x831b,0xe6},\r
+{0x831c,0x25},\r
+{0x831d,0xe0},\r
+{0x831e,0x24},\r
+{0x831f,0x4e},\r
+{0x8320,0xf8},\r
+{0x8321,0xa6},\r
+{0x8322,0x06},\r
+{0x8323,0x08},\r
+{0x8324,0xa6},\r
+{0x8325,0x07},\r
+{0x8326,0x78},\r
+{0x8327,0x8a},\r
+{0x8328,0xe6},\r
+{0x8329,0x24},\r
+{0x832a,0x6e},\r
+{0x832b,0xf8},\r
+{0x832c,0xa6},\r
+{0x832d,0x09},\r
+{0x832e,0x78},\r
+{0x832f,0x8a},\r
+{0x8330,0xe6},\r
+{0x8331,0x24},\r
+{0x8332,0x01},\r
+{0x8333,0xff},\r
+{0x8334,0xe4},\r
+{0x8335,0x33},\r
+{0x8336,0xfe},\r
+{0x8337,0xd3},\r
+{0x8338,0xef},\r
+{0x8339,0x94},\r
+{0x833a,0x0f},\r
+{0x833b,0xee},\r
+{0x833c,0x64},\r
+{0x833d,0x80},\r
+{0x833e,0x94},\r
+{0x833f,0x80},\r
+{0x8340,0x40},\r
+{0x8341,0x04},\r
+{0x8342,0x7f},\r
+{0x8343,0x00},\r
+{0x8344,0x80},\r
+{0x8345,0x05},\r
+{0x8346,0x78},\r
+{0x8347,0x8a},\r
+{0x8348,0xe6},\r
+{0x8349,0x04},\r
+{0x834a,0xff},\r
+{0x834b,0x78},\r
+{0x834c,0x8a},\r
+{0x834d,0xa6},\r
+{0x834e,0x07},\r
+{0x834f,0xe5},\r
+{0x8350,0x1f},\r
+{0x8351,0xb4},\r
+{0x8352,0x01},\r
+{0x8353,0x0a},\r
+{0x8354,0xe6},\r
+{0x8355,0x60},\r
+{0x8356,0x03},\r
+{0x8357,0x02},\r
+{0x8358,0x04},\r
+{0x8359,0xc0},\r
+{0x835a,0x75},\r
+{0x835b,0x1f},\r
+{0x835c,0x02},\r
+{0x835d,0x22},\r
+{0x835e,0x12},\r
+{0x835f,0x0c},\r
+{0x8360,0x7a},\r
+{0x8361,0x78},\r
+{0x8362,0x80},\r
+{0x8363,0xa6},\r
+{0x8364,0x06},\r
+{0x8365,0x08},\r
+{0x8366,0xa6},\r
+{0x8367,0x07},\r
+{0x8368,0x12},\r
+{0x8369,0x0c},\r
+{0x836a,0x7a},\r
+{0x836b,0x78},\r
+{0x836c,0x82},\r
+{0x836d,0xa6},\r
+{0x836e,0x06},\r
+{0x836f,0x08},\r
+{0x8370,0xa6},\r
+{0x8371,0x07},\r
+{0x8372,0x78},\r
+{0x8373,0x6e},\r
+{0x8374,0xe6},\r
+{0x8375,0x78},\r
+{0x8376,0x8c},\r
+{0x8377,0xf6},\r
+{0x8378,0x78},\r
+{0x8379,0x6e},\r
+{0x837a,0xe6},\r
+{0x837b,0x78},\r
+{0x837c,0x8d},\r
+{0x837d,0xf6},\r
+{0x837e,0x7f},\r
+{0x837f,0x01},\r
+{0x8380,0xef},\r
+{0x8381,0x25},\r
+{0x8382,0xe0},\r
+{0x8383,0x24},\r
+{0x8384,0x4f},\r
+{0x8385,0xf9},\r
+{0x8386,0xc3},\r
+{0x8387,0x78},\r
+{0x8388,0x81},\r
+{0x8389,0xe6},\r
+{0x838a,0x97},\r
+{0x838b,0x18},\r
+{0x838c,0xe6},\r
+{0x838d,0x19},\r
+{0x838e,0x97},\r
+{0x838f,0x50},\r
+{0x8390,0x0a},\r
+{0x8391,0x12},\r
+{0x8392,0x0c},\r
+{0x8393,0x82},\r
+{0x8394,0x78},\r
+{0x8395,0x80},\r
+{0x8396,0xa6},\r
+{0x8397,0x04},\r
+{0x8398,0x08},\r
+{0x8399,0xa6},\r
+{0x839a,0x05},\r
+{0x839b,0x74},\r
+{0x839c,0x6e},\r
+{0x839d,0x2f},\r
+{0x839e,0xf9},\r
+{0x839f,0x78},\r
+{0x83a0,0x8c},\r
+{0x83a1,0xe6},\r
+{0x83a2,0xc3},\r
+{0x83a3,0x97},\r
+{0x83a4,0x50},\r
+{0x83a5,0x08},\r
+{0x83a6,0x74},\r
+{0x83a7,0x6e},\r
+{0x83a8,0x2f},\r
+{0x83a9,0xf8},\r
+{0x83aa,0xe6},\r
+{0x83ab,0x78},\r
+{0x83ac,0x8c},\r
+{0x83ad,0xf6},\r
+{0x83ae,0xef},\r
+{0x83af,0x25},\r
+{0x83b0,0xe0},\r
+{0x83b1,0x24},\r
+{0x83b2,0x4f},\r
+{0x83b3,0xf9},\r
+{0x83b4,0xd3},\r
+{0x83b5,0x78},\r
+{0x83b6,0x83},\r
+{0x83b7,0xe6},\r
+{0x83b8,0x97},\r
+{0x83b9,0x18},\r
+{0x83ba,0xe6},\r
+{0x83bb,0x19},\r
+{0x83bc,0x97},\r
+{0x83bd,0x40},\r
+{0x83be,0x0a},\r
+{0x83bf,0x12},\r
+{0x83c0,0x0c},\r
+{0x83c1,0x82},\r
+{0x83c2,0x78},\r
+{0x83c3,0x82},\r
+{0x83c4,0xa6},\r
+{0x83c5,0x04},\r
+{0x83c6,0x08},\r
+{0x83c7,0xa6},\r
+{0x83c8,0x05},\r
+{0x83c9,0x74},\r
+{0x83ca,0x6e},\r
+{0x83cb,0x2f},\r
+{0x83cc,0xf9},\r
+{0x83cd,0x78},\r
+{0x83ce,0x8d},\r
+{0x83cf,0xe6},\r
+{0x83d0,0xd3},\r
+{0x83d1,0x97},\r
+{0x83d2,0x40},\r
+{0x83d3,0x08},\r
+{0x83d4,0x74},\r
+{0x83d5,0x6e},\r
+{0x83d6,0x2f},\r
+{0x83d7,0xf8},\r
+{0x83d8,0xe6},\r
+{0x83d9,0x78},\r
+{0x83da,0x8d},\r
+{0x83db,0xf6},\r
+{0x83dc,0x0f},\r
+{0x83dd,0xef},\r
+{0x83de,0x64},\r
+{0x83df,0x10},\r
+{0x83e0,0x70},\r
+{0x83e1,0x9e},\r
+{0x83e2,0xc3},\r
+{0x83e3,0x79},\r
+{0x83e4,0x81},\r
+{0x83e5,0xe7},\r
+{0x83e6,0x78},\r
+{0x83e7,0x83},\r
+{0x83e8,0x96},\r
+{0x83e9,0xff},\r
+{0x83ea,0x19},\r
+{0x83eb,0xe7},\r
+{0x83ec,0x18},\r
+{0x83ed,0x96},\r
+{0x83ee,0x78},\r
+{0x83ef,0x84},\r
+{0x83f0,0xf6},\r
+{0x83f1,0x08},\r
+{0x83f2,0xa6},\r
+{0x83f3,0x07},\r
+{0x83f4,0xc3},\r
+{0x83f5,0x79},\r
+{0x83f6,0x8c},\r
+{0x83f7,0xe7},\r
+{0x83f8,0x78},\r
+{0x83f9,0x8d},\r
+{0x83fa,0x96},\r
+{0x83fb,0x08},\r
+{0x83fc,0xf6},\r
+{0x83fd,0xd3},\r
+{0x83fe,0x79},\r
+{0x83ff,0x81},\r
+{0x8400,0xe7},\r
+{0x8401,0x78},\r
+{0x8402,0x7f},\r
+{0x8403,0x96},\r
+{0x8404,0x19},\r
+{0x8405,0xe7},\r
+{0x8406,0x18},\r
+{0x8407,0x96},\r
+{0x8408,0x40},\r
+{0x8409,0x05},\r
+{0x840a,0x09},\r
+{0x840b,0xe7},\r
+{0x840c,0x08},\r
+{0x840d,0x80},\r
+{0x840e,0x06},\r
+{0x840f,0xc3},\r
+{0x8410,0x79},\r
+{0x8411,0x7f},\r
+{0x8412,0xe7},\r
+{0x8413,0x78},\r
+{0x8414,0x81},\r
+{0x8415,0x96},\r
+{0x8416,0xff},\r
+{0x8417,0x19},\r
+{0x8418,0xe7},\r
+{0x8419,0x18},\r
+{0x841a,0x96},\r
+{0x841b,0xfe},\r
+{0x841c,0x78},\r
+{0x841d,0x86},\r
+{0x841e,0xa6},\r
+{0x841f,0x06},\r
+{0x8420,0x08},\r
+{0x8421,0xa6},\r
+{0x8422,0x07},\r
+{0x8423,0x79},\r
+{0x8424,0x8c},\r
+{0x8425,0xe7},\r
+{0x8426,0xd3},\r
+{0x8427,0x78},\r
+{0x8428,0x8b},\r
+{0x8429,0x96},\r
+{0x842a,0x40},\r
+{0x842b,0x05},\r
+{0x842c,0xe7},\r
+{0x842d,0x96},\r
+{0x842e,0xff},\r
+{0x842f,0x80},\r
+{0x8430,0x08},\r
+{0x8431,0xc3},\r
+{0x8432,0x79},\r
+{0x8433,0x8b},\r
+{0x8434,0xe7},\r
+{0x8435,0x78},\r
+{0x8436,0x8c},\r
+{0x8437,0x96},\r
+{0x8438,0xff},\r
+{0x8439,0x78},\r
+{0x843a,0x8f},\r
+{0x843b,0xa6},\r
+{0x843c,0x07},\r
+{0x843d,0xe5},\r
+{0x843e,0x1f},\r
+{0x843f,0x64},\r
+{0x8440,0x02},\r
+{0x8441,0x70},\r
+{0x8442,0x69},\r
+{0x8443,0x90},\r
+{0x8444,0x0e},\r
+{0x8445,0x91},\r
+{0x8446,0x93},\r
+{0x8447,0xff},\r
+{0x8448,0x18},\r
+{0x8449,0xe6},\r
+{0x844a,0xc3},\r
+{0x844b,0x9f},\r
+{0x844c,0x50},\r
+{0x844d,0x72},\r
+{0x844e,0x12},\r
+{0x844f,0x0c},\r
+{0x8450,0x4a},\r
+{0x8451,0x12},\r
+{0x8452,0x0c},\r
+{0x8453,0x2f},\r
+{0x8454,0x90},\r
+{0x8455,0x0e},\r
+{0x8456,0x8e},\r
+{0x8457,0x12},\r
+{0x8458,0x0c},\r
+{0x8459,0x38},\r
+{0x845a,0x78},\r
+{0x845b,0x80},\r
+{0x845c,0x12},\r
+{0x845d,0x0c},\r
+{0x845e,0x6b},\r
+{0x845f,0x7b},\r
+{0x8460,0x04},\r
+{0x8461,0x12},\r
+{0x8462,0x0c},\r
+{0x8463,0x1d},\r
+{0x8464,0xc3},\r
+{0x8465,0x12},\r
+{0x8466,0x06},\r
+{0x8467,0x45},\r
+{0x8468,0x50},\r
+{0x8469,0x56},\r
+{0x846a,0x90},\r
+{0x846b,0x0e},\r
+{0x846c,0x92},\r
+{0x846d,0xe4},\r
+{0x846e,0x93},\r
+{0x846f,0xff},\r
+{0x8470,0x78},\r
+{0x8471,0x8f},\r
+{0x8472,0xe6},\r
+{0x8473,0x9f},\r
+{0x8474,0x40},\r
+{0x8475,0x02},\r
+{0x8476,0x80},\r
+{0x8477,0x11},\r
+{0x8478,0x90},\r
+{0x8479,0x0e},\r
+{0x847a,0x90},\r
+{0x847b,0xe4},\r
+{0x847c,0x93},\r
+{0x847d,0xff},\r
+{0x847e,0xd3},\r
+{0x847f,0x78},\r
+{0x8480,0x89},\r
+{0x8481,0xe6},\r
+{0x8482,0x9f},\r
+{0x8483,0x18},\r
+{0x8484,0xe6},\r
+{0x8485,0x94},\r
+{0x8486,0x00},\r
+{0x8487,0x40},\r
+{0x8488,0x03},\r
+{0x8489,0x75},\r
+{0x848a,0x1f},\r
+{0x848b,0x05},\r
+{0x848c,0x12},\r
+{0x848d,0x0c},\r
+{0x848e,0x4a},\r
+{0x848f,0x12},\r
+{0x8490,0x0c},\r
+{0x8491,0x2f},\r
+{0x8492,0x90},\r
+{0x8493,0x0e},\r
+{0x8494,0x8f},\r
+{0x8495,0x12},\r
+{0x8496,0x0c},\r
+{0x8497,0x38},\r
+{0x8498,0x78},\r
+{0x8499,0x7e},\r
+{0x849a,0x12},\r
+{0x849b,0x0c},\r
+{0x849c,0x6b},\r
+{0x849d,0x7b},\r
+{0x849e,0x40},\r
+{0x849f,0x12},\r
+{0x84a0,0x0c},\r
+{0x84a1,0x1d},\r
+{0x84a2,0xd3},\r
+{0x84a3,0x12},\r
+{0x84a4,0x06},\r
+{0x84a5,0x45},\r
+{0x84a6,0x40},\r
+{0x84a7,0x18},\r
+{0x84a8,0x75},\r
+{0x84a9,0x1f},\r
+{0x84aa,0x05},\r
+{0x84ab,0x22},\r
+{0x84ac,0xe5},\r
+{0x84ad,0x1f},\r
+{0x84ae,0xb4},\r
+{0x84af,0x05},\r
+{0x84b0,0x0f},\r
+{0x84b1,0xd2},\r
+{0x84b2,0x01},\r
+{0x84b3,0xc2},\r
+{0x84b4,0x02},\r
+{0x84b5,0xe4},\r
+{0x84b6,0xf5},\r
+{0x84b7,0x1f},\r
+{0x84b8,0xf5},\r
+{0x84b9,0x1e},\r
+{0x84ba,0xd2},\r
+{0x84bb,0x35},\r
+{0x84bc,0xd2},\r
+{0x84bd,0x33},\r
+{0x84be,0xd2},\r
+{0x84bf,0x36},\r
+{0x84c0,0x22},\r
+{0x84c1,0xef},\r
+{0x84c2,0x8d},\r
+{0x84c3,0xf0},\r
+{0x84c4,0xa4},\r
+{0x84c5,0xa8},\r
+{0x84c6,0xf0},\r
+{0x84c7,0xcf},\r
+{0x84c8,0x8c},\r
+{0x84c9,0xf0},\r
+{0x84ca,0xa4},\r
+{0x84cb,0x28},\r
+{0x84cc,0xce},\r
+{0x84cd,0x8d},\r
+{0x84ce,0xf0},\r
+{0x84cf,0xa4},\r
+{0x84d0,0x2e},\r
+{0x84d1,0xfe},\r
+{0x84d2,0x22},\r
+{0x84d3,0xbc},\r
+{0x84d4,0x00},\r
+{0x84d5,0x0b},\r
+{0x84d6,0xbe},\r
+{0x84d7,0x00},\r
+{0x84d8,0x29},\r
+{0x84d9,0xef},\r
+{0x84da,0x8d},\r
+{0x84db,0xf0},\r
+{0x84dc,0x84},\r
+{0x84dd,0xff},\r
+{0x84de,0xad},\r
+{0x84df,0xf0},\r
+{0x84e0,0x22},\r
+{0x84e1,0xe4},\r
+{0x84e2,0xcc},\r
+{0x84e3,0xf8},\r
+{0x84e4,0x75},\r
+{0x84e5,0xf0},\r
+{0x84e6,0x08},\r
+{0x84e7,0xef},\r
+{0x84e8,0x2f},\r
+{0x84e9,0xff},\r
+{0x84ea,0xee},\r
+{0x84eb,0x33},\r
+{0x84ec,0xfe},\r
+{0x84ed,0xec},\r
+{0x84ee,0x33},\r
+{0x84ef,0xfc},\r
+{0x84f0,0xee},\r
+{0x84f1,0x9d},\r
+{0x84f2,0xec},\r
+{0x84f3,0x98},\r
+{0x84f4,0x40},\r
+{0x84f5,0x05},\r
+{0x84f6,0xfc},\r
+{0x84f7,0xee},\r
+{0x84f8,0x9d},\r
+{0x84f9,0xfe},\r
+{0x84fa,0x0f},\r
+{0x84fb,0xd5},\r
+{0x84fc,0xf0},\r
+{0x84fd,0xe9},\r
+{0x84fe,0xe4},\r
+{0x84ff,0xce},\r
+{0x8500,0xfd},\r
+{0x8501,0x22},\r
+{0x8502,0xed},\r
+{0x8503,0xf8},\r
+{0x8504,0xf5},\r
+{0x8505,0xf0},\r
+{0x8506,0xee},\r
+{0x8507,0x84},\r
+{0x8508,0x20},\r
+{0x8509,0xd2},\r
+{0x850a,0x1c},\r
+{0x850b,0xfe},\r
+{0x850c,0xad},\r
+{0x850d,0xf0},\r
+{0x850e,0x75},\r
+{0x850f,0xf0},\r
+{0x8510,0x08},\r
+{0x8511,0xef},\r
+{0x8512,0x2f},\r
+{0x8513,0xff},\r
+{0x8514,0xed},\r
+{0x8515,0x33},\r
+{0x8516,0xfd},\r
+{0x8517,0x40},\r
+{0x8518,0x07},\r
+{0x8519,0x98},\r
+{0x851a,0x50},\r
+{0x851b,0x06},\r
+{0x851c,0xd5},\r
+{0x851d,0xf0},\r
+{0x851e,0xf2},\r
+{0x851f,0x22},\r
+{0x8520,0xc3},\r
+{0x8521,0x98},\r
+{0x8522,0xfd},\r
+{0x8523,0x0f},\r
+{0x8524,0xd5},\r
+{0x8525,0xf0},\r
+{0x8526,0xea},\r
+{0x8527,0x22},\r
+{0x8528,0xe8},\r
+{0x8529,0x8f},\r
+{0x852a,0xf0},\r
+{0x852b,0xa4},\r
+{0x852c,0xcc},\r
+{0x852d,0x8b},\r
+{0x852e,0xf0},\r
+{0x852f,0xa4},\r
+{0x8530,0x2c},\r
+{0x8531,0xfc},\r
+{0x8532,0xe9},\r
+{0x8533,0x8e},\r
+{0x8534,0xf0},\r
+{0x8535,0xa4},\r
+{0x8536,0x2c},\r
+{0x8537,0xfc},\r
+{0x8538,0x8a},\r
+{0x8539,0xf0},\r
+{0x853a,0xed},\r
+{0x853b,0xa4},\r
+{0x853c,0x2c},\r
+{0x853d,0xfc},\r
+{0x853e,0xea},\r
+{0x853f,0x8e},\r
+{0x8540,0xf0},\r
+{0x8541,0xa4},\r
+{0x8542,0xcd},\r
+{0x8543,0xa8},\r
+{0x8544,0xf0},\r
+{0x8545,0x8b},\r
+{0x8546,0xf0},\r
+{0x8547,0xa4},\r
+{0x8548,0x2d},\r
+{0x8549,0xcc},\r
+{0x854a,0x38},\r
+{0x854b,0x25},\r
+{0x854c,0xf0},\r
+{0x854d,0xfd},\r
+{0x854e,0xe9},\r
+{0x854f,0x8f},\r
+{0x8550,0xf0},\r
+{0x8551,0xa4},\r
+{0x8552,0x2c},\r
+{0x8553,0xcd},\r
+{0x8554,0x35},\r
+{0x8555,0xf0},\r
+{0x8556,0xfc},\r
+{0x8557,0xeb},\r
+{0x8558,0x8e},\r
+{0x8559,0xf0},\r
+{0x855a,0xa4},\r
+{0x855b,0xfe},\r
+{0x855c,0xa9},\r
+{0x855d,0xf0},\r
+{0x855e,0xeb},\r
+{0x855f,0x8f},\r
+{0x8560,0xf0},\r
+{0x8561,0xa4},\r
+{0x8562,0xcf},\r
+{0x8563,0xc5},\r
+{0x8564,0xf0},\r
+{0x8565,0x2e},\r
+{0x8566,0xcd},\r
+{0x8567,0x39},\r
+{0x8568,0xfe},\r
+{0x8569,0xe4},\r
+{0x856a,0x3c},\r
+{0x856b,0xfc},\r
+{0x856c,0xea},\r
+{0x856d,0xa4},\r
+{0x856e,0x2d},\r
+{0x856f,0xce},\r
+{0x8570,0x35},\r
+{0x8571,0xf0},\r
+{0x8572,0xfd},\r
+{0x8573,0xe4},\r
+{0x8574,0x3c},\r
+{0x8575,0xfc},\r
+{0x8576,0x22},\r
+{0x8577,0x75},\r
+{0x8578,0xf0},\r
+{0x8579,0x08},\r
+{0x857a,0x75},\r
+{0x857b,0x82},\r
+{0x857c,0x00},\r
+{0x857d,0xef},\r
+{0x857e,0x2f},\r
+{0x857f,0xff},\r
+{0x8580,0xee},\r
+{0x8581,0x33},\r
+{0x8582,0xfe},\r
+{0x8583,0xcd},\r
+{0x8584,0x33},\r
+{0x8585,0xcd},\r
+{0x8586,0xcc},\r
+{0x8587,0x33},\r
+{0x8588,0xcc},\r
+{0x8589,0xc5},\r
+{0x858a,0x82},\r
+{0x858b,0x33},\r
+{0x858c,0xc5},\r
+{0x858d,0x82},\r
+{0x858e,0x9b},\r
+{0x858f,0xed},\r
+{0x8590,0x9a},\r
+{0x8591,0xec},\r
+{0x8592,0x99},\r
+{0x8593,0xe5},\r
+{0x8594,0x82},\r
+{0x8595,0x98},\r
+{0x8596,0x40},\r
+{0x8597,0x0c},\r
+{0x8598,0xf5},\r
+{0x8599,0x82},\r
+{0x859a,0xee},\r
+{0x859b,0x9b},\r
+{0x859c,0xfe},\r
+{0x859d,0xed},\r
+{0x859e,0x9a},\r
+{0x859f,0xfd},\r
+{0x85a0,0xec},\r
+{0x85a1,0x99},\r
+{0x85a2,0xfc},\r
+{0x85a3,0x0f},\r
+{0x85a4,0xd5},\r
+{0x85a5,0xf0},\r
+{0x85a6,0xd6},\r
+{0x85a7,0xe4},\r
+{0x85a8,0xce},\r
+{0x85a9,0xfb},\r
+{0x85aa,0xe4},\r
+{0x85ab,0xcd},\r
+{0x85ac,0xfa},\r
+{0x85ad,0xe4},\r
+{0x85ae,0xcc},\r
+{0x85af,0xf9},\r
+{0x85b0,0xa8},\r
+{0x85b1,0x82},\r
+{0x85b2,0x22},\r
+{0x85b3,0xb8},\r
+{0x85b4,0x00},\r
+{0x85b5,0xc1},\r
+{0x85b6,0xb9},\r
+{0x85b7,0x00},\r
+{0x85b8,0x59},\r
+{0x85b9,0xba},\r
+{0x85ba,0x00},\r
+{0x85bb,0x2d},\r
+{0x85bc,0xec},\r
+{0x85bd,0x8b},\r
+{0x85be,0xf0},\r
+{0x85bf,0x84},\r
+{0x85c0,0xcf},\r
+{0x85c1,0xce},\r
+{0x85c2,0xcd},\r
+{0x85c3,0xfc},\r
+{0x85c4,0xe5},\r
+{0x85c5,0xf0},\r
+{0x85c6,0xcb},\r
+{0x85c7,0xf9},\r
+{0x85c8,0x78},\r
+{0x85c9,0x18},\r
+{0x85ca,0xef},\r
+{0x85cb,0x2f},\r
+{0x85cc,0xff},\r
+{0x85cd,0xee},\r
+{0x85ce,0x33},\r
+{0x85cf,0xfe},\r
+{0x85d0,0xed},\r
+{0x85d1,0x33},\r
+{0x85d2,0xfd},\r
+{0x85d3,0xec},\r
+{0x85d4,0x33},\r
+{0x85d5,0xfc},\r
+{0x85d6,0xeb},\r
+{0x85d7,0x33},\r
+{0x85d8,0xfb},\r
+{0x85d9,0x10},\r
+{0x85da,0xd7},\r
+{0x85db,0x03},\r
+{0x85dc,0x99},\r
+{0x85dd,0x40},\r
+{0x85de,0x04},\r
+{0x85df,0xeb},\r
+{0x85e0,0x99},\r
+{0x85e1,0xfb},\r
+{0x85e2,0x0f},\r
+{0x85e3,0xd8},\r
+{0x85e4,0xe5},\r
+{0x85e5,0xe4},\r
+{0x85e6,0xf9},\r
+{0x85e7,0xfa},\r
+{0x85e8,0x22},\r
+{0x85e9,0x78},\r
+{0x85ea,0x18},\r
+{0x85eb,0xef},\r
+{0x85ec,0x2f},\r
+{0x85ed,0xff},\r
+{0x85ee,0xee},\r
+{0x85ef,0x33},\r
+{0x85f0,0xfe},\r
+{0x85f1,0xed},\r
+{0x85f2,0x33},\r
+{0x85f3,0xfd},\r
+{0x85f4,0xec},\r
+{0x85f5,0x33},\r
+{0x85f6,0xfc},\r
+{0x85f7,0xc9},\r
+{0x85f8,0x33},\r
+{0x85f9,0xc9},\r
+{0x85fa,0x10},\r
+{0x85fb,0xd7},\r
+{0x85fc,0x05},\r
+{0x85fd,0x9b},\r
+{0x85fe,0xe9},\r
+{0x85ff,0x9a},\r
+{0x8600,0x40},\r
+{0x8601,0x07},\r
+{0x8602,0xec},\r
+{0x8603,0x9b},\r
+{0x8604,0xfc},\r
+{0x8605,0xe9},\r
+{0x8606,0x9a},\r
+{0x8607,0xf9},\r
+{0x8608,0x0f},\r
+{0x8609,0xd8},\r
+{0x860a,0xe0},\r
+{0x860b,0xe4},\r
+{0x860c,0xc9},\r
+{0x860d,0xfa},\r
+{0x860e,0xe4},\r
+{0x860f,0xcc},\r
+{0x8610,0xfb},\r
+{0x8611,0x22},\r
+{0x8612,0x75},\r
+{0x8613,0xf0},\r
+{0x8614,0x10},\r
+{0x8615,0xef},\r
+{0x8616,0x2f},\r
+{0x8617,0xff},\r
+{0x8618,0xee},\r
+{0x8619,0x33},\r
+{0x861a,0xfe},\r
+{0x861b,0xed},\r
+{0x861c,0x33},\r
+{0x861d,0xfd},\r
+{0x861e,0xcc},\r
+{0x861f,0x33},\r
+{0x8620,0xcc},\r
+{0x8621,0xc8},\r
+{0x8622,0x33},\r
+{0x8623,0xc8},\r
+{0x8624,0x10},\r
+{0x8625,0xd7},\r
+{0x8626,0x07},\r
+{0x8627,0x9b},\r
+{0x8628,0xec},\r
+{0x8629,0x9a},\r
+{0x862a,0xe8},\r
+{0x862b,0x99},\r
+{0x862c,0x40},\r
+{0x862d,0x0a},\r
+{0x862e,0xed},\r
+{0x862f,0x9b},\r
+{0x8630,0xfd},\r
+{0x8631,0xec},\r
+{0x8632,0x9a},\r
+{0x8633,0xfc},\r
+{0x8634,0xe8},\r
+{0x8635,0x99},\r
+{0x8636,0xf8},\r
+{0x8637,0x0f},\r
+{0x8638,0xd5},\r
+{0x8639,0xf0},\r
+{0x863a,0xda},\r
+{0x863b,0xe4},\r
+{0x863c,0xcd},\r
+{0x863d,0xfb},\r
+{0x863e,0xe4},\r
+{0x863f,0xcc},\r
+{0x8640,0xfa},\r
+{0x8641,0xe4},\r
+{0x8642,0xc8},\r
+{0x8643,0xf9},\r
+{0x8644,0x22},\r
+{0x8645,0xeb},\r
+{0x8646,0x9f},\r
+{0x8647,0xf5},\r
+{0x8648,0xf0},\r
+{0x8649,0xea},\r
+{0x864a,0x9e},\r
+{0x864b,0x42},\r
+{0x864c,0xf0},\r
+{0x864d,0xe9},\r
+{0x864e,0x9d},\r
+{0x864f,0x42},\r
+{0x8650,0xf0},\r
+{0x8651,0xe8},\r
+{0x8652,0x9c},\r
+{0x8653,0x45},\r
+{0x8654,0xf0},\r
+{0x8655,0x22},\r
+{0x8656,0xe8},\r
+{0x8657,0x60},\r
+{0x8658,0x0f},\r
+{0x8659,0xec},\r
+{0x865a,0xc3},\r
+{0x865b,0x13},\r
+{0x865c,0xfc},\r
+{0x865d,0xed},\r
+{0x865e,0x13},\r
+{0x865f,0xfd},\r
+{0x8660,0xee},\r
+{0x8661,0x13},\r
+{0x8662,0xfe},\r
+{0x8663,0xef},\r
+{0x8664,0x13},\r
+{0x8665,0xff},\r
+{0x8666,0xd8},\r
+{0x8667,0xf1},\r
+{0x8668,0x22},\r
+{0x8669,0xe8},\r
+{0x866a,0x60},\r
+{0x866b,0x0f},\r
+{0x866c,0xef},\r
+{0x866d,0xc3},\r
+{0x866e,0x33},\r
+{0x866f,0xff},\r
+{0x8670,0xee},\r
+{0x8671,0x33},\r
+{0x8672,0xfe},\r
+{0x8673,0xed},\r
+{0x8674,0x33},\r
+{0x8675,0xfd},\r
+{0x8676,0xec},\r
+{0x8677,0x33},\r
+{0x8678,0xfc},\r
+{0x8679,0xd8},\r
+{0x867a,0xf1},\r
+{0x867b,0x22},\r
+{0x867c,0xe4},\r
+{0x867d,0x93},\r
+{0x867e,0xfc},\r
+{0x867f,0x74},\r
+{0x8680,0x01},\r
+{0x8681,0x93},\r
+{0x8682,0xfd},\r
+{0x8683,0x74},\r
+{0x8684,0x02},\r
+{0x8685,0x93},\r
+{0x8686,0xfe},\r
+{0x8687,0x74},\r
+{0x8688,0x03},\r
+{0x8689,0x93},\r
+{0x868a,0xff},\r
+{0x868b,0x22},\r
+{0x868c,0xe6},\r
+{0x868d,0xfb},\r
+{0x868e,0x08},\r
+{0x868f,0xe6},\r
+{0x8690,0xf9},\r
+{0x8691,0x08},\r
+{0x8692,0xe6},\r
+{0x8693,0xfa},\r
+{0x8694,0x08},\r
+{0x8695,0xe6},\r
+{0x8696,0xcb},\r
+{0x8697,0xf8},\r
+{0x8698,0x22},\r
+{0x8699,0xec},\r
+{0x869a,0xf6},\r
+{0x869b,0x08},\r
+{0x869c,0xed},\r
+{0x869d,0xf6},\r
+{0x869e,0x08},\r
+{0x869f,0xee},\r
+{0x86a0,0xf6},\r
+{0x86a1,0x08},\r
+{0x86a2,0xef},\r
+{0x86a3,0xf6},\r
+{0x86a4,0x22},\r
+{0x86a5,0xa4},\r
+{0x86a6,0x25},\r
+{0x86a7,0x82},\r
+{0x86a8,0xf5},\r
+{0x86a9,0x82},\r
+{0x86aa,0xe5},\r
+{0x86ab,0xf0},\r
+{0x86ac,0x35},\r
+{0x86ad,0x83},\r
+{0x86ae,0xf5},\r
+{0x86af,0x83},\r
+{0x86b0,0x22},\r
+{0x86b1,0xd0},\r
+{0x86b2,0x83},\r
+{0x86b3,0xd0},\r
+{0x86b4,0x82},\r
+{0x86b5,0xf8},\r
+{0x86b6,0xe4},\r
+{0x86b7,0x93},\r
+{0x86b8,0x70},\r
+{0x86b9,0x12},\r
+{0x86ba,0x74},\r
+{0x86bb,0x01},\r
+{0x86bc,0x93},\r
+{0x86bd,0x70},\r
+{0x86be,0x0d},\r
+{0x86bf,0xa3},\r
+{0x86c0,0xa3},\r
+{0x86c1,0x93},\r
+{0x86c2,0xf8},\r
+{0x86c3,0x74},\r
+{0x86c4,0x01},\r
+{0x86c5,0x93},\r
+{0x86c6,0xf5},\r
+{0x86c7,0x82},\r
+{0x86c8,0x88},\r
+{0x86c9,0x83},\r
+{0x86ca,0xe4},\r
+{0x86cb,0x73},\r
+{0x86cc,0x74},\r
+{0x86cd,0x02},\r
+{0x86ce,0x93},\r
+{0x86cf,0x68},\r
+{0x86d0,0x60},\r
+{0x86d1,0xef},\r
+{0x86d2,0xa3},\r
+{0x86d3,0xa3},\r
+{0x86d4,0xa3},\r
+{0x86d5,0x80},\r
+{0x86d6,0xdf},\r
+{0x86d7,0x90},\r
+{0x86d8,0x38},\r
+{0x86d9,0x04},\r
+{0x86da,0x78},\r
+{0x86db,0x52},\r
+{0x86dc,0x12},\r
+{0x86dd,0x0b},\r
+{0x86de,0xfd},\r
+{0x86df,0x90},\r
+{0x86e0,0x38},\r
+{0x86e1,0x00},\r
+{0x86e2,0xe0},\r
+{0x86e3,0xfe},\r
+{0x86e4,0xa3},\r
+{0x86e5,0xe0},\r
+{0x86e6,0xfd},\r
+{0x86e7,0xed},\r
+{0x86e8,0xff},\r
+{0x86e9,0xc3},\r
+{0x86ea,0x12},\r
+{0x86eb,0x0b},\r
+{0x86ec,0x9e},\r
+{0x86ed,0x90},\r
+{0x86ee,0x38},\r
+{0x86ef,0x10},\r
+{0x86f0,0x12},\r
+{0x86f1,0x0b},\r
+{0x86f2,0x92},\r
+{0x86f3,0x90},\r
+{0x86f4,0x38},\r
+{0x86f5,0x06},\r
+{0x86f6,0x78},\r
+{0x86f7,0x54},\r
+{0x86f8,0x12},\r
+{0x86f9,0x0b},\r
+{0x86fa,0xfd},\r
+{0x86fb,0x90},\r
+{0x86fc,0x38},\r
+{0x86fd,0x02},\r
+{0x86fe,0xe0},\r
+{0x86ff,0xfe},\r
+{0x8700,0xa3},\r
+{0x8701,0xe0},\r
+{0x8702,0xfd},\r
+{0x8703,0xed},\r
+{0x8704,0xff},\r
+{0x8705,0xc3},\r
+{0x8706,0x12},\r
+{0x8707,0x0b},\r
+{0x8708,0x9e},\r
+{0x8709,0x90},\r
+{0x870a,0x38},\r
+{0x870b,0x12},\r
+{0x870c,0x12},\r
+{0x870d,0x0b},\r
+{0x870e,0x92},\r
+{0x870f,0xa3},\r
+{0x8710,0xe0},\r
+{0x8711,0xb4},\r
+{0x8712,0x31},\r
+{0x8713,0x07},\r
+{0x8714,0x78},\r
+{0x8715,0x52},\r
+{0x8716,0x79},\r
+{0x8717,0x52},\r
+{0x8718,0x12},\r
+{0x8719,0x0c},\r
+{0x871a,0x13},\r
+{0x871b,0x90},\r
+{0x871c,0x38},\r
+{0x871d,0x14},\r
+{0x871e,0xe0},\r
+{0x871f,0xb4},\r
+{0x8720,0x71},\r
+{0x8721,0x15},\r
+{0x8722,0x78},\r
+{0x8723,0x52},\r
+{0x8724,0xe6},\r
+{0x8725,0xfe},\r
+{0x8726,0x08},\r
+{0x8727,0xe6},\r
+{0x8728,0x78},\r
+{0x8729,0x02},\r
+{0x872a,0xce},\r
+{0x872b,0xc3},\r
+{0x872c,0x13},\r
+{0x872d,0xce},\r
+{0x872e,0x13},\r
+{0x872f,0xd8},\r
+{0x8730,0xf9},\r
+{0x8731,0x79},\r
+{0x8732,0x53},\r
+{0x8733,0xf7},\r
+{0x8734,0xee},\r
+{0x8735,0x19},\r
+{0x8736,0xf7},\r
+{0x8737,0x90},\r
+{0x8738,0x38},\r
+{0x8739,0x15},\r
+{0x873a,0xe0},\r
+{0x873b,0xb4},\r
+{0x873c,0x31},\r
+{0x873d,0x07},\r
+{0x873e,0x78},\r
+{0x873f,0x54},\r
+{0x8740,0x79},\r
+{0x8741,0x54},\r
+{0x8742,0x12},\r
+{0x8743,0x0c},\r
+{0x8744,0x13},\r
+{0x8745,0x90},\r
+{0x8746,0x38},\r
+{0x8747,0x15},\r
+{0x8748,0xe0},\r
+{0x8749,0xb4},\r
+{0x874a,0x71},\r
+{0x874b,0x15},\r
+{0x874c,0x78},\r
+{0x874d,0x54},\r
+{0x874e,0xe6},\r
+{0x874f,0xfe},\r
+{0x8750,0x08},\r
+{0x8751,0xe6},\r
+{0x8752,0x78},\r
+{0x8753,0x02},\r
+{0x8754,0xce},\r
+{0x8755,0xc3},\r
+{0x8756,0x13},\r
+{0x8757,0xce},\r
+{0x8758,0x13},\r
+{0x8759,0xd8},\r
+{0x875a,0xf9},\r
+{0x875b,0x79},\r
+{0x875c,0x55},\r
+{0x875d,0xf7},\r
+{0x875e,0xee},\r
+{0x875f,0x19},\r
+{0x8760,0xf7},\r
+{0x8761,0x79},\r
+{0x8762,0x52},\r
+{0x8763,0x12},\r
+{0x8764,0x0b},\r
+{0x8765,0xd9},\r
+{0x8766,0x09},\r
+{0x8767,0x12},\r
+{0x8768,0x0b},\r
+{0x8769,0xd9},\r
+{0x876a,0xaf},\r
+{0x876b,0x47},\r
+{0x876c,0x12},\r
+{0x876d,0x0b},\r
+{0x876e,0xb2},\r
+{0x876f,0xe5},\r
+{0x8770,0x44},\r
+{0x8771,0xfb},\r
+{0x8772,0x7a},\r
+{0x8773,0x00},\r
+{0x8774,0xfd},\r
+{0x8775,0x7c},\r
+{0x8776,0x00},\r
+{0x8777,0x12},\r
+{0x8778,0x04},\r
+{0x8779,0xd3},\r
+{0x877a,0x78},\r
+{0x877b,0x5a},\r
+{0x877c,0xa6},\r
+{0x877d,0x06},\r
+{0x877e,0x08},\r
+{0x877f,0xa6},\r
+{0x8780,0x07},\r
+{0x8781,0xaf},\r
+{0x8782,0x45},\r
+{0x8783,0x12},\r
+{0x8784,0x0b},\r
+{0x8785,0xb2},\r
+{0x8786,0xad},\r
+{0x8787,0x03},\r
+{0x8788,0x7c},\r
+{0x8789,0x00},\r
+{0x878a,0x12},\r
+{0x878b,0x04},\r
+{0x878c,0xd3},\r
+{0x878d,0x78},\r
+{0x878e,0x56},\r
+{0x878f,0xa6},\r
+{0x8790,0x06},\r
+{0x8791,0x08},\r
+{0x8792,0xa6},\r
+{0x8793,0x07},\r
+{0x8794,0xaf},\r
+{0x8795,0x48},\r
+{0x8796,0x78},\r
+{0x8797,0x54},\r
+{0x8798,0x12},\r
+{0x8799,0x0b},\r
+{0x879a,0xb4},\r
+{0x879b,0xe5},\r
+{0x879c,0x43},\r
+{0x879d,0xfb},\r
+{0x879e,0xfd},\r
+{0x879f,0x7c},\r
+{0x87a0,0x00},\r
+{0x87a1,0x12},\r
+{0x87a2,0x04},\r
+{0x87a3,0xd3},\r
+{0x87a4,0x78},\r
+{0x87a5,0x5c},\r
+{0x87a6,0xa6},\r
+{0x87a7,0x06},\r
+{0x87a8,0x08},\r
+{0x87a9,0xa6},\r
+{0x87aa,0x07},\r
+{0x87ab,0xaf},\r
+{0x87ac,0x46},\r
+{0x87ad,0x7e},\r
+{0x87ae,0x00},\r
+{0x87af,0x78},\r
+{0x87b0,0x54},\r
+{0x87b1,0x12},\r
+{0x87b2,0x0b},\r
+{0x87b3,0xb6},\r
+{0x87b4,0xad},\r
+{0x87b5,0x03},\r
+{0x87b6,0x7c},\r
+{0x87b7,0x00},\r
+{0x87b8,0x12},\r
+{0x87b9,0x04},\r
+{0x87ba,0xd3},\r
+{0x87bb,0x78},\r
+{0x87bc,0x58},\r
+{0x87bd,0xa6},\r
+{0x87be,0x06},\r
+{0x87bf,0x08},\r
+{0x87c0,0xa6},\r
+{0x87c1,0x07},\r
+{0x87c2,0xc3},\r
+{0x87c3,0x78},\r
+{0x87c4,0x5b},\r
+{0x87c5,0xe6},\r
+{0x87c6,0x94},\r
+{0x87c7,0x08},\r
+{0x87c8,0x18},\r
+{0x87c9,0xe6},\r
+{0x87ca,0x94},\r
+{0x87cb,0x00},\r
+{0x87cc,0x50},\r
+{0x87cd,0x05},\r
+{0x87ce,0x76},\r
+{0x87cf,0x00},\r
+{0x87d0,0x08},\r
+{0x87d1,0x76},\r
+{0x87d2,0x08},\r
+{0x87d3,0xc3},\r
+{0x87d4,0x78},\r
+{0x87d5,0x5d},\r
+{0x87d6,0xe6},\r
+{0x87d7,0x94},\r
+{0x87d8,0x08},\r
+{0x87d9,0x18},\r
+{0x87da,0xe6},\r
+{0x87db,0x94},\r
+{0x87dc,0x00},\r
+{0x87dd,0x50},\r
+{0x87de,0x05},\r
+{0x87df,0x76},\r
+{0x87e0,0x00},\r
+{0x87e1,0x08},\r
+{0x87e2,0x76},\r
+{0x87e3,0x08},\r
+{0x87e4,0x78},\r
+{0x87e5,0x5a},\r
+{0x87e6,0x12},\r
+{0x87e7,0x0b},\r
+{0x87e8,0xc6},\r
+{0x87e9,0xff},\r
+{0x87ea,0xd3},\r
+{0x87eb,0x78},\r
+{0x87ec,0x57},\r
+{0x87ed,0xe6},\r
+{0x87ee,0x9f},\r
+{0x87ef,0x18},\r
+{0x87f0,0xe6},\r
+{0x87f1,0x9e},\r
+{0x87f2,0x40},\r
+{0x87f3,0x0e},\r
+{0x87f4,0x78},\r
+{0x87f5,0x5a},\r
+{0x87f6,0xe6},\r
+{0x87f7,0x13},\r
+{0x87f8,0xfe},\r
+{0x87f9,0x08},\r
+{0x87fa,0xe6},\r
+{0x87fb,0x78},\r
+{0x87fc,0x57},\r
+{0x87fd,0x12},\r
+{0x87fe,0x0c},\r
+{0x87ff,0x08},\r
+{0x8800,0x80},\r
+{0x8801,0x04},\r
+{0x8802,0x7e},\r
+{0x8803,0x00},\r
+{0x8804,0x7f},\r
+{0x8805,0x00},\r
+{0x8806,0x78},\r
+{0x8807,0x5e},\r
+{0x8808,0x12},\r
+{0x8809,0x0b},\r
+{0x880a,0xbe},\r
+{0x880b,0xff},\r
+{0x880c,0xd3},\r
+{0x880d,0x78},\r
+{0x880e,0x59},\r
+{0x880f,0xe6},\r
+{0x8810,0x9f},\r
+{0x8811,0x18},\r
+{0x8812,0xe6},\r
+{0x8813,0x9e},\r
+{0x8814,0x40},\r
+{0x8815,0x0e},\r
+{0x8816,0x78},\r
+{0x8817,0x5c},\r
+{0x8818,0xe6},\r
+{0x8819,0x13},\r
+{0x881a,0xfe},\r
+{0x881b,0x08},\r
+{0x881c,0xe6},\r
+{0x881d,0x78},\r
+{0x881e,0x59},\r
+{0x881f,0x12},\r
+{0x8820,0x0c},\r
+{0x8821,0x08},\r
+{0x8822,0x80},\r
+{0x8823,0x04},\r
+{0x8824,0x7e},\r
+{0x8825,0x00},\r
+{0x8826,0x7f},\r
+{0x8827,0x00},\r
+{0x8828,0xe4},\r
+{0x8829,0xfc},\r
+{0x882a,0xfd},\r
+{0x882b,0x78},\r
+{0x882c,0x62},\r
+{0x882d,0x12},\r
+{0x882e,0x06},\r
+{0x882f,0x99},\r
+{0x8830,0x78},\r
+{0x8831,0x5a},\r
+{0x8832,0x12},\r
+{0x8833,0x0b},\r
+{0x8834,0xc6},\r
+{0x8835,0x78},\r
+{0x8836,0x57},\r
+{0x8837,0x26},\r
+{0x8838,0xff},\r
+{0x8839,0xee},\r
+{0x883a,0x18},\r
+{0x883b,0x36},\r
+{0x883c,0xfe},\r
+{0x883d,0x78},\r
+{0x883e,0x66},\r
+{0x883f,0x12},\r
+{0x8840,0x0b},\r
+{0x8841,0xbe},\r
+{0x8842,0x78},\r
+{0x8843,0x59},\r
+{0x8844,0x26},\r
+{0x8845,0xff},\r
+{0x8846,0xee},\r
+{0x8847,0x18},\r
+{0x8848,0x36},\r
+{0x8849,0xfe},\r
+{0x884a,0xe4},\r
+{0x884b,0xfc},\r
+{0x884c,0xfd},\r
+{0x884d,0x78},\r
+{0x884e,0x6a},\r
+{0x884f,0x12},\r
+{0x8850,0x06},\r
+{0x8851,0x99},\r
+{0x8852,0x12},\r
+{0x8853,0x0b},\r
+{0x8854,0xce},\r
+{0x8855,0x78},\r
+{0x8856,0x66},\r
+{0x8857,0x12},\r
+{0x8858,0x06},\r
+{0x8859,0x8c},\r
+{0x885a,0xd3},\r
+{0x885b,0x12},\r
+{0x885c,0x06},\r
+{0x885d,0x45},\r
+{0x885e,0x40},\r
+{0x885f,0x08},\r
+{0x8860,0x12},\r
+{0x8861,0x0b},\r
+{0x8862,0xce},\r
+{0x8863,0x78},\r
+{0x8864,0x66},\r
+{0x8865,0x12},\r
+{0x8866,0x06},\r
+{0x8867,0x99},\r
+{0x8868,0x78},\r
+{0x8869,0x54},\r
+{0x886a,0x12},\r
+{0x886b,0x0b},\r
+{0x886c,0xd0},\r
+{0x886d,0x78},\r
+{0x886e,0x6a},\r
+{0x886f,0x12},\r
+{0x8870,0x06},\r
+{0x8871,0x8c},\r
+{0x8872,0xd3},\r
+{0x8873,0x12},\r
+{0x8874,0x06},\r
+{0x8875,0x45},\r
+{0x8876,0x40},\r
+{0x8877,0x0a},\r
+{0x8878,0x78},\r
+{0x8879,0x54},\r
+{0x887a,0x12},\r
+{0x887b,0x0b},\r
+{0x887c,0xd0},\r
+{0x887d,0x78},\r
+{0x887e,0x6a},\r
+{0x887f,0x12},\r
+{0x8880,0x06},\r
+{0x8881,0x99},\r
+{0x8882,0x78},\r
+{0x8883,0x61},\r
+{0x8884,0xe6},\r
+{0x8885,0x90},\r
+{0x8886,0x60},\r
+{0x8887,0x01},\r
+{0x8888,0xf0},\r
+{0x8889,0x78},\r
+{0x888a,0x65},\r
+{0x888b,0xe6},\r
+{0x888c,0xa3},\r
+{0x888d,0xf0},\r
+{0x888e,0x78},\r
+{0x888f,0x69},\r
+{0x8890,0xe6},\r
+{0x8891,0xa3},\r
+{0x8892,0xf0},\r
+{0x8893,0x78},\r
+{0x8894,0x55},\r
+{0x8895,0xe6},\r
+{0x8896,0xa3},\r
+{0x8897,0xf0},\r
+{0x8898,0x7d},\r
+{0x8899,0x01},\r
+{0x889a,0x78},\r
+{0x889b,0x61},\r
+{0x889c,0x12},\r
+{0x889d,0x0b},\r
+{0x889e,0xe9},\r
+{0x889f,0x24},\r
+{0x88a0,0x01},\r
+{0x88a1,0x12},\r
+{0x88a2,0x0b},\r
+{0x88a3,0xa6},\r
+{0x88a4,0x78},\r
+{0x88a5,0x65},\r
+{0x88a6,0x12},\r
+{0x88a7,0x0b},\r
+{0x88a8,0xe9},\r
+{0x88a9,0x24},\r
+{0x88aa,0x02},\r
+{0x88ab,0x12},\r
+{0x88ac,0x0b},\r
+{0x88ad,0xa6},\r
+{0x88ae,0x78},\r
+{0x88af,0x69},\r
+{0x88b0,0x12},\r
+{0x88b1,0x0b},\r
+{0x88b2,0xe9},\r
+{0x88b3,0x24},\r
+{0x88b4,0x03},\r
+{0x88b5,0x12},\r
+{0x88b6,0x0b},\r
+{0x88b7,0xa6},\r
+{0x88b8,0x78},\r
+{0x88b9,0x6d},\r
+{0x88ba,0x12},\r
+{0x88bb,0x0b},\r
+{0x88bc,0xe9},\r
+{0x88bd,0x24},\r
+{0x88be,0x04},\r
+{0x88bf,0x12},\r
+{0x88c0,0x0b},\r
+{0x88c1,0xa6},\r
+{0x88c2,0x0d},\r
+{0x88c3,0xbd},\r
+{0x88c4,0x05},\r
+{0x88c5,0xd4},\r
+{0x88c6,0xc2},\r
+{0x88c7,0x0e},\r
+{0x88c8,0xc2},\r
+{0x88c9,0x06},\r
+{0x88ca,0x22},\r
+{0x88cb,0x85},\r
+{0x88cc,0x08},\r
+{0x88cd,0x41},\r
+{0x88ce,0x90},\r
+{0x88cf,0x30},\r
+{0x88d0,0x24},\r
+{0x88d1,0xe0},\r
+{0x88d2,0xf5},\r
+{0x88d3,0x3d},\r
+{0x88d4,0xa3},\r
+{0x88d5,0xe0},\r
+{0x88d6,0xf5},\r
+{0x88d7,0x3e},\r
+{0x88d8,0xa3},\r
+{0x88d9,0xe0},\r
+{0x88da,0xf5},\r
+{0x88db,0x3f},\r
+{0x88dc,0xa3},\r
+{0x88dd,0xe0},\r
+{0x88de,0xf5},\r
+{0x88df,0x40},\r
+{0x88e0,0xa3},\r
+{0x88e1,0xe0},\r
+{0x88e2,0xf5},\r
+{0x88e3,0x3c},\r
+{0x88e4,0xd2},\r
+{0x88e5,0x34},\r
+{0x88e6,0xe5},\r
+{0x88e7,0x41},\r
+{0x88e8,0x12},\r
+{0x88e9,0x06},\r
+{0x88ea,0xb1},\r
+{0x88eb,0x09},\r
+{0x88ec,0x31},\r
+{0x88ed,0x03},\r
+{0x88ee,0x09},\r
+{0x88ef,0x35},\r
+{0x88f0,0x04},\r
+{0x88f1,0x09},\r
+{0x88f2,0x3b},\r
+{0x88f3,0x05},\r
+{0x88f4,0x09},\r
+{0x88f5,0x3e},\r
+{0x88f6,0x06},\r
+{0x88f7,0x09},\r
+{0x88f8,0x41},\r
+{0x88f9,0x07},\r
+{0x88fa,0x09},\r
+{0x88fb,0x4a},\r
+{0x88fc,0x08},\r
+{0x88fd,0x09},\r
+{0x88fe,0x5b},\r
+{0x88ff,0x12},\r
+{0x8900,0x09},\r
+{0x8901,0x73},\r
+{0x8902,0x18},\r
+{0x8903,0x09},\r
+{0x8904,0x89},\r
+{0x8905,0x19},\r
+{0x8906,0x09},\r
+{0x8907,0x5e},\r
+{0x8908,0x1a},\r
+{0x8909,0x09},\r
+{0x890a,0x6a},\r
+{0x890b,0x1b},\r
+{0x890c,0x09},\r
+{0x890d,0xad},\r
+{0x890e,0x80},\r
+{0x890f,0x09},\r
+{0x8910,0xb2},\r
+{0x8911,0x81},\r
+{0x8912,0x0a},\r
+{0x8913,0x1d},\r
+{0x8914,0x8f},\r
+{0x8915,0x0a},\r
+{0x8916,0x09},\r
+{0x8917,0x90},\r
+{0x8918,0x0a},\r
+{0x8919,0x1d},\r
+{0x891a,0x91},\r
+{0x891b,0x0a},\r
+{0x891c,0x1d},\r
+{0x891d,0x92},\r
+{0x891e,0x0a},\r
+{0x891f,0x1d},\r
+{0x8920,0x93},\r
+{0x8921,0x0a},\r
+{0x8922,0x1d},\r
+{0x8923,0x94},\r
+{0x8924,0x0a},\r
+{0x8925,0x1d},\r
+{0x8926,0x98},\r
+{0x8927,0x0a},\r
+{0x8928,0x17},\r
+{0x8929,0x9f},\r
+{0x892a,0x0a},\r
+{0x892b,0x1a},\r
+{0x892c,0xec},\r
+{0x892d,0x00},\r
+{0x892e,0x00},\r
+{0x892f,0x0a},\r
+{0x8930,0x38},\r
+{0x8931,0x12},\r
+{0x8932,0x0f},\r
+{0x8933,0x74},\r
+{0x8934,0x22},\r
+{0x8935,0x12},\r
+{0x8936,0x0f},\r
+{0x8937,0x74},\r
+{0x8938,0xd2},\r
+{0x8939,0x03},\r
+{0x893a,0x22},\r
+{0x893b,0xd2},\r
+{0x893c,0x03},\r
+{0x893d,0x22},\r
+{0x893e,0xc2},\r
+{0x893f,0x03},\r
+{0x8940,0x22},\r
+{0x8941,0xa2},\r
+{0x8942,0x37},\r
+{0x8943,0xe4},\r
+{0x8944,0x33},\r
+{0x8945,0xf5},\r
+{0x8946,0x3c},\r
+{0x8947,0x02},\r
+{0x8948,0x0a},\r
+{0x8949,0x1d},\r
+{0x894a,0xc2},\r
+{0x894b,0x01},\r
+{0x894c,0xc2},\r
+{0x894d,0x02},\r
+{0x894e,0xc2},\r
+{0x894f,0x03},\r
+{0x8950,0x12},\r
+{0x8951,0x0d},\r
+{0x8952,0x0d},\r
+{0x8953,0x75},\r
+{0x8954,0x1e},\r
+{0x8955,0x70},\r
+{0x8956,0xd2},\r
+{0x8957,0x35},\r
+{0x8958,0x02},\r
+{0x8959,0x0a},\r
+{0x895a,0x1d},\r
+{0x895b,0x02},\r
+{0x895c,0x0a},\r
+{0x895d,0x04},\r
+{0x895e,0x85},\r
+{0x895f,0x40},\r
+{0x8960,0x4a},\r
+{0x8961,0x85},\r
+{0x8962,0x3c},\r
+{0x8963,0x4b},\r
+{0x8964,0x12},\r
+{0x8965,0x0a},\r
+{0x8966,0xff},\r
+{0x8967,0x02},\r
+{0x8968,0x0a},\r
+{0x8969,0x1d},\r
+{0x896a,0x85},\r
+{0x896b,0x4a},\r
+{0x896c,0x40},\r
+{0x896d,0x85},\r
+{0x896e,0x4b},\r
+{0x896f,0x3c},\r
+{0x8970,0x02},\r
+{0x8971,0x0a},\r
+{0x8972,0x1d},\r
+{0x8973,0xe4},\r
+{0x8974,0xf5},\r
+{0x8975,0x22},\r
+{0x8976,0xf5},\r
+{0x8977,0x23},\r
+{0x8978,0x85},\r
+{0x8979,0x40},\r
+{0x897a,0x31},\r
+{0x897b,0x85},\r
+{0x897c,0x3f},\r
+{0x897d,0x30},\r
+{0x897e,0x85},\r
+{0x897f,0x3e},\r
+{0x8980,0x2f},\r
+{0x8981,0x85},\r
+{0x8982,0x3d},\r
+{0x8983,0x2e},\r
+{0x8984,0x12},\r
+{0x8985,0x0f},\r
+{0x8986,0x46},\r
+{0x8987,0x80},\r
+{0x8988,0x1f},\r
+{0x8989,0x75},\r
+{0x898a,0x22},\r
+{0x898b,0x00},\r
+{0x898c,0x75},\r
+{0x898d,0x23},\r
+{0x898e,0x01},\r
+{0x898f,0x74},\r
+{0x8990,0xff},\r
+{0x8991,0xf5},\r
+{0x8992,0x2d},\r
+{0x8993,0xf5},\r
+{0x8994,0x2c},\r
+{0x8995,0xf5},\r
+{0x8996,0x2b},\r
+{0x8997,0xf5},\r
+{0x8998,0x2a},\r
+{0x8999,0x12},\r
+{0x899a,0x0f},\r
+{0x899b,0x46},\r
+{0x899c,0x85},\r
+{0x899d,0x2d},\r
+{0x899e,0x40},\r
+{0x899f,0x85},\r
+{0x89a0,0x2c},\r
+{0x89a1,0x3f},\r
+{0x89a2,0x85},\r
+{0x89a3,0x2b},\r
+{0x89a4,0x3e},\r
+{0x89a5,0x85},\r
+{0x89a6,0x2a},\r
+{0x89a7,0x3d},\r
+{0x89a8,0xe4},\r
+{0x89a9,0xf5},\r
+{0x89aa,0x3c},\r
+{0x89ab,0x80},\r
+{0x89ac,0x70},\r
+{0x89ad,0x12},\r
+{0x89ae,0x0f},\r
+{0x89af,0x16},\r
+{0x89b0,0x80},\r
+{0x89b1,0x6b},\r
+{0x89b2,0x85},\r
+{0x89b3,0x3d},\r
+{0x89b4,0x45},\r
+{0x89b5,0x85},\r
+{0x89b6,0x3e},\r
+{0x89b7,0x46},\r
+{0x89b8,0xe5},\r
+{0x89b9,0x47},\r
+{0x89ba,0xc3},\r
+{0x89bb,0x13},\r
+{0x89bc,0xff},\r
+{0x89bd,0xe5},\r
+{0x89be,0x45},\r
+{0x89bf,0xc3},\r
+{0x89c0,0x9f},\r
+{0x89c1,0x50},\r
+{0x89c2,0x02},\r
+{0x89c3,0x8f},\r
+{0x89c4,0x45},\r
+{0x89c5,0xe5},\r
+{0x89c6,0x48},\r
+{0x89c7,0xc3},\r
+{0x89c8,0x13},\r
+{0x89c9,0xff},\r
+{0x89ca,0xe5},\r
+{0x89cb,0x46},\r
+{0x89cc,0xc3},\r
+{0x89cd,0x9f},\r
+{0x89ce,0x50},\r
+{0x89cf,0x02},\r
+{0x89d0,0x8f},\r
+{0x89d1,0x46},\r
+{0x89d2,0xe5},\r
+{0x89d3,0x47},\r
+{0x89d4,0xc3},\r
+{0x89d5,0x13},\r
+{0x89d6,0xff},\r
+{0x89d7,0xfd},\r
+{0x89d8,0xe5},\r
+{0x89d9,0x45},\r
+{0x89da,0x2d},\r
+{0x89db,0xfd},\r
+{0x89dc,0xe4},\r
+{0x89dd,0x33},\r
+{0x89de,0xfc},\r
+{0x89df,0xe5},\r
+{0x89e0,0x44},\r
+{0x89e1,0x12},\r
+{0x89e2,0x0f},\r
+{0x89e3,0x90},\r
+{0x89e4,0x40},\r
+{0x89e5,0x05},\r
+{0x89e6,0xe5},\r
+{0x89e7,0x44},\r
+{0x89e8,0x9f},\r
+{0x89e9,0xf5},\r
+{0x89ea,0x45},\r
+{0x89eb,0xe5},\r
+{0x89ec,0x48},\r
+{0x89ed,0xc3},\r
+{0x89ee,0x13},\r
+{0x89ef,0xff},\r
+{0x89f0,0xfd},\r
+{0x89f1,0xe5},\r
+{0x89f2,0x46},\r
+{0x89f3,0x2d},\r
+{0x89f4,0xfd},\r
+{0x89f5,0xe4},\r
+{0x89f6,0x33},\r
+{0x89f7,0xfc},\r
+{0x89f8,0xe5},\r
+{0x89f9,0x43},\r
+{0x89fa,0x12},\r
+{0x89fb,0x0f},\r
+{0x89fc,0x90},\r
+{0x89fd,0x40},\r
+{0x89fe,0x05},\r
+{0x89ff,0xe5},\r
+{0x8a00,0x43},\r
+{0x8a01,0x9f},\r
+{0x8a02,0xf5},\r
+{0x8a03,0x46},\r
+{0x8a04,0x12},\r
+{0x8a05,0x06},\r
+{0x8a06,0xd7},\r
+{0x8a07,0x80},\r
+{0x8a08,0x14},\r
+{0x8a09,0x85},\r
+{0x8a0a,0x40},\r
+{0x8a0b,0x48},\r
+{0x8a0c,0x85},\r
+{0x8a0d,0x3f},\r
+{0x8a0e,0x47},\r
+{0x8a0f,0x85},\r
+{0x8a10,0x3e},\r
+{0x8a11,0x46},\r
+{0x8a12,0x85},\r
+{0x8a13,0x3d},\r
+{0x8a14,0x45},\r
+{0x8a15,0x80},\r
+{0x8a16,0x06},\r
+{0x8a17,0x02},\r
+{0x8a18,0x06},\r
+{0x8a19,0xd7},\r
+{0x8a1a,0x12},\r
+{0x8a1b,0x0d},\r
+{0x8a1c,0x7e},\r
+{0x8a1d,0x90},\r
+{0x8a1e,0x30},\r
+{0x8a1f,0x24},\r
+{0x8a20,0xe5},\r
+{0x8a21,0x3d},\r
+{0x8a22,0xf0},\r
+{0x8a23,0xa3},\r
+{0x8a24,0xe5},\r
+{0x8a25,0x3e},\r
+{0x8a26,0xf0},\r
+{0x8a27,0xa3},\r
+{0x8a28,0xe5},\r
+{0x8a29,0x3f},\r
+{0x8a2a,0xf0},\r
+{0x8a2b,0xa3},\r
+{0x8a2c,0xe5},\r
+{0x8a2d,0x40},\r
+{0x8a2e,0xf0},\r
+{0x8a2f,0xa3},\r
+{0x8a30,0xe5},\r
+{0x8a31,0x3c},\r
+{0x8a32,0xf0},\r
+{0x8a33,0x90},\r
+{0x8a34,0x30},\r
+{0x8a35,0x23},\r
+{0x8a36,0xe4},\r
+{0x8a37,0xf0},\r
+{0x8a38,0x22},\r
+{0x8a39,0xc0},\r
+{0x8a3a,0xe0},\r
+{0x8a3b,0xc0},\r
+{0x8a3c,0x83},\r
+{0x8a3d,0xc0},\r
+{0x8a3e,0x82},\r
+{0x8a3f,0xc0},\r
+{0x8a40,0xd0},\r
+{0x8a41,0x90},\r
+{0x8a42,0x3f},\r
+{0x8a43,0x0c},\r
+{0x8a44,0xe0},\r
+{0x8a45,0xf5},\r
+{0x8a46,0x32},\r
+{0x8a47,0xe5},\r
+{0x8a48,0x32},\r
+{0x8a49,0x30},\r
+{0x8a4a,0xe3},\r
+{0x8a4b,0x74},\r
+{0x8a4c,0x30},\r
+{0x8a4d,0x36},\r
+{0x8a4e,0x66},\r
+{0x8a4f,0x90},\r
+{0x8a50,0x60},\r
+{0x8a51,0x19},\r
+{0x8a52,0xe0},\r
+{0x8a53,0xf5},\r
+{0x8a54,0x0a},\r
+{0x8a55,0xa3},\r
+{0x8a56,0xe0},\r
+{0x8a57,0xf5},\r
+{0x8a58,0x0b},\r
+{0x8a59,0x90},\r
+{0x8a5a,0x60},\r
+{0x8a5b,0x1d},\r
+{0x8a5c,0xe0},\r
+{0x8a5d,0xf5},\r
+{0x8a5e,0x14},\r
+{0x8a5f,0xa3},\r
+{0x8a60,0xe0},\r
+{0x8a61,0xf5},\r
+{0x8a62,0x15},\r
+{0x8a63,0x90},\r
+{0x8a64,0x60},\r
+{0x8a65,0x21},\r
+{0x8a66,0xe0},\r
+{0x8a67,0xf5},\r
+{0x8a68,0x0c},\r
+{0x8a69,0xa3},\r
+{0x8a6a,0xe0},\r
+{0x8a6b,0xf5},\r
+{0x8a6c,0x0d},\r
+{0x8a6d,0x90},\r
+{0x8a6e,0x60},\r
+{0x8a6f,0x29},\r
+{0x8a70,0xe0},\r
+{0x8a71,0xf5},\r
+{0x8a72,0x0e},\r
+{0x8a73,0xa3},\r
+{0x8a74,0xe0},\r
+{0x8a75,0xf5},\r
+{0x8a76,0x0f},\r
+{0x8a77,0x90},\r
+{0x8a78,0x60},\r
+{0x8a79,0x31},\r
+{0x8a7a,0xe0},\r
+{0x8a7b,0xf5},\r
+{0x8a7c,0x10},\r
+{0x8a7d,0xa3},\r
+{0x8a7e,0xe0},\r
+{0x8a7f,0xf5},\r
+{0x8a80,0x11},\r
+{0x8a81,0x90},\r
+{0x8a82,0x60},\r
+{0x8a83,0x39},\r
+{0x8a84,0xe0},\r
+{0x8a85,0xf5},\r
+{0x8a86,0x12},\r
+{0x8a87,0xa3},\r
+{0x8a88,0xe0},\r
+{0x8a89,0xf5},\r
+{0x8a8a,0x13},\r
+{0x8a8b,0x30},\r
+{0x8a8c,0x01},\r
+{0x8a8d,0x06},\r
+{0x8a8e,0x30},\r
+{0x8a8f,0x33},\r
+{0x8a90,0x03},\r
+{0x8a91,0xd3},\r
+{0x8a92,0x80},\r
+{0x8a93,0x01},\r
+{0x8a94,0xc3},\r
+{0x8a95,0x92},\r
+{0x8a96,0x09},\r
+{0x8a97,0x30},\r
+{0x8a98,0x02},\r
+{0x8a99,0x06},\r
+{0x8a9a,0x30},\r
+{0x8a9b,0x33},\r
+{0x8a9c,0x03},\r
+{0x8a9d,0xd3},\r
+{0x8a9e,0x80},\r
+{0x8a9f,0x01},\r
+{0x8aa0,0xc3},\r
+{0x8aa1,0x92},\r
+{0x8aa2,0x0a},\r
+{0x8aa3,0x30},\r
+{0x8aa4,0x33},\r
+{0x8aa5,0x0c},\r
+{0x8aa6,0x30},\r
+{0x8aa7,0x03},\r
+{0x8aa8,0x09},\r
+{0x8aa9,0x20},\r
+{0x8aaa,0x02},\r
+{0x8aab,0x06},\r
+{0x8aac,0x20},\r
+{0x8aad,0x01},\r
+{0x8aae,0x03},\r
+{0x8aaf,0xd3},\r
+{0x8ab0,0x80},\r
+{0x8ab1,0x01},\r
+{0x8ab2,0xc3},\r
+{0x8ab3,0x92},\r
+{0x8ab4,0x0b},\r
+{0x8ab5,0x90},\r
+{0x8ab6,0x30},\r
+{0x8ab7,0x01},\r
+{0x8ab8,0xe0},\r
+{0x8ab9,0x44},\r
+{0x8aba,0x40},\r
+{0x8abb,0xf0},\r
+{0x8abc,0xe0},\r
+{0x8abd,0x54},\r
+{0x8abe,0xbf},\r
+{0x8abf,0xf0},\r
+{0x8ac0,0xe5},\r
+{0x8ac1,0x32},\r
+{0x8ac2,0x30},\r
+{0x8ac3,0xe1},\r
+{0x8ac4,0x14},\r
+{0x8ac5,0x30},\r
+{0x8ac6,0x34},\r
+{0x8ac7,0x11},\r
+{0x8ac8,0x90},\r
+{0x8ac9,0x30},\r
+{0x8aca,0x22},\r
+{0x8acb,0xe0},\r
+{0x8acc,0xf5},\r
+{0x8acd,0x08},\r
+{0x8ace,0xe4},\r
+{0x8acf,0xf0},\r
+{0x8ad0,0x30},\r
+{0x8ad1,0x00},\r
+{0x8ad2,0x03},\r
+{0x8ad3,0xd3},\r
+{0x8ad4,0x80},\r
+{0x8ad5,0x01},\r
+{0x8ad6,0xc3},\r
+{0x8ad7,0x92},\r
+{0x8ad8,0x08},\r
+{0x8ad9,0xe5},\r
+{0x8ada,0x32},\r
+{0x8adb,0x30},\r
+{0x8adc,0xe5},\r
+{0x8add,0x12},\r
+{0x8ade,0x90},\r
+{0x8adf,0x56},\r
+{0x8ae0,0xa1},\r
+{0x8ae1,0xe0},\r
+{0x8ae2,0xf5},\r
+{0x8ae3,0x09},\r
+{0x8ae4,0x30},\r
+{0x8ae5,0x31},\r
+{0x8ae6,0x09},\r
+{0x8ae7,0x30},\r
+{0x8ae8,0x05},\r
+{0x8ae9,0x03},\r
+{0x8aea,0xd3},\r
+{0x8aeb,0x80},\r
+{0x8aec,0x01},\r
+{0x8aed,0xc3},\r
+{0x8aee,0x92},\r
+{0x8aef,0x0d},\r
+{0x8af0,0x90},\r
+{0x8af1,0x3f},\r
+{0x8af2,0x0c},\r
+{0x8af3,0xe5},\r
+{0x8af4,0x32},\r
+{0x8af5,0xf0},\r
+{0x8af6,0xd0},\r
+{0x8af7,0xd0},\r
+{0x8af8,0xd0},\r
+{0x8af9,0x82},\r
+{0x8afa,0xd0},\r
+{0x8afb,0x83},\r
+{0x8afc,0xd0},\r
+{0x8afd,0xe0},\r
+{0x8afe,0x32},\r
+{0x8aff,0x90},\r
+{0x8b00,0x0e},\r
+{0x8b01,0x7e},\r
+{0x8b02,0xe4},\r
+{0x8b03,0x93},\r
+{0x8b04,0xfe},\r
+{0x8b05,0x74},\r
+{0x8b06,0x01},\r
+{0x8b07,0x93},\r
+{0x8b08,0xff},\r
+{0x8b09,0xc3},\r
+{0x8b0a,0x90},\r
+{0x8b0b,0x0e},\r
+{0x8b0c,0x7c},\r
+{0x8b0d,0x74},\r
+{0x8b0e,0x01},\r
+{0x8b0f,0x93},\r
+{0x8b10,0x9f},\r
+{0x8b11,0xff},\r
+{0x8b12,0xe4},\r
+{0x8b13,0x93},\r
+{0x8b14,0x9e},\r
+{0x8b15,0xfe},\r
+{0x8b16,0xe4},\r
+{0x8b17,0x8f},\r
+{0x8b18,0x3b},\r
+{0x8b19,0x8e},\r
+{0x8b1a,0x3a},\r
+{0x8b1b,0xf5},\r
+{0x8b1c,0x39},\r
+{0x8b1d,0xf5},\r
+{0x8b1e,0x38},\r
+{0x8b1f,0xab},\r
+{0x8b20,0x3b},\r
+{0x8b21,0xaa},\r
+{0x8b22,0x3a},\r
+{0x8b23,0xa9},\r
+{0x8b24,0x39},\r
+{0x8b25,0xa8},\r
+{0x8b26,0x38},\r
+{0x8b27,0xaf},\r
+{0x8b28,0x4b},\r
+{0x8b29,0xfc},\r
+{0x8b2a,0xfd},\r
+{0x8b2b,0xfe},\r
+{0x8b2c,0x12},\r
+{0x8b2d,0x05},\r
+{0x8b2e,0x28},\r
+{0x8b2f,0x12},\r
+{0x8b30,0x0d},\r
+{0x8b31,0xe1},\r
+{0x8b32,0xe4},\r
+{0x8b33,0x7b},\r
+{0x8b34,0xff},\r
+{0x8b35,0xfa},\r
+{0x8b36,0xf9},\r
+{0x8b37,0xf8},\r
+{0x8b38,0x12},\r
+{0x8b39,0x05},\r
+{0x8b3a,0xb3},\r
+{0x8b3b,0x12},\r
+{0x8b3c,0x0d},\r
+{0x8b3d,0xe1},\r
+{0x8b3e,0x90},\r
+{0x8b3f,0x0e},\r
+{0x8b40,0x69},\r
+{0x8b41,0xe4},\r
+{0x8b42,0x12},\r
+{0x8b43,0x0d},\r
+{0x8b44,0xf6},\r
+{0x8b45,0x12},\r
+{0x8b46,0x0d},\r
+{0x8b47,0xe1},\r
+{0x8b48,0xe4},\r
+{0x8b49,0x85},\r
+{0x8b4a,0x4a},\r
+{0x8b4b,0x37},\r
+{0x8b4c,0xf5},\r
+{0x8b4d,0x36},\r
+{0x8b4e,0xf5},\r
+{0x8b4f,0x35},\r
+{0x8b50,0xf5},\r
+{0x8b51,0x34},\r
+{0x8b52,0xaf},\r
+{0x8b53,0x37},\r
+{0x8b54,0xae},\r
+{0x8b55,0x36},\r
+{0x8b56,0xad},\r
+{0x8b57,0x35},\r
+{0x8b58,0xac},\r
+{0x8b59,0x34},\r
+{0x8b5a,0xa3},\r
+{0x8b5b,0x12},\r
+{0x8b5c,0x0d},\r
+{0x8b5d,0xf6},\r
+{0x8b5e,0x8f},\r
+{0x8b5f,0x37},\r
+{0x8b60,0x8e},\r
+{0x8b61,0x36},\r
+{0x8b62,0x8d},\r
+{0x8b63,0x35},\r
+{0x8b64,0x8c},\r
+{0x8b65,0x34},\r
+{0x8b66,0xe5},\r
+{0x8b67,0x3b},\r
+{0x8b68,0x45},\r
+{0x8b69,0x37},\r
+{0x8b6a,0xf5},\r
+{0x8b6b,0x3b},\r
+{0x8b6c,0xe5},\r
+{0x8b6d,0x3a},\r
+{0x8b6e,0x45},\r
+{0x8b6f,0x36},\r
+{0x8b70,0xf5},\r
+{0x8b71,0x3a},\r
+{0x8b72,0xe5},\r
+{0x8b73,0x39},\r
+{0x8b74,0x45},\r
+{0x8b75,0x35},\r
+{0x8b76,0xf5},\r
+{0x8b77,0x39},\r
+{0x8b78,0xe5},\r
+{0x8b79,0x38},\r
+{0x8b7a,0x45},\r
+{0x8b7b,0x34},\r
+{0x8b7c,0xf5},\r
+{0x8b7d,0x38},\r
+{0x8b7e,0xe4},\r
+{0x8b7f,0xf5},\r
+{0x8b80,0x22},\r
+{0x8b81,0xf5},\r
+{0x8b82,0x23},\r
+{0x8b83,0x85},\r
+{0x8b84,0x3b},\r
+{0x8b85,0x31},\r
+{0x8b86,0x85},\r
+{0x8b87,0x3a},\r
+{0x8b88,0x30},\r
+{0x8b89,0x85},\r
+{0x8b8a,0x39},\r
+{0x8b8b,0x2f},\r
+{0x8b8c,0x85},\r
+{0x8b8d,0x38},\r
+{0x8b8e,0x2e},\r
+{0x8b8f,0x02},\r
+{0x8b90,0x0f},\r
+{0x8b91,0x46},\r
+{0x8b92,0xe0},\r
+{0x8b93,0xa3},\r
+{0x8b94,0xe0},\r
+{0x8b95,0x75},\r
+{0x8b96,0xf0},\r
+{0x8b97,0x02},\r
+{0x8b98,0xa4},\r
+{0x8b99,0xff},\r
+{0x8b9a,0xae},\r
+{0x8b9b,0xf0},\r
+{0x8b9c,0xc3},\r
+{0x8b9d,0x08},\r
+{0x8b9e,0xe6},\r
+{0x8b9f,0x9f},\r
+{0x8ba0,0xf6},\r
+{0x8ba1,0x18},\r
+{0x8ba2,0xe6},\r
+{0x8ba3,0x9e},\r
+{0x8ba4,0xf6},\r
+{0x8ba5,0x22},\r
+{0x8ba6,0xff},\r
+{0x8ba7,0xe5},\r
+{0x8ba8,0xf0},\r
+{0x8ba9,0x34},\r
+{0x8baa,0x60},\r
+{0x8bab,0x8f},\r
+{0x8bac,0x82},\r
+{0x8bad,0xf5},\r
+{0x8bae,0x83},\r
+{0x8baf,0xec},\r
+{0x8bb0,0xf0},\r
+{0x8bb1,0x22},\r
+{0x8bb2,0x78},\r
+{0x8bb3,0x52},\r
+{0x8bb4,0x7e},\r
+{0x8bb5,0x00},\r
+{0x8bb6,0xe6},\r
+{0x8bb7,0xfc},\r
+{0x8bb8,0x08},\r
+{0x8bb9,0xe6},\r
+{0x8bba,0xfd},\r
+{0x8bbb,0x02},\r
+{0x8bbc,0x04},\r
+{0x8bbd,0xc1},\r
+{0x8bbe,0xe4},\r
+{0x8bbf,0xfc},\r
+{0x8bc0,0xfd},\r
+{0x8bc1,0x12},\r
+{0x8bc2,0x06},\r
+{0x8bc3,0x99},\r
+{0x8bc4,0x78},\r
+{0x8bc5,0x5c},\r
+{0x8bc6,0xe6},\r
+{0x8bc7,0xc3},\r
+{0x8bc8,0x13},\r
+{0x8bc9,0xfe},\r
+{0x8bca,0x08},\r
+{0x8bcb,0xe6},\r
+{0x8bcc,0x13},\r
+{0x8bcd,0x22},\r
+{0x8bce,0x78},\r
+{0x8bcf,0x52},\r
+{0x8bd0,0xe6},\r
+{0x8bd1,0xfe},\r
+{0x8bd2,0x08},\r
+{0x8bd3,0xe6},\r
+{0x8bd4,0xff},\r
+{0x8bd5,0xe4},\r
+{0x8bd6,0xfc},\r
+{0x8bd7,0xfd},\r
+{0x8bd8,0x22},\r
+{0x8bd9,0xe7},\r
+{0x8bda,0xc4},\r
+{0x8bdb,0xf8},\r
+{0x8bdc,0x54},\r
+{0x8bdd,0xf0},\r
+{0x8bde,0xc8},\r
+{0x8bdf,0x68},\r
+{0x8be0,0xf7},\r
+{0x8be1,0x09},\r
+{0x8be2,0xe7},\r
+{0x8be3,0xc4},\r
+{0x8be4,0x54},\r
+{0x8be5,0x0f},\r
+{0x8be6,0x48},\r
+{0x8be7,0xf7},\r
+{0x8be8,0x22},\r
+{0x8be9,0xe6},\r
+{0x8bea,0xfc},\r
+{0x8beb,0xed},\r
+{0x8bec,0x75},\r
+{0x8bed,0xf0},\r
+{0x8bee,0x04},\r
+{0x8bef,0xa4},\r
+{0x8bf0,0x22},\r
+{0x8bf1,0x12},\r
+{0x8bf2,0x06},\r
+{0x8bf3,0x7c},\r
+{0x8bf4,0x8f},\r
+{0x8bf5,0x48},\r
+{0x8bf6,0x8e},\r
+{0x8bf7,0x47},\r
+{0x8bf8,0x8d},\r
+{0x8bf9,0x46},\r
+{0x8bfa,0x8c},\r
+{0x8bfb,0x45},\r
+{0x8bfc,0x22},\r
+{0x8bfd,0xe0},\r
+{0x8bfe,0xfe},\r
+{0x8bff,0xa3},\r
+{0x8c00,0xe0},\r
+{0x8c01,0xfd},\r
+{0x8c02,0xee},\r
+{0x8c03,0xf6},\r
+{0x8c04,0xed},\r
+{0x8c05,0x08},\r
+{0x8c06,0xf6},\r
+{0x8c07,0x22},\r
+{0x8c08,0x13},\r
+{0x8c09,0xff},\r
+{0x8c0a,0xc3},\r
+{0x8c0b,0xe6},\r
+{0x8c0c,0x9f},\r
+{0x8c0d,0xff},\r
+{0x8c0e,0x18},\r
+{0x8c0f,0xe6},\r
+{0x8c10,0x9e},\r
+{0x8c11,0xfe},\r
+{0x8c12,0x22},\r
+{0x8c13,0xe6},\r
+{0x8c14,0xc3},\r
+{0x8c15,0x13},\r
+{0x8c16,0xf7},\r
+{0x8c17,0x08},\r
+{0x8c18,0xe6},\r
+{0x8c19,0x13},\r
+{0x8c1a,0x09},\r
+{0x8c1b,0xf7},\r
+{0x8c1c,0x22},\r
+{0x8c1d,0xad},\r
+{0x8c1e,0x39},\r
+{0x8c1f,0xac},\r
+{0x8c20,0x38},\r
+{0x8c21,0xfa},\r
+{0x8c22,0xf9},\r
+{0x8c23,0xf8},\r
+{0x8c24,0x12},\r
+{0x8c25,0x05},\r
+{0x8c26,0x28},\r
+{0x8c27,0x8f},\r
+{0x8c28,0x3b},\r
+{0x8c29,0x8e},\r
+{0x8c2a,0x3a},\r
+{0x8c2b,0x8d},\r
+{0x8c2c,0x39},\r
+{0x8c2d,0x8c},\r
+{0x8c2e,0x38},\r
+{0x8c2f,0xab},\r
+{0x8c30,0x37},\r
+{0x8c31,0xaa},\r
+{0x8c32,0x36},\r
+{0x8c33,0xa9},\r
+{0x8c34,0x35},\r
+{0x8c35,0xa8},\r
+{0x8c36,0x34},\r
+{0x8c37,0x22},\r
+{0x8c38,0x93},\r
+{0x8c39,0xff},\r
+{0x8c3a,0xe4},\r
+{0x8c3b,0xfc},\r
+{0x8c3c,0xfd},\r
+{0x8c3d,0xfe},\r
+{0x8c3e,0x12},\r
+{0x8c3f,0x05},\r
+{0x8c40,0x28},\r
+{0x8c41,0x8f},\r
+{0x8c42,0x37},\r
+{0x8c43,0x8e},\r
+{0x8c44,0x36},\r
+{0x8c45,0x8d},\r
+{0x8c46,0x35},\r
+{0x8c47,0x8c},\r
+{0x8c48,0x34},\r
+{0x8c49,0x22},\r
+{0x8c4a,0x78},\r
+{0x8c4b,0x84},\r
+{0x8c4c,0xe6},\r
+{0x8c4d,0xfe},\r
+{0x8c4e,0x08},\r
+{0x8c4f,0xe6},\r
+{0x8c50,0xff},\r
+{0x8c51,0xe4},\r
+{0x8c52,0x8f},\r
+{0x8c53,0x37},\r
+{0x8c54,0x8e},\r
+{0x8c55,0x36},\r
+{0x8c56,0xf5},\r
+{0x8c57,0x35},\r
+{0x8c58,0xf5},\r
+{0x8c59,0x34},\r
+{0x8c5a,0x22},\r
+{0x8c5b,0x90},\r
+{0x8c5c,0x0e},\r
+{0x8c5d,0x8c},\r
+{0x8c5e,0xe4},\r
+{0x8c5f,0x93},\r
+{0x8c60,0x25},\r
+{0x8c61,0xe0},\r
+{0x8c62,0x24},\r
+{0x8c63,0x0a},\r
+{0x8c64,0xf8},\r
+{0x8c65,0xe6},\r
+{0x8c66,0xfe},\r
+{0x8c67,0x08},\r
+{0x8c68,0xe6},\r
+{0x8c69,0xff},\r
+{0x8c6a,0x22},\r
+{0x8c6b,0xe6},\r
+{0x8c6c,0xfe},\r
+{0x8c6d,0x08},\r
+{0x8c6e,0xe6},\r
+{0x8c6f,0xff},\r
+{0x8c70,0xe4},\r
+{0x8c71,0x8f},\r
+{0x8c72,0x3b},\r
+{0x8c73,0x8e},\r
+{0x8c74,0x3a},\r
+{0x8c75,0xf5},\r
+{0x8c76,0x39},\r
+{0x8c77,0xf5},\r
+{0x8c78,0x38},\r
+{0x8c79,0x22},\r
+{0x8c7a,0x78},\r
+{0x8c7b,0x4e},\r
+{0x8c7c,0xe6},\r
+{0x8c7d,0xfe},\r
+{0x8c7e,0x08},\r
+{0x8c7f,0xe6},\r
+{0x8c80,0xff},\r
+{0x8c81,0x22},\r
+{0x8c82,0xef},\r
+{0x8c83,0x25},\r
+{0x8c84,0xe0},\r
+{0x8c85,0x24},\r
+{0x8c86,0x4e},\r
+{0x8c87,0xf8},\r
+{0x8c88,0xe6},\r
+{0x8c89,0xfc},\r
+{0x8c8a,0x08},\r
+{0x8c8b,0xe6},\r
+{0x8c8c,0xfd},\r
+{0x8c8d,0x22},\r
+{0x8c8e,0x78},\r
+{0x8c8f,0x89},\r
+{0x8c90,0xef},\r
+{0x8c91,0x26},\r
+{0x8c92,0xf6},\r
+{0x8c93,0x18},\r
+{0x8c94,0xe4},\r
+{0x8c95,0x36},\r
+{0x8c96,0xf6},\r
+{0x8c97,0x22},\r
+{0x8c98,0x75},\r
+{0x8c99,0x89},\r
+{0x8c9a,0x03},\r
+{0x8c9b,0x75},\r
+{0x8c9c,0xa8},\r
+{0x8c9d,0x01},\r
+{0x8c9e,0x75},\r
+{0x8c9f,0xb8},\r
+{0x8ca0,0x04},\r
+{0x8ca1,0x75},\r
+{0x8ca2,0x34},\r
+{0x8ca3,0xff},\r
+{0x8ca4,0x75},\r
+{0x8ca5,0x35},\r
+{0x8ca6,0x0e},\r
+{0x8ca7,0x75},\r
+{0x8ca8,0x36},\r
+{0x8ca9,0x15},\r
+{0x8caa,0x75},\r
+{0x8cab,0x37},\r
+{0x8cac,0x0d},\r
+{0x8cad,0x12},\r
+{0x8cae,0x0e},\r
+{0x8caf,0x9a},\r
+{0x8cb0,0x12},\r
+{0x8cb1,0x00},\r
+{0x8cb2,0x09},\r
+{0x8cb3,0x12},\r
+{0x8cb4,0x0f},\r
+{0x8cb5,0x16},\r
+{0x8cb6,0x12},\r
+{0x8cb7,0x00},\r
+{0x8cb8,0x06},\r
+{0x8cb9,0xd2},\r
+{0x8cba,0x00},\r
+{0x8cbb,0xd2},\r
+{0x8cbc,0x34},\r
+{0x8cbd,0xd2},\r
+{0x8cbe,0xaf},\r
+{0x8cbf,0x75},\r
+{0x8cc0,0x34},\r
+{0x8cc1,0xff},\r
+{0x8cc2,0x75},\r
+{0x8cc3,0x35},\r
+{0x8cc4,0x0e},\r
+{0x8cc5,0x75},\r
+{0x8cc6,0x36},\r
+{0x8cc7,0x49},\r
+{0x8cc8,0x75},\r
+{0x8cc9,0x37},\r
+{0x8cca,0x03},\r
+{0x8ccb,0x12},\r
+{0x8ccc,0x0e},\r
+{0x8ccd,0x9a},\r
+{0x8cce,0x30},\r
+{0x8ccf,0x08},\r
+{0x8cd0,0x09},\r
+{0x8cd1,0xc2},\r
+{0x8cd2,0x34},\r
+{0x8cd3,0x12},\r
+{0x8cd4,0x08},\r
+{0x8cd5,0xcb},\r
+{0x8cd6,0xc2},\r
+{0x8cd7,0x08},\r
+{0x8cd8,0xd2},\r
+{0x8cd9,0x34},\r
+{0x8cda,0x30},\r
+{0x8cdb,0x0b},\r
+{0x8cdc,0x09},\r
+{0x8cdd,0xc2},\r
+{0x8cde,0x36},\r
+{0x8cdf,0x12},\r
+{0x8ce0,0x02},\r
+{0x8ce1,0x6c},\r
+{0x8ce2,0xc2},\r
+{0x8ce3,0x0b},\r
+{0x8ce4,0xd2},\r
+{0x8ce5,0x36},\r
+{0x8ce6,0x30},\r
+{0x8ce7,0x09},\r
+{0x8ce8,0x09},\r
+{0x8ce9,0xc2},\r
+{0x8cea,0x36},\r
+{0x8ceb,0x12},\r
+{0x8cec,0x00},\r
+{0x8ced,0x0e},\r
+{0x8cee,0xc2},\r
+{0x8cef,0x09},\r
+{0x8cf0,0xd2},\r
+{0x8cf1,0x36},\r
+{0x8cf2,0x30},\r
+{0x8cf3,0x0e},\r
+{0x8cf4,0x03},\r
+{0x8cf5,0x12},\r
+{0x8cf6,0x06},\r
+{0x8cf7,0xd7},\r
+{0x8cf8,0x30},\r
+{0x8cf9,0x35},\r
+{0x8cfa,0xd3},\r
+{0x8cfb,0x90},\r
+{0x8cfc,0x30},\r
+{0x8cfd,0x29},\r
+{0x8cfe,0xe5},\r
+{0x8cff,0x1e},\r
+{0x8d00,0xf0},\r
+{0x8d01,0xb4},\r
+{0x8d02,0x10},\r
+{0x8d03,0x05},\r
+{0x8d04,0x90},\r
+{0x8d05,0x30},\r
+{0x8d06,0x23},\r
+{0x8d07,0xe4},\r
+{0x8d08,0xf0},\r
+{0x8d09,0xc2},\r
+{0x8d0a,0x35},\r
+{0x8d0b,0x80},\r
+{0x8d0c,0xc1},\r
+{0x8d0d,0xe4},\r
+{0x8d0e,0xf5},\r
+{0x8d0f,0x4b},\r
+{0x8d10,0x90},\r
+{0x8d11,0x0e},\r
+{0x8d12,0x7a},\r
+{0x8d13,0x93},\r
+{0x8d14,0xff},\r
+{0x8d15,0xe4},\r
+{0x8d16,0x8f},\r
+{0x8d17,0x37},\r
+{0x8d18,0xf5},\r
+{0x8d19,0x36},\r
+{0x8d1a,0xf5},\r
+{0x8d1b,0x35},\r
+{0x8d1c,0xf5},\r
+{0x8d1d,0x34},\r
+{0x8d1e,0xaf},\r
+{0x8d1f,0x37},\r
+{0x8d20,0xae},\r
+{0x8d21,0x36},\r
+{0x8d22,0xad},\r
+{0x8d23,0x35},\r
+{0x8d24,0xac},\r
+{0x8d25,0x34},\r
+{0x8d26,0x90},\r
+{0x8d27,0x0e},\r
+{0x8d28,0x6a},\r
+{0x8d29,0x12},\r
+{0x8d2a,0x0d},\r
+{0x8d2b,0xf6},\r
+{0x8d2c,0x8f},\r
+{0x8d2d,0x37},\r
+{0x8d2e,0x8e},\r
+{0x8d2f,0x36},\r
+{0x8d30,0x8d},\r
+{0x8d31,0x35},\r
+{0x8d32,0x8c},\r
+{0x8d33,0x34},\r
+{0x8d34,0x90},\r
+{0x8d35,0x0e},\r
+{0x8d36,0x72},\r
+{0x8d37,0x12},\r
+{0x8d38,0x06},\r
+{0x8d39,0x7c},\r
+{0x8d3a,0xef},\r
+{0x8d3b,0x45},\r
+{0x8d3c,0x37},\r
+{0x8d3d,0xf5},\r
+{0x8d3e,0x37},\r
+{0x8d3f,0xee},\r
+{0x8d40,0x45},\r
+{0x8d41,0x36},\r
+{0x8d42,0xf5},\r
+{0x8d43,0x36},\r
+{0x8d44,0xed},\r
+{0x8d45,0x45},\r
+{0x8d46,0x35},\r
+{0x8d47,0xf5},\r
+{0x8d48,0x35},\r
+{0x8d49,0xec},\r
+{0x8d4a,0x45},\r
+{0x8d4b,0x34},\r
+{0x8d4c,0xf5},\r
+{0x8d4d,0x34},\r
+{0x8d4e,0xe4},\r
+{0x8d4f,0xf5},\r
+{0x8d50,0x22},\r
+{0x8d51,0xf5},\r
+{0x8d52,0x23},\r
+{0x8d53,0x85},\r
+{0x8d54,0x37},\r
+{0x8d55,0x31},\r
+{0x8d56,0x85},\r
+{0x8d57,0x36},\r
+{0x8d58,0x30},\r
+{0x8d59,0x85},\r
+{0x8d5a,0x35},\r
+{0x8d5b,0x2f},\r
+{0x8d5c,0x85},\r
+{0x8d5d,0x34},\r
+{0x8d5e,0x2e},\r
+{0x8d5f,0x12},\r
+{0x8d60,0x0f},\r
+{0x8d61,0x46},\r
+{0x8d62,0xe4},\r
+{0x8d63,0xf5},\r
+{0x8d64,0x22},\r
+{0x8d65,0xf5},\r
+{0x8d66,0x23},\r
+{0x8d67,0x90},\r
+{0x8d68,0x0e},\r
+{0x8d69,0x72},\r
+{0x8d6a,0x12},\r
+{0x8d6b,0x0d},\r
+{0x8d6c,0xea},\r
+{0x8d6d,0x12},\r
+{0x8d6e,0x0f},\r
+{0x8d6f,0x46},\r
+{0x8d70,0xe4},\r
+{0x8d71,0xf5},\r
+{0x8d72,0x22},\r
+{0x8d73,0xf5},\r
+{0x8d74,0x23},\r
+{0x8d75,0x90},\r
+{0x8d76,0x0e},\r
+{0x8d77,0x6e},\r
+{0x8d78,0x12},\r
+{0x8d79,0x0d},\r
+{0x8d7a,0xea},\r
+{0x8d7b,0x02},\r
+{0x8d7c,0x0f},\r
+{0x8d7d,0x46},\r
+{0x8d7e,0xe5},\r
+{0x8d7f,0x40},\r
+{0x8d80,0x24},\r
+{0x8d81,0xf2},\r
+{0x8d82,0xf5},\r
+{0x8d83,0x37},\r
+{0x8d84,0xe5},\r
+{0x8d85,0x3f},\r
+{0x8d86,0x34},\r
+{0x8d87,0x43},\r
+{0x8d88,0xf5},\r
+{0x8d89,0x36},\r
+{0x8d8a,0xe5},\r
+{0x8d8b,0x3e},\r
+{0x8d8c,0x34},\r
+{0x8d8d,0xa2},\r
+{0x8d8e,0xf5},\r
+{0x8d8f,0x35},\r
+{0x8d90,0xe5},\r
+{0x8d91,0x3d},\r
+{0x8d92,0x34},\r
+{0x8d93,0x28},\r
+{0x8d94,0xf5},\r
+{0x8d95,0x34},\r
+{0x8d96,0xe5},\r
+{0x8d97,0x37},\r
+{0x8d98,0xff},\r
+{0x8d99,0xe4},\r
+{0x8d9a,0xfe},\r
+{0x8d9b,0xfd},\r
+{0x8d9c,0xfc},\r
+{0x8d9d,0x78},\r
+{0x8d9e,0x18},\r
+{0x8d9f,0x12},\r
+{0x8da0,0x06},\r
+{0x8da1,0x69},\r
+{0x8da2,0x8f},\r
+{0x8da3,0x40},\r
+{0x8da4,0x8e},\r
+{0x8da5,0x3f},\r
+{0x8da6,0x8d},\r
+{0x8da7,0x3e},\r
+{0x8da8,0x8c},\r
+{0x8da9,0x3d},\r
+{0x8daa,0xe5},\r
+{0x8dab,0x37},\r
+{0x8dac,0x54},\r
+{0x8dad,0xa0},\r
+{0x8dae,0xff},\r
+{0x8daf,0xe5},\r
+{0x8db0,0x36},\r
+{0x8db1,0xfe},\r
+{0x8db2,0xe4},\r
+{0x8db3,0xfd},\r
+{0x8db4,0xfc},\r
+{0x8db5,0x78},\r
+{0x8db6,0x07},\r
+{0x8db7,0x12},\r
+{0x8db8,0x06},\r
+{0x8db9,0x56},\r
+{0x8dba,0x78},\r
+{0x8dbb,0x10},\r
+{0x8dbc,0x12},\r
+{0x8dbd,0x0f},\r
+{0x8dbe,0x9a},\r
+{0x8dbf,0xe4},\r
+{0x8dc0,0xff},\r
+{0x8dc1,0xfe},\r
+{0x8dc2,0xe5},\r
+{0x8dc3,0x35},\r
+{0x8dc4,0xfd},\r
+{0x8dc5,0xe4},\r
+{0x8dc6,0xfc},\r
+{0x8dc7,0x78},\r
+{0x8dc8,0x0e},\r
+{0x8dc9,0x12},\r
+{0x8dca,0x06},\r
+{0x8dcb,0x56},\r
+{0x8dcc,0x12},\r
+{0x8dcd,0x0f},\r
+{0x8dce,0x9d},\r
+{0x8dcf,0xe4},\r
+{0x8dd0,0xff},\r
+{0x8dd1,0xfe},\r
+{0x8dd2,0xfd},\r
+{0x8dd3,0xe5},\r
+{0x8dd4,0x34},\r
+{0x8dd5,0xfc},\r
+{0x8dd6,0x78},\r
+{0x8dd7,0x18},\r
+{0x8dd8,0x12},\r
+{0x8dd9,0x06},\r
+{0x8dda,0x56},\r
+{0x8ddb,0x78},\r
+{0x8ddc,0x08},\r
+{0x8ddd,0x12},\r
+{0x8dde,0x0f},\r
+{0x8ddf,0x9a},\r
+{0x8de0,0x22},\r
+{0x8de1,0x8f},\r
+{0x8de2,0x3b},\r
+{0x8de3,0x8e},\r
+{0x8de4,0x3a},\r
+{0x8de5,0x8d},\r
+{0x8de6,0x39},\r
+{0x8de7,0x8c},\r
+{0x8de8,0x38},\r
+{0x8de9,0x22},\r
+{0x8dea,0x12},\r
+{0x8deb,0x06},\r
+{0x8dec,0x7c},\r
+{0x8ded,0x8f},\r
+{0x8dee,0x31},\r
+{0x8def,0x8e},\r
+{0x8df0,0x30},\r
+{0x8df1,0x8d},\r
+{0x8df2,0x2f},\r
+{0x8df3,0x8c},\r
+{0x8df4,0x2e},\r
+{0x8df5,0x22},\r
+{0x8df6,0x93},\r
+{0x8df7,0xf9},\r
+{0x8df8,0xf8},\r
+{0x8df9,0x02},\r
+{0x8dfa,0x06},\r
+{0x8dfb,0x69},\r
+{0x8dfc,0x00},\r
+{0x8dfd,0x00},\r
+{0x8dfe,0x00},\r
+{0x8dff,0x00},\r
+{0x8e00,0x12},\r
+{0x8e01,0x01},\r
+{0x8e02,0x17},\r
+{0x8e03,0x08},\r
+{0x8e04,0x31},\r
+{0x8e05,0x15},\r
+{0x8e06,0x53},\r
+{0x8e07,0x54},\r
+{0x8e08,0x44},\r
+{0x8e09,0x20},\r
+{0x8e0a,0x20},\r
+{0x8e0b,0x20},\r
+{0x8e0c,0x20},\r
+{0x8e0d,0x20},\r
+{0x8e0e,0x13},\r
+{0x8e0f,0x01},\r
+{0x8e10,0x10},\r
+{0x8e11,0x01},\r
+{0x8e12,0x56},\r
+{0x8e13,0x40},\r
+{0x8e14,0x1a},\r
+{0x8e15,0x30},\r
+{0x8e16,0x29},\r
+{0x8e17,0x7e},\r
+{0x8e18,0x00},\r
+{0x8e19,0x30},\r
+{0x8e1a,0x04},\r
+{0x8e1b,0x20},\r
+{0x8e1c,0xdf},\r
+{0x8e1d,0x30},\r
+{0x8e1e,0x05},\r
+{0x8e1f,0x40},\r
+{0x8e20,0xbf},\r
+{0x8e21,0x50},\r
+{0x8e22,0x03},\r
+{0x8e23,0x00},\r
+{0x8e24,0xfd},\r
+{0x8e25,0x50},\r
+{0x8e26,0x27},\r
+{0x8e27,0x01},\r
+{0x8e28,0xfe},\r
+{0x8e29,0x60},\r
+{0x8e2a,0x00},\r
+{0x8e2b,0x11},\r
+{0x8e2c,0x00},\r
+{0x8e2d,0x3f},\r
+{0x8e2e,0x05},\r
+{0x8e2f,0x30},\r
+{0x8e30,0x00},\r
+{0x8e31,0x3f},\r
+{0x8e32,0x06},\r
+{0x8e33,0x22},\r
+{0x8e34,0x00},\r
+{0x8e35,0x3f},\r
+{0x8e36,0x01},\r
+{0x8e37,0x2a},\r
+{0x8e38,0x00},\r
+{0x8e39,0x3f},\r
+{0x8e3a,0x02},\r
+{0x8e3b,0x00},\r
+{0x8e3c,0x00},\r
+{0x8e3d,0x36},\r
+{0x8e3e,0x06},\r
+{0x8e3f,0x07},\r
+{0x8e40,0x00},\r
+{0x8e41,0x3f},\r
+{0x8e42,0x0b},\r
+{0x8e43,0x0f},\r
+{0x8e44,0xf0},\r
+{0x8e45,0x00},\r
+{0x8e46,0x00},\r
+{0x8e47,0x00},\r
+{0x8e48,0x00},\r
+{0x8e49,0x30},\r
+{0x8e4a,0x01},\r
+{0x8e4b,0x40},\r
+{0x8e4c,0xbf},\r
+{0x8e4d,0x30},\r
+{0x8e4e,0x01},\r
+{0x8e4f,0x00},\r
+{0x8e50,0xbf},\r
+{0x8e51,0x30},\r
+{0x8e52,0x29},\r
+{0x8e53,0x70},\r
+{0x8e54,0x00},\r
+{0x8e55,0x3a},\r
+{0x8e56,0x00},\r
+{0x8e57,0x00},\r
+{0x8e58,0xff},\r
+{0x8e59,0x3a},\r
+{0x8e5a,0x00},\r
+{0x8e5b,0x00},\r
+{0x8e5c,0xff},\r
+{0x8e5d,0x36},\r
+{0x8e5e,0x03},\r
+{0x8e5f,0x36},\r
+{0x8e60,0x02},\r
+{0x8e61,0x41},\r
+{0x8e62,0x44},\r
+{0x8e63,0x58},\r
+{0x8e64,0x20},\r
+{0x8e65,0x18},\r
+{0x8e66,0x10},\r
+{0x8e67,0x0a},\r
+{0x8e68,0x04},\r
+{0x8e69,0x04},\r
+{0x8e6a,0x00},\r
+{0x8e6b,0x03},\r
+{0x8e6c,0xff},\r
+{0x8e6d,0x64},\r
+{0x8e6e,0x00},\r
+{0x8e6f,0x00},\r
+{0x8e70,0x80},\r
+{0x8e71,0x00},\r
+{0x8e72,0x00},\r
+{0x8e73,0x00},\r
+{0x8e74,0x00},\r
+{0x8e75,0x00},\r
+{0x8e76,0x00},\r
+{0x8e77,0x02},\r
+{0x8e78,0x04},\r
+{0x8e79,0x06},\r
+{0x8e7a,0x06},\r
+{0x8e7b,0x00},\r
+{0x8e7c,0x02},\r
+{0x8e7d,0x60},//cc},\r
+{0x8e7e,0x00},\r
+{0x8e7f,0x70},\r
+{0x8e80,0x50},\r
+{0x8e81,0x3c},\r
+{0x8e82,0x28},\r
+{0x8e83,0x1e},\r
+{0x8e84,0x10},\r
+{0x8e85,0x10},\r
+{0x8e86,0x50},\r
+{0x8e87,0x2d},\r
+{0x8e88,0x28},\r
+{0x8e89,0x16},\r
+{0x8e8a,0x10},\r
+{0x8e8b,0x10},\r
+{0x8e8c,0x02},\r
+{0x8e8d,0x00},\r
+{0x8e8e,0x10},\r
+{0x8e8f,0x30},\r
+{0x8e90,0x0a},\r
+{0x8e91,0x04},\r
+{0x8e92,0x05},\r
+{0x8e93,0x08},\r
+{0x8e94,0x06},\r
+{0x8e95,0x05},\r
+{0x8e96,0x00},\r
+{0x8e97,0xa5},\r
+{0x8e98,0x5a},\r
+{0x8e99,0x00},\r
+{0x8e9a,0xae},\r
+{0x8e9b,0x35},\r
+{0x8e9c,0xaf},\r
+{0x8e9d,0x36},\r
+{0x8e9e,0xe4},\r
+{0x8e9f,0xfd},\r
+{0x8ea0,0xed},\r
+{0x8ea1,0xc3},\r
+{0x8ea2,0x95},\r
+{0x8ea3,0x37},\r
+{0x8ea4,0x50},\r
+{0x8ea5,0x33},\r
+{0x8ea6,0x12},\r
+{0x8ea7,0x0f},\r
+{0x8ea8,0xe2},\r
+{0x8ea9,0xe4},\r
+{0x8eaa,0x93},\r
+{0x8eab,0xf5},\r
+{0x8eac,0x38},\r
+{0x8ead,0x74},\r
+{0x8eae,0x01},\r
+{0x8eaf,0x93},\r
+{0x8eb0,0xf5},\r
+{0x8eb1,0x39},\r
+{0x8eb2,0x45},\r
+{0x8eb3,0x38},\r
+{0x8eb4,0x60},\r
+{0x8eb5,0x23},\r
+{0x8eb6,0x85},\r
+{0x8eb7,0x39},\r
+{0x8eb8,0x82},\r
+{0x8eb9,0x85},\r
+{0x8eba,0x38},\r
+{0x8ebb,0x83},\r
+{0x8ebc,0xe0},\r
+{0x8ebd,0xfc},\r
+{0x8ebe,0x12},\r
+{0x8ebf,0x0f},\r
+{0x8ec0,0xe2},\r
+{0x8ec1,0x74},\r
+{0x8ec2,0x03},\r
+{0x8ec3,0x93},\r
+{0x8ec4,0x52},\r
+{0x8ec5,0x04},\r
+{0x8ec6,0x12},\r
+{0x8ec7,0x0f},\r
+{0x8ec8,0xe2},\r
+{0x8ec9,0x74},\r
+{0x8eca,0x02},\r
+{0x8ecb,0x93},\r
+{0x8ecc,0x42},\r
+{0x8ecd,0x04},\r
+{0x8ece,0x85},\r
+{0x8ecf,0x39},\r
+{0x8ed0,0x82},\r
+{0x8ed1,0x85},\r
+{0x8ed2,0x38},\r
+{0x8ed3,0x83},\r
+{0x8ed4,0xec},\r
+{0x8ed5,0xf0},\r
+{0x8ed6,0x0d},\r
+{0x8ed7,0x80},\r
+{0x8ed8,0xc7},\r
+{0x8ed9,0x22},\r
+{0x8eda,0x78},\r
+{0x8edb,0xbe},\r
+{0x8edc,0xe6},\r
+{0x8edd,0xd3},\r
+{0x8ede,0x08},\r
+{0x8edf,0xff},\r
+{0x8ee0,0xe6},\r
+{0x8ee1,0x64},\r
+{0x8ee2,0x80},\r
+{0x8ee3,0xf8},\r
+{0x8ee4,0xef},\r
+{0x8ee5,0x64},\r
+{0x8ee6,0x80},\r
+{0x8ee7,0x98},\r
+{0x8ee8,0x22},\r
+{0x8ee9,0x93},\r
+{0x8eea,0xff},\r
+{0x8eeb,0x7e},\r
+{0x8eec,0x00},\r
+{0x8eed,0xe6},\r
+{0x8eee,0xfc},\r
+{0x8eef,0x08},\r
+{0x8ef0,0xe6},\r
+{0x8ef1,0xfd},\r
+{0x8ef2,0x12},\r
+{0x8ef3,0x04},\r
+{0x8ef4,0xc1},\r
+{0x8ef5,0x78},\r
+{0x8ef6,0xc1},\r
+{0x8ef7,0xe6},\r
+{0x8ef8,0xfc},\r
+{0x8ef9,0x08},\r
+{0x8efa,0xe6},\r
+{0x8efb,0xfd},\r
+{0x8efc,0xd3},\r
+{0x8efd,0xef},\r
+{0x8efe,0x9d},\r
+{0x8eff,0xee},\r
+{0x8f00,0x9c},\r
+{0x8f01,0x22},\r
+{0x8f02,0x78},\r
+{0x8f03,0xbd},\r
+{0x8f04,0xd3},\r
+{0x8f05,0xe6},\r
+{0x8f06,0x64},\r
+{0x8f07,0x80},\r
+{0x8f08,0x94},\r
+{0x8f09,0x80},\r
+{0x8f0a,0x22},\r
+{0x8f0b,0x25},\r
+{0x8f0c,0xe0},\r
+{0x8f0d,0x24},\r
+{0x8f0e,0x0a},\r
+{0x8f0f,0xf8},\r
+{0x8f10,0xe6},\r
+{0x8f11,0xfe},\r
+{0x8f12,0x08},\r
+{0x8f13,0xe6},\r
+{0x8f14,0xff},\r
+{0x8f15,0x22},\r
+{0x8f16,0xe5},\r
+{0x8f17,0x3c},\r
+{0x8f18,0xd3},\r
+{0x8f19,0x94},\r
+{0x8f1a,0x00},\r
+{0x8f1b,0x40},\r
+{0x8f1c,0x0b},\r
+{0x8f1d,0x90},\r
+{0x8f1e,0x0e},\r
+{0x8f1f,0x88},\r
+{0x8f20,0x12},\r
+{0x8f21,0x0b},\r
+{0x8f22,0xf1},\r
+{0x8f23,0x90},\r
+{0x8f24,0x0e},\r
+{0x8f25,0x86},\r
+{0x8f26,0x80},\r
+{0x8f27,0x09},\r
+{0x8f28,0x90},\r
+{0x8f29,0x0e},\r
+{0x8f2a,0x82},\r
+{0x8f2b,0x12},\r
+{0x8f2c,0x0b},\r
+{0x8f2d,0xf1},\r
+{0x8f2e,0x90},\r
+{0x8f2f,0x0e},\r
+{0x8f30,0x80},\r
+{0x8f31,0xe4},\r
+{0x8f32,0x93},\r
+{0x8f33,0xf5},\r
+{0x8f34,0x44},\r
+{0x8f35,0xa3},\r
+{0x8f36,0xe4},\r
+{0x8f37,0x93},\r
+{0x8f38,0xf5},\r
+{0x8f39,0x43},\r
+{0x8f3a,0xd2},\r
+{0x8f3b,0x06},\r
+{0x8f3c,0x30},\r
+{0x8f3d,0x06},\r
+{0x8f3e,0x03},\r
+{0x8f3f,0xd3},\r
+{0x8f40,0x80},\r
+{0x8f41,0x01},\r
+{0x8f42,0xc3},\r
+{0x8f43,0x92},\r
+{0x8f44,0x0e},\r
+{0x8f45,0x22},\r
+{0x8f46,0xa2},\r
+{0x8f47,0xaf},\r
+{0x8f48,0x92},\r
+{0x8f49,0x32},\r
+{0x8f4a,0xc2},\r
+{0x8f4b,0xaf},\r
+{0x8f4c,0xe5},\r
+{0x8f4d,0x23},\r
+{0x8f4e,0x45},\r
+{0x8f4f,0x22},\r
+{0x8f50,0x90},\r
+{0x8f51,0x0e},\r
+{0x8f52,0x5d},\r
+{0x8f53,0x60},\r
+{0x8f54,0x0e},\r
+{0x8f55,0x12},\r
+{0x8f56,0x0f},\r
+{0x8f57,0xcb},\r
+{0x8f58,0xe0},\r
+{0x8f59,0xf5},\r
+{0x8f5a,0x2c},\r
+{0x8f5b,0x12},\r
+{0x8f5c,0x0f},\r
+{0x8f5d,0xc8},\r
+{0x8f5e,0xe0},\r
+{0x8f5f,0xf5},\r
+{0x8f60,0x2d},\r
+{0x8f61,0x80},\r
+{0x8f62,0x0c},\r
+{0x8f63,0x12},\r
+{0x8f64,0x0f},\r
+{0x8f65,0xcb},\r
+{0x8f66,0xe5},\r
+{0x8f67,0x30},\r
+{0x8f68,0xf0},\r
+{0x8f69,0x12},\r
+{0x8f6a,0x0f},\r
+{0x8f6b,0xc8},\r
+{0x8f6c,0xe5},\r
+{0x8f6d,0x31},\r
+{0x8f6e,0xf0},\r
+{0x8f6f,0xa2},\r
+{0x8f70,0x32},\r
+{0x8f71,0x92},\r
+{0x8f72,0xaf},\r
+{0x8f73,0x22},\r
+{0x8f74,0xd2},\r
+{0x8f75,0x01},\r
+{0x8f76,0xc2},\r
+{0x8f77,0x02},\r
+{0x8f78,0xe4},\r
+{0x8f79,0xf5},\r
+{0x8f7a,0x1f},\r
+{0x8f7b,0xf5},\r
+{0x8f7c,0x1e},\r
+{0x8f7d,0xd2},\r
+{0x8f7e,0x35},\r
+{0x8f7f,0xd2},\r
+{0x8f80,0x33},\r
+{0x8f81,0xd2},\r
+{0x8f82,0x36},\r
+{0x8f83,0xd2},\r
+{0x8f84,0x01},\r
+{0x8f85,0xc2},\r
+{0x8f86,0x02},\r
+{0x8f87,0xf5},\r
+{0x8f88,0x1f},\r
+{0x8f89,0xf5},\r
+{0x8f8a,0x1e},\r
+{0x8f8b,0xd2},\r
+{0x8f8c,0x35},\r
+{0x8f8d,0xd2},\r
+{0x8f8e,0x33},\r
+{0x8f8f,0x22},\r
+{0x8f90,0xfb},\r
+{0x8f91,0xd3},\r
+{0x8f92,0xed},\r
+{0x8f93,0x9b},\r
+{0x8f94,0x74},\r
+{0x8f95,0x80},\r
+{0x8f96,0xf8},\r
+{0x8f97,0x6c},\r
+{0x8f98,0x98},\r
+{0x8f99,0x22},\r
+{0x8f9a,0x12},\r
+{0x8f9b,0x06},\r
+{0x8f9c,0x69},\r
+{0x8f9d,0xe5},\r
+{0x8f9e,0x40},\r
+{0x8f9f,0x2f},\r
+{0x8fa0,0xf5},\r
+{0x8fa1,0x40},\r
+{0x8fa2,0xe5},\r
+{0x8fa3,0x3f},\r
+{0x8fa4,0x3e},\r
+{0x8fa5,0xf5},\r
+{0x8fa6,0x3f},\r
+{0x8fa7,0xe5},\r
+{0x8fa8,0x3e},\r
+{0x8fa9,0x3d},\r
+{0x8faa,0xf5},\r
+{0x8fab,0x3e},\r
+{0x8fac,0xe5},\r
+{0x8fad,0x3d},\r
+{0x8fae,0x3c},\r
+{0x8faf,0xf5},\r
+{0x8fb0,0x3d},\r
+{0x8fb1,0x22},\r
+{0x8fb2,0xc0},\r
+{0x8fb3,0xe0},\r
+{0x8fb4,0xc0},\r
+{0x8fb5,0x83},\r
+{0x8fb6,0xc0},\r
+{0x8fb7,0x82},\r
+{0x8fb8,0x90},\r
+{0x8fb9,0x3f},\r
+{0x8fba,0x0d},\r
+{0x8fbb,0xe0},\r
+{0x8fbc,0xf5},\r
+{0x8fbd,0x33},\r
+{0x8fbe,0xe5},\r
+{0x8fbf,0x33},\r
+{0x8fc0,0xf0},\r
+{0x8fc1,0xd0},\r
+{0x8fc2,0x82},\r
+{0x8fc3,0xd0},\r
+{0x8fc4,0x83},\r
+{0x8fc5,0xd0},\r
+{0x8fc6,0xe0},\r
+{0x8fc7,0x32},\r
+{0x8fc8,0x90},\r
+{0x8fc9,0x0e},\r
+{0x8fca,0x5f},\r
+{0x8fcb,0xe4},\r
+{0x8fcc,0x93},\r
+{0x8fcd,0xfe},\r
+{0x8fce,0x74},\r
+{0x8fcf,0x01},\r
+{0x8fd0,0x93},\r
+{0x8fd1,0xf5},\r
+{0x8fd2,0x82},\r
+{0x8fd3,0x8e},\r
+{0x8fd4,0x83},\r
+{0x8fd5,0x22},\r
+{0x8fd6,0x78},\r
+{0x8fd7,0x7f},\r
+{0x8fd8,0xe4},\r
+{0x8fd9,0xf6},\r
+{0x8fda,0xd8},\r
+{0x8fdb,0xfd},\r
+{0x8fdc,0x75},\r
+{0x8fdd,0x81},\r
+{0x8fde,0xcd},\r
+{0x8fdf,0x02},\r
+{0x8fe0,0x0c},\r
+{0x8fe1,0x98},\r
+{0x8fe2,0x8f},\r
+{0x8fe3,0x82},\r
+{0x8fe4,0x8e},\r
+{0x8fe5,0x83},\r
+{0x8fe6,0x75},\r
+{0x8fe7,0xf0},\r
+{0x8fe8,0x04},\r
+{0x8fe9,0xed},\r
+{0x8fea,0x02},\r
+{0x8feb,0x06},\r
+{0x8fec,0xa5},\r
+{0x3022,0x00},\r
+{0x3023,0x00},\r
+{0x3024,0x00},\r
+{0x3025,0x00},\r
+{0x3026,0x00},\r
+{0x3027,0x00},\r
+{0x3028,0x00},\r
+{0x3029,0x7F},\r
+{0x3000,0x00},\r
+#endif\r
+ {SEQUENCE_END,0x00},\r
+};\r
--- /dev/null
+/*
+ * Driver for OV5640 CMOS Image Sensor from OmniVision
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+#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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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<<i)) {
+ if (sensor_write(client, CMD_PARA0_Reg+i, cmdinfo->cmd_para[i])) {
+ SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
+ goto sensor_af_cmdset_err;
+ }
+ SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
+ }
+ }
+
+ 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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+MODULE_LICENSE("GPL");
+
+
\r
static void rk30_camera_request_reserve_mem(void)\r
{\r
+ int i,max_resolution;\r
+ int cam_ipp_mem=PMEM_CAMIPP_NECESSARY, cam_pmem=PMEM_CAM_NECESSARY;\r
+\r
+ i =0;\r
+ max_resolution = 0x00;\r
+ while (strstr(new_camera[i].dev.device_info.dev.init_name,"end")==NULL) {\r
+ if (new_camera[i].resolution > max_resolution)\r
+ max_resolution = new_camera[i].resolution;\r
+ i++;\r
+ }\r
+\r
+ if (max_resolution < PMEM_SENSOR_FULL_RESOLUTION_CIF_1)\r
+ max_resolution = PMEM_SENSOR_FULL_RESOLUTION_CIF_1;\r
+ if (max_resolution < PMEM_SENSOR_FULL_RESOLUTION_CIF_0)\r
+ max_resolution = PMEM_SENSOR_FULL_RESOLUTION_CIF_0;\r
+\r
+ switch (max_resolution)\r
+ {\r
+ case 0x800000:\r
+ default:\r
+ {\r
+ cam_ipp_mem = 0x800000;\r
+ cam_pmem = 0x1900000;\r
+ break;\r
+ }\r
+\r
+ case 0x500000:\r
+ {\r
+ cam_ipp_mem = 0x800000;\r
+ cam_pmem = 0x1400000;\r
+ break;\r
+ }\r
+\r
+ case 0x300000:\r
+ {\r
+ cam_ipp_mem = 0x600000;\r
+ cam_pmem = 0xf00000;\r
+ break;\r
+ }\r
+\r
+ case 0x200000:\r
+ {\r
+ cam_ipp_mem = 0x600000;\r
+ cam_pmem = 0xc00000;\r
+ break;\r
+ }\r
+\r
+ case 0x100000:\r
+ {\r
+ cam_ipp_mem = 0x600000;\r
+ cam_pmem = 0xa00000;\r
+ break;\r
+ }\r
+\r
+ case 0x30000:\r
+ {\r
+ cam_ipp_mem = 0x600000;\r
+ cam_pmem = 0x600000;\r
+ break;\r
+ }\r
+ }\r
+\r
+ \r
+\r
#ifdef CONFIG_VIDEO_RK29_WORK_IPP\r
rk_camera_platform_data.meminfo.vbase = rk_camera_platform_data.meminfo_cif1.vbase = NULL;\r
#if defined(CONFIG_VIDEO_RKCIF_WORK_SIMUL_OFF) || ((RK_SUPPORT_CIF0 && RK_SUPPORT_CIF1) == 0)\r
rk_camera_platform_data.meminfo.name = "camera_ipp_mem";\r
- rk_camera_platform_data.meminfo.start = board_mem_reserve_add("camera_ipp_mem",PMEM_CAMIPP_NECESSARY);\r
- rk_camera_platform_data.meminfo.size= PMEM_CAMIPP_NECESSARY;\r
+ rk_camera_platform_data.meminfo.start = board_mem_reserve_add("camera_ipp_mem",cam_ipp_mem);\r
+ rk_camera_platform_data.meminfo.size= cam_ipp_mem;\r
\r
memcpy(&rk_camera_platform_data.meminfo_cif1,&rk_camera_platform_data.meminfo,sizeof(struct rk29camera_mem_res));\r
#else\r
#endif\r
#endif\r
#if PMEM_CAM_NECESSARY\r
- android_pmem_cam_pdata.start = board_mem_reserve_add((char*)(android_pmem_cam_pdata.name),PMEM_CAM_NECESSARY);\r
- android_pmem_cam_pdata.size= PMEM_CAM_NECESSARY;\r
+ android_pmem_cam_pdata.start = board_mem_reserve_add((char*)(android_pmem_cam_pdata.name),cam_pmem);\r
+ android_pmem_cam_pdata.size= cam_pmem;\r
#endif\r
\r
}\r
{\r
int i;\r
int host_registered_0,host_registered_1;\r
+ struct rkcamera_platform_data *new_camera;\r
\r
rk_init_camera_plateform_data();\r
\r
host_registered_0 = 0;\r
host_registered_1 = 0;\r
+ \r
for (i=0; i<RK_CAM_NUM; i++) {\r
if (rk_camera_platform_data.register_dev[i].device_info.name) {\r
\r
if (rk_camera_platform_data.register_dev[i].link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_0) {\r
- #if RK_SUPPORT_CIF0\r
- if (!host_registered_0) {\r
- platform_device_register(&rk_device_camera_host_0);\r
- host_registered_0 = 1;\r
- }\r
+ #if RK_SUPPORT_CIF0 \r
+ host_registered_0 = 1;\r
#else\r
printk(KERN_ERR "%s(%d) : This chip isn't support CIF0, Please user check ...\n",__FUNCTION__,__LINE__);\r
#endif\r
\r
if (rk_camera_platform_data.register_dev[i].link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_1) {\r
#if RK_SUPPORT_CIF1\r
- if (!host_registered_1) {\r
- platform_device_register(&rk_device_camera_host_1);\r
- host_registered_1 = 1;\r
- }\r
+ host_registered_1 = 1;\r
#else\r
printk(KERN_ERR "%s(%d) : This chip isn't support CIF1, Please user check ...\n",__FUNCTION__,__LINE__);\r
#endif\r
}\r
}\r
\r
+ \r
+ i=0;\r
+ new_camera = rk_camera_platform_data.register_dev_new;\r
+ if (new_camera != NULL) {\r
+ while (strstr(new_camera->dev.device_info.dev.init_name,"end")==NULL) {\r
+ if (new_camera->dev.link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_1) {\r
+ host_registered_1 = 1;\r
+ } else if (new_camera->dev.link_info.bus_id == RK_CAM_PLATFORM_DEV_ID_0) {\r
+ host_registered_0 = 1;\r
+ }\r
+ new_camera++;\r
+ }\r
+ }\r
+\r
+ if (host_registered_0) {\r
+ platform_device_register(&rk_device_camera_host_0);\r
+ }\r
+\r
+ if (host_registered_1) {\r
+ platform_device_register(&rk_device_camera_host_1);\r
+ } \r
+\r
for (i=0; i<RK_CAM_NUM; i++) {\r
if (rk_camera_platform_data.register_dev[i].device_info.name) {\r
platform_device_register(&rk_camera_platform_data.register_dev[i].device_info);\r
}\r
}\r
+\r
+ if (rk_camera_platform_data.sensor_register)\r
+ (rk_camera_platform_data.sensor_register)(); \r
+ \r
#if PMEM_CAM_NECESSARY\r
platform_device_register(&android_pmem_cam_device);\r
#endif\r
#define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
#endif
#include <asm/cacheflush.h>
+
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
#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)
* 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 |\
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;
* 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;
#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
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);
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));
#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;
}
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);
}
}
}
}
#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)
{
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:
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; h<scale_times; h++) {
for (w=0; w<scale_times; w++) {
- int ipp_times = 3;
src_y_offset = (pcdev->zoominfo.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
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);
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);
}
}
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);
}
#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);
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()){
#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;
}
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)
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);
/* 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;
}
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);
// 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 */
//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;
}
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)
{
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);
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;
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;
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;
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);
}
}
}
- 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);
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)
{
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
}
RK_CAMERA_TRY_FMT_END:
- if (ret)
+ if (ret<0)
RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
return ret;
}
struct v4l2_capability *cap)
{
struct rk_camera_dev *pcdev = ici->priv;
+ struct rkcamera_platform_data *new_camera;
char orientation[5];
int i;
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));
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)
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;
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:
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;
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;
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)) {
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);
} 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);
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;
#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:
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:
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;
}
-
+\r
+#include "generic_sensor.h"\r
/*
- * Driver for SP2518 CMOS Image Sensor from Superpix
- *
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*
-* History Author Data
-* First Version yuanjianping 2012-09-20
-* Set P0:0x14 = 0x40 zengchaohui 2012-09-20
-*/
-
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/log2.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/circ_buf.h>
-#include <linux/miscdevice.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-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) ((x<y) ? x: y)
-#define MAX(x,y) ((x>y) ? 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\r
+*v0.0.1: this driver is compatible with generic_sensor\r
+*/\r
+static int version = KERNEL_VERSION(0,0,1);\r
+module_param(version, int, S_IRUGO);\r
+\r
+\r
+\r
+static int debug;\r
+module_param(debug, int, S_IRUGO|S_IWUSR);\r
+\r
+#define dprintk(level, fmt, arg...) do { \\r
+ if (debug > level) \\r
+ printk(KERN_WARNING fmt , ## arg); } while (0)\r
+\r
+/* Sensor Driver Configuration Begin */\r
+#define SENSOR_NAME RK29_CAM_SENSOR_SP2518\r
+#define SENSOR_V4L2_IDENT V4L2_IDENT_SP2518\r
+#define SENSOR_ID 0x53\r
+#define SENSOR_BUS_PARAM (SOCAM_MASTER |\\r
+ SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\\r
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)\r
+#define SENSOR_PREVIEW_W 800\r
+#define SENSOR_PREVIEW_H 600\r
+#define SENSOR_PREVIEW_FPS 15000 // 15fps \r
+#define SENSOR_FULLRES_L_FPS 7500 // 7.5fps\r
+#define SENSOR_FULLRES_H_FPS 7500 // 7.5fps\r
+#define SENSOR_720P_FPS 0\r
+#define SENSOR_1080P_FPS 0\r
+\r
+#define SENSOR_REGISTER_LEN 1 // sensor register address bytes\r
+#define SENSOR_VALUE_LEN 1 // sensor register value bytes\r
+\r
+static unsigned int SensorConfiguration = (CFG_WhiteBalance|CFG_Effect|CFG_Scene);\r
+static unsigned int SensorChipID[] = {SENSOR_ID};\r
+/* Sensor Driver Configuration End */\r
+\r
+\r
+#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a))\r
+#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a)\r
+\r
+#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b)\r
+#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v))\r
+#define sensor_write_array generic_sensor_write_array\r
+\r
+struct sensor_parameter\r
+{\r
+ unsigned int PreviewDummyPixels;\r
+ unsigned int CaptureDummyPixels;\r
+ unsigned int preview_exposure;\r
+ unsigned short int preview_line_width;\r
+ unsigned short int preview_gain;\r
+\r
+ unsigned short int PreviewPclk;\r
+ unsigned short int CapturePclk;\r
+ char awb[6];\r
+};\r
+\r
+struct specific_sensor{\r
+ struct generic_sensor common_sensor;\r
+ //define user data below\r
+ struct sensor_parameter parameter;\r
+\r
+};\r
+\r
+/*\r
+* Local define\r
+*/\r
//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\r
+#define SP2518_P0_0xf8 0x74//6e\r
+#define SP2518_P0_0xf9 0x80//74\r
+#define SP2518_P0_0xfa 0x74//6a\r
+//HEQ\r
+#define SP2518_P0_0xdd 0x80\r
+#define SP2518_P0_0xde 0x95\r
//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\r
+\r
+/*\r
+* The follow setting need been filled.\r
+* \r
+* Must Filled:\r
+* sensor_init_data : Sensor initial setting;\r
+* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video;\r
+* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga;\r
+* sensor_softreset_data : Sensor software reset register;\r
+* sensor_check_id_data : Sensir chip id register;\r
+*\r
+* Optional filled:\r
+* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video;\r
+* sensor_720p: Sensor 720p setting, it is for video;\r
+* sensor_1080p: Sensor 1080p setting, it is for video;\r
+*\r
+* :::::WARNING:::::\r
+* The SensorEnd which is the setting end flag must be filled int the last of each setting;\r
+*/\r
+\r
+/* Sensor initial setting */\r
+static struct rk_sensor_reg sensor_init_data[] = {\r
{0xfd,0x00},
{0x1b,0x1a},//maximum drv ability //0x02 modify by sp_yjp,20120809
{0x0e,0x01},
{0x1a,0x80},
{0x1b,0x80},
{0x43,0x80},
- //outdoor
- {0x00,0xd4},
- {0x01,0xb0},
- {0x02,0x90},
- {0x03,0x78},
+ //outdoor\r
+ {0x00,0xd4},\r
+ {0x01,0xb0},\r
+ {0x02,0x90},\r
+ {0x03,0x78},\r
//d65
{0x35,0xd6},//d6;b0
{0x36,0xf0},//f0;d1;e9
{0xc0,0xb0},
{0xc1,0xf0},
- {0xd3,0x77},
- {0xd4,0x77},
- {0xd6,0x77},
- {0xd7,0x77},
- {0xd8,0x77},
- {0xd9,0x77},
- {0xda,0x77},
- {0xdb,0x77},
+ {0xd3,0x77},\r
+ {0xd4,0x77},\r
+ {0xd6,0x77},\r
+ {0xd7,0x77},\r
+ {0xd8,0x77},\r
+ {0xd9,0x77},\r
+ {0xda,0x77},\r
+ {0xdb,0x77},\r
//uv_dif
{0xfd,0x00},
{0xf3,0x03},
{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},\r
+ \r
//SVGA
{0xfd,0x00},
{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}, \r
+ {0x5d,0x0e}, //vsync delay\r
+ \r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for capture */\r
+static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={\r
+\r
{0xfd,0x00},
{0x47,0x00},
{0x48,0x00},
{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},\r
+ SensorEnd\r
+};\r
+/* Senor full resolution setting: recommand for video */\r
+static struct rk_sensor_reg sensor_fullres_highfps_data[] ={\r
+ SensorEnd\r
+};\r
+/* Preview resolution setting*/\r
+static struct rk_sensor_reg sensor_preview_data[] =\r
+{\r
+ {0xfd,0x00},\r
{0x47,0x00},
{0x48,0x00},
{0x49,0x04},
- {0x4a,0xb0},
-
+ {0x4a,0xb0}, \r
{0x4b,0x00},
{0x4c,0x00},
{0x4d,0x06},
{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},\r
+\r
+ SensorEnd\r
+};\r
+/* 1280x720 */\r
+static struct rk_sensor_reg sensor_720p[]={\r
+ SensorEnd\r
+};\r
+\r
+/* 1920x1080 */\r
+static struct rk_sensor_reg sensor_1080p[]={\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_softreset_data[]={\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_check_id_data[]={\r
+ SensorRegVal(0x02,0),\r
+ SensorEnd\r
+};\r
+/*\r
+* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx\r
+*/\r
+static struct rk_sensor_reg sensor_WhiteB_Auto[]=\r
+{\r
+ {0xfd, 0x01}, \r
{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},\r
+ SensorEnd\r
+};\r
+/* Cloudy Colour Temperature : 6500K - 8000K */\r
+static struct rk_sensor_reg sensor_WhiteB_Cloudy[]=\r
+{\r
+ {0xfd,0x00},\r
{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},\r
+ SensorEnd\r
+};\r
+/* ClearDay Colour Temperature : 5000K - 6500K */\r
+static struct rk_sensor_reg sensor_WhiteB_ClearDay[]=\r
+{\r
+ {0xfd,0x00},\r
{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},\r
+ SensorEnd\r
+};\r
+/* Office Colour Temperature : 3500K - 5000K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]=\r
+{\r
+ {0xfd,0x00},\r
{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},\r
+ SensorEnd\r
+\r
+};\r
+/* Home Colour Temperature : 2500K - 3500K */\r
+static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]=\r
+{\r
+ //Home\r
+ {0x3406, 0x01},\r
+ {0x3400, 0x04},\r
+ {0x3401, 0x58},\r
+ {0x3402, 0x04},\r
+ {0x3403, 0x00},\r
+ {0x3404, 0x07},\r
+ {0x3405, 0x24},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2,\r
+ sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness0[]=\r
+{\r
+ // Brightness -2\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness1[]=\r
+{\r
+ // Brightness -1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness2[]=\r
+{\r
+ // Brightness 0\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness3[]=\r
+{\r
+ // Brightness +1\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness4[]=\r
+{\r
+ // Brightness +2\r
+\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Brightness5[]=\r
+{\r
+ // Brightness +3\r
+\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3,\r
+ sensor_Brightness4, sensor_Brightness5,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Normal[] =\r
+{\r
+ {0xfd, 0x00},\r
{0x62, 0x00},
{0x63, 0x80},
- {0x64, 0x80},
- {0xff, 0xff}
-};
-
-static struct reginfo sensor_Effect_WandB[] =
-{
- {0xfd, 0x00},
+ {0x64, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_WandB[] =\r
+{\r
+ {0xfd, 0x00},\r
{0x62, 0x20},
{0x63, 0x80},
- {0x64, 0x80},
- {0xff, 0xff}
-};
-
-static struct reginfo sensor_Effect_Sepia[] =
-{
- {0xfd, 0x00},
+ {0x64, 0x80},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Sepia[] =\r
+{\r
+ {0xfd, 0x00},\r
{0x62, 0x10},
{0x63, 0xb0},
- {0x64, 0x40},
- {0xff, 0xff}
-};
-
-static struct reginfo sensor_Effect_Negative[] =
-{
- {0xfd, 0x00},
+ {0x64, 0x40},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Negative[] =\r
+{\r
+ {0xfd, 0x00},\r
{0x62, 0x04},
{0x63, 0x80},
- {0x64, 0x80},
- {0xff, 0xff}
-};
-static struct reginfo sensor_Effect_Bluish[] =
-{
- {0xfd, 0x00},
+ {0x64, 0x80},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg sensor_Effect_Bluish[] =\r
+{\r
+ {0xfd, 0x00},\r
{0x62, 0x10},
{0x63, 0x80},
- {0x64, 0xb0},
- {0xff, 0xff}
-};
-
-static struct reginfo sensor_Effect_Green[] =
-{
- {0xfd, 0x00},
+ {0x64, 0xb0},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Effect_Green[] =\r
+{\r
+ {0xfd, 0x00},\r
{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},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia,\r
+ sensor_Effect_Bluish, sensor_Effect_Green,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Exposure6[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,\r
+ sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL,\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Saturation2[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Contrast0[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast1[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast2[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast3[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast4[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Contrast5[]=\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Contrast6[]=\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3,\r
+ sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL,\r
+};\r
+static struct rk_sensor_reg sensor_SceneAuto[] =\r
+{\r
+ {0xfd, 0x00},\r
+ {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},\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_SceneNight[] =\r
+{\r
+ {0xfd,0x00},\r
+ {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},\r
+
+ {0xfd,0x00},\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,};\r
+\r
+static struct rk_sensor_reg sensor_Zoom0[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom1[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+static struct rk_sensor_reg sensor_Zoom2[] =\r
+{\r
+ SensorEnd\r
+};\r
+\r
+\r
+static struct rk_sensor_reg sensor_Zoom3[] =\r
+{\r
+ SensorEnd\r
+};\r
+static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,};\r
+\r
+/*\r
+* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu\r
+*/\r
+static struct v4l2_querymenu sensor_menus[] =\r
+{\r
+};\r
+/*\r
+* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl\r
+*/\r
+static struct sensor_v4l2ctrl_usr_s sensor_controls[] =\r
+{\r
+};\r
+\r
+//MUST define the current used format as the first item \r
+static struct rk_sensor_datafmt sensor_colour_fmts[] = {\r
+ {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} \r
+};\r
+static struct soc_camera_ops sensor_ops;\r
+\r
+\r
+/*\r
+**********************************************************\r
+* Following is local code:\r
+* \r
+* Please codeing your program here \r
+**********************************************************\r
+*/\r
+\r
+/*\r
+**********************************************************\r
+* Following is callback\r
+* If necessary, you could coding these callback\r
+**********************************************************\r
+*/\r
+/*\r
+* the function is called in open sensor \r
+*/\r
+static int sensor_activate_cb(struct i2c_client *client)\r
+{\r
+\r
+ SENSOR_DG("%s",__FUNCTION__); \r
+\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called in close sensor\r
+*/\r
+static int sensor_deactivate_cb(struct i2c_client *client)\r
+{\r
+ //struct generic_sensor *sensor = to_generic_sensor(client);\r
+\r
+ SENSOR_DG("%s",__FUNCTION__);\r
+ \r
+ return 0;\r
+}\r
+/*\r
+* the function is called before sensor register setting in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+/*\r
+* the function is called after sensor register setting finished in VIDIOC_S_FMT \r
+*/\r
+static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture)\r
+{\r
+ return 0;\r
+}\r
+static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ \r
+ return 0;\r
+}\r
+static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series)\r
+{\r
+ return 0;\r
+}\r
+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;i<sizeof(sensor_init_data) / 2;i++)
- {
- 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);
- }
-
- }
-
-
- 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(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; i<ext_ctrl->count; i++) {
- if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct soc_camera_device *icd = client->dev.platform_data;
- int i, error_cnt=0, error_idx=-1;
-
-
- for (i=0; i<ext_ctrl->count; i++) {
- if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
- error_cnt++;
- error_idx = i;
- }
- }
-
- if (error_cnt > 1)
- error_idx = ext_ctrl->count;
-
- if (error_idx != -1) {
- ext_ctrl->error_idx = error_idx;
- return -EINVAL;
- } else {
- return 0;
- }
-}
-
-/* Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one */
-static int sensor_video_probe(struct soc_camera_device *icd,
- struct i2c_client *client)
-{
- char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
- if (sensor->sensor_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 <kernel@rock-chips>");
-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)\r
+{\r
+ //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+ \r
+ if (pm_msg.event == PM_EVENT_SUSPEND) {\r
+ SENSOR_DG("Suspend");\r
+ \r
+ } else {\r
+ SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event);\r
+ return -EINVAL;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int sensor_resume(struct soc_camera_device *icd)\r
+{\r
+\r
+ SENSOR_DG("Resume");\r
+\r
+ return 0;\r
+\r
+}\r
+static int sensor_mirror_cb (struct i2c_client *client, int mirror)\r
+{\r
+ int err = 0;\r
+ \r
+ SENSOR_DG("mirror: %d",mirror);\r
+ \r
+\r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_HFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_mirror_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_mirror failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_mirror success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+\r
+static int sensor_flip_cb(struct i2c_client *client, int flip)\r
+{\r
+ int err = 0; \r
+\r
+ SENSOR_DG("flip: %d",flip);\r
+ \r
+ return err; \r
+}\r
+/*\r
+* the function is v4l2 control V4L2_CID_VFLIP callback \r
+*/\r
+static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, \r
+ struct v4l2_ext_control *ext_ctrl)\r
+{\r
+ struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
+\r
+ if (sensor_flip_cb(client,ext_ctrl->value) != 0)\r
+ SENSOR_TR("sensor_flip failed, value:0x%x",ext_ctrl->value);\r
+ \r
+ SENSOR_DG("sensor_flip success, value:0x%x",ext_ctrl->value);\r
+ return 0;\r
+}\r
+/*\r
+* the functions are focus callbacks\r
+*/\r
+static int sensor_focus_init_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_single_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_near_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_far_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_const_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+static int sensor_focus_af_close_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client){\r
+ return 0;\r
+}\r
+\r
+/*\r
+face defect call back\r
+*/\r
+static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){\r
+ return 0;\r
+}\r
+\r
+/*\r
+* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some\r
+* initialization in the function. \r
+*/\r
+static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd)\r
+{\r
+ return;\r
+}\r
+\r
+/*\r
+* :::::WARNING:::::\r
+* It is not allowed to modify the following code\r
+*/\r
+\r
+sensor_init_parameters_default_code();\r
+\r
+sensor_v4l2_struct_initialization();\r
+\r
+sensor_probe_default_code();\r
+\r
+sensor_remove_default_code();\r
+\r
+sensor_driver_default_module_code();\r
+\r
+\r
--- /dev/null
+
+/*
+ * Driver for SP2518 CMOS Image Sensor from Superpix
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*
+* History Author Data
+* First Version yuanjianping 2012-09-20
+* Set P0:0x14 = 0x40 zengchaohui 2012-09-20
+*/
+
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+#include <plat/rk_camera.h>
+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) ((x<y) ? x: y)
+#define MAX(x,y) ((x>y) ? 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;i<sizeof(sensor_init_data) / 2;i++)
+ {
+ 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);
+ }
+
+ }
+
+
+ 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(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; i<ext_ctrl->count; i++) {
+ if (sensor_g_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct soc_camera_device *icd = client->dev.platform_data;
+ int i, error_cnt=0, error_idx=-1;
+
+
+ for (i=0; i<ext_ctrl->count; i++) {
+ if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {
+ error_cnt++;
+ error_idx = i;
+ }
+ }
+
+ if (error_cnt > 1)
+ error_idx = ext_ctrl->count;
+
+ if (error_idx != -1) {
+ ext_ctrl->error_idx = error_idx;
+ return -EINVAL;
+ } else {
+ return 0;
+ }
+}
+
+/* Interface active, can use i2c. If it fails, it can indeed mean, that
+ * this wasn't our capture interface, so, we wait for the right one */
+static int sensor_video_probe(struct soc_camera_device *icd,
+ struct i2c_client *client)
+{
+ char 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; i<RK29_CAM_SUPPORT_NUMS;i++) {
+ if (sensor->sensor_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 <kernel@rock-chips>");
+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);
+*/
+
+
+
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;
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 */
};
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! */
};