camera: mt9p111 support falsh for fih
authorddl <ddl@rockchip.com>
Wed, 4 May 2011 06:40:31 +0000 (14:40 +0800)
committerddl <ddl@rockchip.com>
Wed, 4 May 2011 06:41:33 +0000 (14:41 +0800)
arch/arm/mach-rk29/board-rk29-fih.c
drivers/media/video/mt9p111.c

index 8b2572a6247292e5b673004257abdbdf89f2e7ed..b588c031f7e6922bc28e18da759726734dd2f19d 100755 (executable)
@@ -54,6 +54,7 @@
 #include <linux/mtd/partitions.h>
 
 #include <linux/atmel_maxtouch.h>
+#include <linux/leds-att1272.h>
 
 #include "devices.h"
 #include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
@@ -909,6 +910,13 @@ struct tps65910_platform_data rk29_tps65910_data = {
 };
 #endif /* CONFIG_TPS65910_CORE */
 
+#if defined (CONFIG_LEDS_ATT1272) 
+struct att1272_led_platform_data att1272_data = {
+    .name = "att1272",
+    .en_gpio = RK29_PIN1_PB0,
+    .flen_gpio = RK29_PIN1_PB1,
+};
+#endif
 
 /*****************************************************************************************
  * i2c devices
@@ -1079,6 +1087,16 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
       .platform_data  = &mxt224_info,
     },
 #endif
+
+#if defined (CONFIG_LEDS_ATT1272)
+    {
+      .type           = "att1272",
+      .addr           = 0x37,
+      .flags          = 0,
+      .irq            = 0,
+      .platform_data  = &att1272_data,
+    },
+#endif
 };
 #endif
 
@@ -1124,29 +1142,43 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
  * author: ddl@rock-chips.com
  *****************************************************************************************/
 #ifdef CONFIG_VIDEO_RK29
-#define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_MT9P111         /* back camera sensor */
-#define SENSOR_IIC_ADDR_0          0x78 
-#define SENSOR_IIC_ADAPTER_ID_0    1
-#define SENSOR_POWER_PIN_0         RK29_PIN5_PD7
-#define SENSOR_RESET_PIN_0         INVALID_GPIO
-#define SENSOR_POWERDN_PIN_0       RK29_PIN1_PB2
-#define SENSOR_FALSH_PIN_0         INVALID_GPIO
-#define SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L
-#define SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L
-#define SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H
-#define SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L
-
-#define SENSOR_NAME_1 RK29_CAM_SENSOR_NAME_S5K6AA          /* front camera sensor */
-#define SENSOR_IIC_ADDR_1          0x78
-#define SENSOR_IIC_ADAPTER_ID_1    1
-#define SENSOR_POWER_PIN_1         INVALID_GPIO
-#define SENSOR_RESET_PIN_1         RK29_PIN1_PB3
-#define SENSOR_POWERDN_PIN_1       RK29_PIN6_PB7
-#define SENSOR_FALSH_PIN_1         INVALID_GPIO
-#define SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L
-#define SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L
-#define SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_L
-#define SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
+/*---------------- Camera Sensor Configuration Begin ------------------------*/
+#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_MT9P111                      /* back camera sensor */
+#define CONFIG_SENSOR_IIC_ADDR_0           0x78
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_0    1
+#define CONFIG_SENSOR_POWER_PIN_0         RK29_PIN5_PD7
+#define CONFIG_SENSOR_RESET_PIN_0         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_0       RK29_PIN1_PB2
+#define CONFIG_SENSOR_FALSH_PIN_0         RK29_PIN1_PB1
+#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_H
+
+#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_S5K6AA                      /* front camera sensor */
+#define CONFIG_SENSOR_IIC_ADDR_1           0x78
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_1    1
+#define CONFIG_SENSOR_POWER_PIN_1         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_1         RK29_PIN1_PB3
+#define CONFIG_SENSOR_POWERDN_PIN_1       RK29_PIN6_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_L
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
+/*---------------- Camera Sensor Configuration End------------------------*/
+
+#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 SENSOR_NAME_0 STR(CONFIG_SENSOR_0)                     /* back camera sensor */
+#define SENSOR_NAME_1 STR(CONFIG_SENSOR_1)                     /* front camera sensor */
+#define SENSOR_DEVICE_NAME_0  STR(CONS(CONFIG_SENSOR_0, _back))
+#define SENSOR_DEVICE_NAME_1  STR(CONS(CONFIG_SENSOR_1, _front))
 
 static int rk29_sensor_io_init(void);
 static int rk29_sensor_io_deinit(int sensor);
@@ -1158,21 +1190,21 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
     .sensor_ioctrl = rk29_sensor_ioctrl,
     .gpio_res = {
         {
-            .gpio_reset = SENSOR_RESET_PIN_0,
-            .gpio_power = SENSOR_POWER_PIN_0,
-            .gpio_powerdown = SENSOR_POWERDN_PIN_0,
-            .gpio_flash = SENSOR_FALSH_PIN_0,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_0|SENSOR_RESETACTIVE_LEVEL_0|SENSOR_POWERDNACTIVE_LEVEL_0|SENSOR_FLASHACTIVE_LEVEL_0),
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_0,
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_0,
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_0,
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_0,
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_0|CONFIG_SENSOR_RESETACTIVE_LEVEL_0|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0|CONFIG_SENSOR_FLASHACTIVE_LEVEL_0),
             .gpio_init = 0,
-            .dev_name = SENSOR_NAME_0,
+            .dev_name = SENSOR_DEVICE_NAME_0,
         }, {
-            .gpio_reset = SENSOR_RESET_PIN_1,
-            .gpio_power = SENSOR_POWER_PIN_1,
-            .gpio_powerdown = SENSOR_POWERDN_PIN_1,
-            .gpio_flash = SENSOR_FALSH_PIN_1,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_1|SENSOR_POWERDNACTIVE_LEVEL_1|SENSOR_FLASHACTIVE_LEVEL_1),
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_1,
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_1,
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_1,
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_1,
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_1|CONFIG_SENSOR_RESETACTIVE_LEVEL_1|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1|CONFIG_SENSOR_FLASHACTIVE_LEVEL_1),
             .gpio_init = 0,
-            .dev_name = SENSOR_NAME_1,
+            .dev_name = SENSOR_DEVICE_NAME_1,
         }
     },
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP
@@ -1387,13 +1419,35 @@ static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,
                {
                        if (camera_flash != INVALID_GPIO) {
                                if (camera_io_init & RK29_CAM_FLASHACTIVE_MASK) {
-                                       if (on) {
-                                       gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
-                                       //printk("\n%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
-                                       } else {
-                                               gpio_set_value(camera_flash,(((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
-                                       //printk("\n%s..%s..FlashPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
-                               }
+                    switch (on)
+                    {
+                        case Flash_Off:
+                        {
+                            gpio_set_value(camera_flash,(((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+                                           printk("\n%s..%s..FlashPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); 
+                                           break;
+                        }
+
+                        case Flash_On:
+                        {
+                            gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+                                           printk("\n%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+                                           break;
+                        }
+
+                        case Flash_Torch:
+                        {
+                            gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+                                           printk("\n%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+                                           break;
+                        }
+
+                        default:
+                        {
+                            printk("\n%s..%s..Flash command(%d) is invalidate \n",__FUNCTION__,dev_name(dev),on);
+                            break;
+                        }
+                    }
                                } else {
                                        ret = RK29_CAM_EIO_REQUESTFAIL;
                                        printk("\n%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_flash);
@@ -1428,10 +1482,10 @@ static int rk29_sensor_powerdown(struct device *dev, int on)
 {
        return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);
 }
-#if (SENSOR_IIC_ADDR_0 != 0x00)
+#if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)
 static struct i2c_board_info rk29_i2c_cam_info_0[] = {
        {
-               I2C_BOARD_INFO(SENSOR_NAME_0, SENSOR_IIC_ADDR_0>>1)
+               I2C_BOARD_INFO(SENSOR_NAME_0, CONFIG_SENSOR_IIC_ADDR_0>>1)
        },
 };
 
@@ -1440,7 +1494,7 @@ static struct soc_camera_link rk29_iclink_0 = {
        .power          = rk29_sensor_power,
        .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_0[0],
-       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_0,
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_0,
        .module_name    = SENSOR_NAME_0,
 };
 
@@ -1449,15 +1503,15 @@ static struct platform_device rk29_soc_camera_pdrv_0 = {
        .name   = "soc-camera-pdrv",
        .id     = 0,
        .dev    = {
-               .init_name = SENSOR_NAME_0,
+               .init_name = SENSOR_DEVICE_NAME_0,
                .platform_data = &rk29_iclink_0,
        },
 };
 #endif
-#if (SENSOR_IIC_ADDR_1 != 0x00)
+#if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)
 static struct i2c_board_info rk29_i2c_cam_info_1[] = {
        {
-               I2C_BOARD_INFO(SENSOR_NAME_1, SENSOR_IIC_ADDR_1>>1)
+               I2C_BOARD_INFO(SENSOR_NAME_1, CONFIG_SENSOR_IIC_ADDR_1>>1)
        },
 };
 
@@ -1466,7 +1520,7 @@ static struct soc_camera_link rk29_iclink_1 = {
        .power          = rk29_sensor_power,
        .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_1[0],
-       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_1,
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_1,
        .module_name    = SENSOR_NAME_1,
 };
 
@@ -1475,7 +1529,7 @@ static struct platform_device rk29_soc_camera_pdrv_1 = {
        .name   = "soc-camera-pdrv",
        .id     = 1,
        .dev    = {
-               .init_name = SENSOR_NAME_1,
+               .init_name = SENSOR_DEVICE_NAME_1,
                .platform_data = &rk29_iclink_1,
        },
 };
@@ -2167,10 +2221,10 @@ static struct platform_device *devices[] __initdata = {
 #endif
 #ifdef CONFIG_VIDEO_RK29
        &rk29_device_camera,      /* ddl@rock-chips.com : camera support  */
-       #if (SENSOR_IIC_ADDR_0 != 0x00)
+       #if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)
        &rk29_soc_camera_pdrv_0,
        #endif
-       #if (SENSOR_IIC_ADDR_1 != 0x00)
+       #if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)
        &rk29_soc_camera_pdrv_1,
        #endif
        &android_pmem_cam_device,
index 03058ec28009e3be8f3f7bc38f269ce732421c1d..665798cb1294869a0e8880e9d70d7a95df4097be 100755 (executable)
@@ -44,7 +44,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define MAX(x,y)    ((x>y) ? x: y)
 
 /* Sensor Driver Configuration */
-#define SENSOR_NAME mt9p111
+#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
@@ -68,7 +68,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_Scene         1
 #define CONFIG_SENSOR_DigitalZoom   0
 #define CONFIG_SENSOR_Exposure      0
-#define CONFIG_SENSOR_Flash         0
+#define CONFIG_SENSOR_Flash         1
 #define CONFIG_SENSOR_Mirror        0
 #define CONFIG_SENSOR_Flip          0
 #define CONFIG_SENSOR_Focus         0
@@ -2230,6 +2230,7 @@ struct sensor
        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)
@@ -2266,10 +2267,13 @@ static int sensor_task_lock(struct i2c_client *client, int lock)
                                preempt_enable();
                }
        }
-#endif
+    
        return 0;
 sensor_task_lock_err:
-       return -1;
+       return -1;    
+#else
+    return 0;
+#endif
 }
 
 /* sensor register write */
@@ -2577,7 +2581,7 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
        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:
@@ -2609,7 +2613,7 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
                }
                default:
                {
-                       SENSOR_TR("%s power cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd);
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
                        break;
                }
        }
@@ -2758,7 +2762,7 @@ static int sensor_deactivate(struct i2c_client *client)
        /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */
        icd->user_width = SENSOR_INIT_WIDTH;
     icd->user_height = SENSOR_INIT_HEIGHT;
-
+       msleep(100);
        return 0;
 }
 static  struct reginfo sensor_power_down_sequence[]=
@@ -2873,67 +2877,248 @@ static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f)
 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 (((set_w >= 640) && (set_h >= 480)) && (sensor_vga[0].reg!=SEQUENCE_END)) {
+            winseqe_set_addr = sensor_vga;
+            *ret_w = 640;
+            *ret_h = 480;
+        } 
+        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 (((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;
-    }
+        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;
 }
 
 static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
     struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
     struct v4l2_pix_format *pix = &f->fmt.pix;
     struct reginfo *winseqe_set_addr=NULL;
-    int ret = 0, set_w,set_h;
+    int ret = 0, set_w,set_h,cnt;
     u16 seq_state=0;
         
        if (sensor->info_priv.pixfmt != pix->pixelformat) {
@@ -2989,16 +3174,23 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                SENSOR_TR("%s Preview 2 Capture failed\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)
-              return ret;
-            SENSOR_DG("mt9p111 Preview seq_state = 0x%x\n",seq_state);
-         } while(seq_state != 0x07);
-        
+              goto sensor_s_fmt_end;
+            cnt++;
+            SENSOR_DG("mt9p111 Preview 2 Capture seq_state = 0x%x\n",seq_state);
+         } while((seq_state != 0x07) && (cnt < 20));
+
+        #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        
                sensor->info_priv.capture_w = set_w;
                sensor->info_priv.capture_h = set_h;
                sensor->info_priv.snap2preview = true;
@@ -3009,20 +3201,26 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
                        SENSOR_TR("%s Capture 2 Preview failed\n", SENSOR_NAME_STRING());
                        goto sensor_s_fmt_end;
                }
-
-        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)
-              return ret;
-            SENSOR_DG("mt9p111 Snapshot  seq_state = 0x%x\n",seq_state);
-          } while(seq_state != 0x03);
-
             
-                       sensor->info_priv.preview_w = pix->width;
-                       sensor->info_priv.preview_h = pix->height;
-                       sensor->info_priv.snap2preview = false;
+            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));
+            
+            #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 = pix->width;
+               sensor->info_priv.preview_h = pix->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__,pix->width,pix->height);
                }
@@ -3334,6 +3532,27 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4
     return -EINVAL;
 }
 #endif
+#if CONFIG_SENSOR_Flash
+static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value)
+{
+    struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+    struct sensor *sensor = to_sensor(client);
+       const struct v4l2_queryctrl *qctrl_info;
+    
+    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
 #if CONFIG_SENSOR_Focus
 static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
 {
@@ -3799,6 +4018,8 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
 #if CONFIG_SENSOR_Flash
         case V4L2_CID_FLASH:
             {
+                if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
+                    return -EINVAL;
                 sensor->info_priv.flash = ext_ctrl->value;
 
                 SENSOR_DG("%s flash is %x\n",SENSOR_NAME_STRING(), sensor->info_priv.flash);
@@ -3872,7 +4093,6 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
                sensor->info_priv.enable = 0;
        }
 
-sensor_s_stream_end:
        return 0;
 }
 
@@ -3945,8 +4165,10 @@ sensor_video_probe_err:
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
        struct i2c_client *client = sd->priv;
+    struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
-
+    int ret = 0;
+    
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
        {
@@ -3957,7 +4179,36 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
+            /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
+               for this project */
+            #if CONFIG_SENSOR_Flash    
+            int i;
+               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(&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:
@@ -3966,8 +4217,8 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                        break;
                }
        }
-
-       return 0;
+sensor_ioctl_end:
+       return ret;
 
 }