camera: camera io config support power/reset/powerdown/flash
authorddl <ddl@rockchip.com>
Fri, 14 Jan 2011 05:23:10 +0000 (13:23 +0800)
committerddl <ddl@rockchip.com>
Fri, 14 Jan 2011 05:23:10 +0000 (13:23 +0800)
arch/arm/mach-rk29/board-rk29-aigo.c
arch/arm/mach-rk29/board-rk29-winaccord.c
arch/arm/mach-rk29/board-rk29sdk.c
arch/arm/mach-rk29/include/mach/rk29_camera.h
drivers/media/video/ov2655.c
drivers/media/video/ov2659.c
drivers/media/video/ov5642.c
drivers/media/video/rk29_camera_oneframe.c
include/media/soc_camera.h

index 8f01bce28f62fe3585641493508a1843dc3af415..c421835d7e77cfe4ecf641d9ec16cdd80556f0b8 100644 (file)
@@ -211,7 +211,7 @@ static int rk29_fb_io_init(struct rk29_fb_setting_info *fb_setting)
         gpio_direction_output(FB_LCD_CABC_EN_PIN, 0);\r
         gpio_set_value(FB_LCD_CABC_EN_PIN, GPIO_LOW);\r
     }\r
-    \r
+\r
     return ret;\r
 }\r
 \r
@@ -392,28 +392,28 @@ int it7260_init_platform_hw(void)
       return -EIO;\r
     }\r
 \r
-    gpio_direction_output(TOUCH_PWR_PIN, 0);    \r
+    gpio_direction_output(TOUCH_PWR_PIN, 0);\r
     gpio_set_value(TOUCH_PWR_PIN,GPIO_LOW);\r
 \r
-    msleep(100);       \r
+    msleep(100);\r
+\r
+    gpio_direction_output(TOUCH_INT_PIN, 0);\r
+    gpio_set_value(TOUCH_INT_PIN,GPIO_LOW);\r
 \r
-    gpio_direction_output(TOUCH_INT_PIN, 0);   \r
-    gpio_set_value(TOUCH_INT_PIN,GPIO_LOW);    \r
\r
-    msleep(100);  \r
-    gpio_set_value(TOUCH_PWR_PIN,GPIO_HIGH);   \r
-    msleep(100);       \r
+    msleep(100);\r
+    gpio_set_value(TOUCH_PWR_PIN,GPIO_HIGH);\r
+    msleep(100);\r
 \r
     gpio_direction_output(TOUCH_RESET_PIN, 0);\r
     mdelay(100);\r
     gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);\r
     mdelay(100);\r
     gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);\r
-       \r
-    gpio_direction_output(TOUCH_INT_PIN, 1);    \r
-    gpio_pull_updown(TOUCH_INT_PIN, 0);  \r
-       \r
-  \r
+\r
+    gpio_direction_output(TOUCH_INT_PIN, 1);\r
+    gpio_pull_updown(TOUCH_INT_PIN, 0);\r
+\r
+\r
     return 0;\r
 }\r
 \r
@@ -518,7 +518,7 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
                .type                   = "stc3100",\r
                .addr           = 0x70,\r
                .flags                  = 0,\r
-       }, \r
+       },\r
 #endif\r
 #if defined (CONFIG_BATTERY_BQ27510)\r
        {\r
@@ -617,235 +617,389 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
  * author: ddl@rock-chips.com\r
  *****************************************************************************************/\r
 #ifdef CONFIG_VIDEO_RK29\r
-#define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_OV5642                      /* back camera sensor */\r
-#define SENSOR_IIC_ADDR_0          0x78\r
-#define SENSOR_IIC_ADAPTER_ID_0    1\r
-#define SENSOR_POWER_PIN_0         RK29_PIN6_PB7\r
-#define SENSOR_RESET_PIN_0         INVALID_GPIO\r
-#define SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L\r
-#define SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L\r
-\r
-\r
-#define SENSOR_NAME_1 RK29_CAM_SENSOR_NAME_OV2659                      /* front camera sensor */\r
-#define SENSOR_IIC_ADDR_1          0x60\r
-#define SENSOR_IIC_ADAPTER_ID_1    1\r
-#define SENSOR_POWER_PIN_1         RK29_PIN5_PD7\r
-#define SENSOR_RESET_PIN_1         INVALID_GPIO\r
-#define SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L\r
-#define SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L\r
-\r
-static int rk29_sensor_io_init(void);\r
-static int rk29_sensor_io_deinit(void);\r
-\r
-struct rk29camera_platform_data rk29_camera_platform_data = {\r
-    .io_init = rk29_sensor_io_init,\r
-    .io_deinit = rk29_sensor_io_deinit,\r
-    .gpio_res = {\r
-        {\r
-            .gpio_reset = SENSOR_RESET_PIN_0,\r
-            .gpio_power = SENSOR_POWER_PIN_0,\r
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_0|SENSOR_RESETACTIVE_LEVEL_0),\r
-            .dev_name = SENSOR_NAME_0,\r
-        }, {\r
-            .gpio_reset = SENSOR_RESET_PIN_1,\r
-            .gpio_power = SENSOR_POWER_PIN_1,\r
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_1),\r
-            .dev_name = SENSOR_NAME_1,\r
-        }\r
-    },\r
-       #ifdef CONFIG_VIDEO_RK29_WORK_IPP\r
-       .meminfo = {\r
-           .name  = "camera_ipp_mem",\r
-               .start = MEM_CAMIPP_BASE,\r
-               .size   = MEM_CAMIPP_SIZE,\r
-       }\r
-       #endif\r
-};\r
-\r
-static int rk29_sensor_io_init(void)\r
-{\r
-    int ret = 0, i;\r
-    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
-       unsigned int camera_ioflag;\r
-\r
-    for (i=0; i<2; i++) {\r
-        camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;\r
-        camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;\r
-               camera_ioflag = rk29_camera_platform_data.gpio_res[i].gpio_flag;\r
-\r
-        if (camera_power != INVALID_GPIO) {\r
-            ret = gpio_request(camera_power, "camera power");\r
-            if (ret)\r
-                continue;\r
-\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
-                       //printk("\n%s....%d  %x   \n",__FUNCTION__,__LINE__,(((~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
-                if (camera_power != INVALID_GPIO)\r
-                    gpio_free(camera_power);\r
-\r
-                continue;\r
-            }\r
-\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
-                       //printk("\n%s....%d  %x \n",__FUNCTION__,__LINE__,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-\r
-        }\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-static int rk29_sensor_io_deinit(void)\r
-{\r
-    unsigned int i;\r
-    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
-\r
-    //printk("\n%s....%d    ******** ddl *********\n",__FUNCTION__,__LINE__);\r
-\r
-    for (i=0; i<2; i++) {\r
-        camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;\r
-        camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;\r
-\r
-        if (camera_power != INVALID_GPIO){\r
-            gpio_direction_input(camera_power);\r
-            gpio_free(camera_power);\r
-        }\r
-\r
-        if (camera_reset != INVALID_GPIO)  {\r
-            gpio_direction_input(camera_reset);\r
-            gpio_free(camera_reset);\r
-        }\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static int rk29_sensor_power(struct device *dev, int on)\r
-{\r
-    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;\r
-       unsigned int camera_ioflag;\r
-\r
-    if(rk29_camera_platform_data.gpio_res[0].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) {\r
-        camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;\r
-        camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;\r
-               camera_ioflag = rk29_camera_platform_data.gpio_res[0].gpio_flag;\r
-    } else if (rk29_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk29_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) {\r
-        camera_reset = rk29_camera_platform_data.gpio_res[1].gpio_reset;\r
-        camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;\r
-               camera_ioflag = rk29_camera_platform_data.gpio_res[1].gpio_flag;\r
-    }\r
-\r
-    if (camera_reset != INVALID_GPIO) {\r
-        gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-        //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-    }\r
-    if (camera_power != INVALID_GPIO)  {\r
-        if (on) {\r
-               gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
-               } else {\r
-                       gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
-                       msleep(100);\r
-               }\r
-       }\r
-\r
-    if (camera_reset != INVALID_GPIO)  {\r
-               if (on) {\r
-               msleep(3);          /* delay 3 ms */\r
-               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-               //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
-               }\r
-    }\r
-    return 0;\r
+#define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_OV5642                      /* back camera sensor */
+#define SENSOR_IIC_ADDR_0          0x78
+#define SENSOR_IIC_ADAPTER_ID_0    1
+#define SENSOR_POWER_PIN_0         INVALID_GPIO
+#define SENSOR_RESET_PIN_0         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_0       RK29_PIN6_PB7
+#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_OV2659                      /* front camera sensor */
+#define SENSOR_IIC_ADDR_1          0x60
+#define SENSOR_IIC_ADAPTER_ID_1    1
+#define SENSOR_POWER_PIN_1         INVALID_GPIO
+#define SENSOR_RESET_PIN_1         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_1       RK29_PIN5_PD7
+#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_H
+#define SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L\r
+\r
+static int rk29_sensor_io_init(void);
+static int rk29_sensor_io_deinit(int sensor);
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
+
+struct rk29camera_platform_data rk29_camera_platform_data = {
+    .io_init = rk29_sensor_io_init,
+    .io_deinit = rk29_sensor_io_deinit,
+    .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_init = 0,
+            .dev_name = SENSOR_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_init = 0,
+            .dev_name = SENSOR_NAME_1,
+        }
+    },
+       #ifdef CONFIG_VIDEO_RK29_WORK_IPP
+       .meminfo = {
+           .name  = "camera_ipp_mem",
+               .start = MEM_CAMIPP_BASE,
+               .size   = MEM_CAMIPP_SIZE,
+       }
+       #endif
+};
+
+static int rk29_sensor_io_init(void)
+{
+    int ret = 0, i;
+    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
+       unsigned int camera_ioflag;
+
+    for (i=0; i<2; i++) {
+        camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;
+        camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;
+               camera_powerdown = rk29_camera_platform_data.gpio_res[i].gpio_powerdown;
+        camera_flash = rk29_camera_platform_data.gpio_res[i].gpio_flash;
+               camera_ioflag = rk29_camera_platform_data.gpio_res[i].gpio_flag;
+               rk29_camera_platform_data.gpio_res[i].gpio_init = 0;
+
+        if (camera_power != INVALID_GPIO) {
+            ret = gpio_request(camera_power, "camera power");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK;
+            gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+            gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+
+                       //printk("\n%s....power pin(%d) init success(0x%x)  \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+
+        }
+
+        if (camera_reset != INVALID_GPIO) {
+            ret = gpio_request(camera_reset, "camera reset");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK;
+            gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+            gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+
+                       //printk("\n%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+
+        }
+
+               if (camera_powerdown != INVALID_GPIO) {
+            ret = gpio_request(camera_powerdown, "camera powerdown");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK;
+            gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+            gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+
+                       //printk("\n%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+
+        }
+
+               if (camera_flash != INVALID_GPIO) {
+            ret = gpio_request(camera_flash, "camera flash");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK;
+            gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+            gpio_direction_output(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+
+                       //printk("\n%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));\r
+
+        }
+               continue;
+sensor_io_int_loop_end:
+               rk29_sensor_io_deinit(i);
+               continue;
+    }
+
+    return 0;
+}
+
+static int rk29_sensor_io_deinit(int sensor)
+{
+    unsigned int i;
+    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
+
+    camera_reset = rk29_camera_platform_data.gpio_res[sensor].gpio_reset;
+    camera_power = rk29_camera_platform_data.gpio_res[sensor].gpio_power;
+       camera_powerdown = rk29_camera_platform_data.gpio_res[sensor].gpio_powerdown;
+    camera_flash = rk29_camera_platform_data.gpio_res[sensor].gpio_flash;
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) {
+           if (camera_power != INVALID_GPIO) {
+               gpio_direction_input(camera_power);
+               gpio_free(camera_power);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) {
+           if (camera_reset != INVALID_GPIO)  {
+               gpio_direction_input(camera_reset);
+               gpio_free(camera_reset);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {
+           if (camera_powerdown != INVALID_GPIO)  {
+               gpio_direction_input(camera_powerdown);
+               gpio_free(camera_powerdown);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) {
+           if (camera_flash != INVALID_GPIO)  {
+               gpio_direction_input(camera_flash);
+               gpio_free(camera_flash);
+           }
+       }
+
+       rk29_camera_platform_data.gpio_res[sensor].gpio_init = 0;
+    return 0;
+}
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on)
+{
+    unsigned int camera_power=INVALID_GPIO,camera_reset=INVALID_GPIO, camera_powerdown=INVALID_GPIO,camera_flash = INVALID_GPIO;
+       unsigned int camera_ioflag,camera_io_init;
+       int ret = RK29_CAM_IO_SUCCESS;
+
+    if(rk29_camera_platform_data.gpio_res[0].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) {
+               camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;
+               camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[0].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[0].gpio_flash;
+               camera_ioflag = rk29_camera_platform_data.gpio_res[0].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[0].gpio_init;
+    } else if (rk29_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk29_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) {
+       camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;
+        camera_reset = rk29_camera_platform_data.gpio_res[1].gpio_reset;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[1].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[1].gpio_flash;
+               camera_ioflag = rk29_camera_platform_data.gpio_res[1].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[1].gpio_init;
+    }
+
+       switch (cmd)
+       {
+               case Cam_Power:
+               {
+                       if (camera_power != INVALID_GPIO)  {
+                               if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {
+                               if (on) {
+                                       gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+                                               msleep(10);
+                                       } else {
+                                               gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
+                                       }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+               case Cam_Reset:
+               {
+                       if (camera_reset != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+                                       } else {
+                                               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));\r
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+
+               case Cam_PowerDown:
+               {
+                       if (camera_powerdown != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+                                       } else {
+                                               gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));\r
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_powerdown);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+
+               case Cam_Flash:
+               {
+                       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));\r
+                                       } 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));\r
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_flash);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+
+               default:
+               {
+                       printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);
+                       break;
+               }
+       }
+    return ret;
 }\r
-#if (SENSOR_IIC_ADDR_0 != 0x00)\r
-static struct i2c_board_info rk29_i2c_cam_info_0[] = {\r
-       {\r
-               I2C_BOARD_INFO(SENSOR_NAME_0, SENSOR_IIC_ADDR_0>>1)\r
-       },\r
-};\r
-\r
-struct soc_camera_link rk29_iclink_0 = {\r
-       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
-       .power          = rk29_sensor_power,\r
-       .board_info     = &rk29_i2c_cam_info_0[0],\r
-       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_0,\r
-       .module_name    = SENSOR_NAME_0,\r
-};\r
-\r
-/*platform_device : soc-camera need  */\r
-struct platform_device rk29_soc_camera_pdrv_0 = {\r
-       .name   = "soc-camera-pdrv",\r
-       .id     = 0,\r
-       .dev    = {\r
-               .init_name = SENSOR_NAME_0,\r
-               .platform_data = &rk29_iclink_0,\r
-       },\r
-};\r
-#endif\r
-static struct i2c_board_info rk29_i2c_cam_info_1[] = {\r
-       {\r
-               I2C_BOARD_INFO(SENSOR_NAME_1, SENSOR_IIC_ADDR_1>>1)\r
-       },\r
-};\r
-\r
-struct soc_camera_link rk29_iclink_1 = {\r
-       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
-       .power          = rk29_sensor_power,\r
-       .board_info     = &rk29_i2c_cam_info_1[0],\r
-       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_1,\r
-       .module_name    = SENSOR_NAME_1,\r
-};\r
-\r
-/*platform_device : soc-camera need  */\r
-struct platform_device rk29_soc_camera_pdrv_1 = {\r
-       .name   = "soc-camera-pdrv",\r
-       .id     = 1,\r
-       .dev    = {\r
-               .init_name = SENSOR_NAME_1,\r
-               .platform_data = &rk29_iclink_1,\r
-       },\r
-};\r
-\r
-\r
-static u64 rockchip_device_camera_dmamask = 0xffffffffUL;\r
-struct resource rk29_camera_resource[] = {\r
-       [0] = {\r
-               .start = RK29_VIP_PHYS,\r
-               .end   = RK29_VIP_PHYS + RK29_VIP_SIZE - 1,\r
-               .flags = IORESOURCE_MEM,\r
-       },\r
-       [1] = {\r
-               .start = IRQ_VIP,\r
-               .end   = IRQ_VIP,\r
-               .flags = IORESOURCE_IRQ,\r
-       }\r
-};\r
-\r
-/*platform_device : */\r
-struct platform_device rk29_device_camera = {\r
-       .name             = RK29_CAM_DRV_NAME,\r
-       .id               = RK29_CAM_PLATFORM_DEV_ID,               /* This is used to put cameras on this interface */\r
-       .num_resources    = ARRAY_SIZE(rk29_camera_resource),\r
-       .resource         = rk29_camera_resource,\r
-       .dev            = {\r
-               .dma_mask = &rockchip_device_camera_dmamask,\r
-               .coherent_dma_mask = 0xffffffffUL,\r
-               .platform_data  = &rk29_camera_platform_data,\r
-       }\r
-};\r
+static int rk29_sensor_power(struct device *dev, int on)
+{
+       rk29_sensor_ioctrl(dev,Cam_Power,on);
+    return 0;
+}
+static int rk29_sensor_reset(struct device *dev)
+{
+       rk29_sensor_ioctrl(dev,Cam_Reset,1);
+       msleep(2);
+       rk29_sensor_ioctrl(dev,Cam_Reset,0);
+       return 0;
+}
+static int rk29_sensor_powerdown(struct device *dev, int on)
+{
+       return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);
+}
+#if (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)
+       },
+};
+
+struct soc_camera_link rk29_iclink_0 = {
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
+       .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
+       .board_info     = &rk29_i2c_cam_info_0[0],
+       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_0,
+       .module_name    = SENSOR_NAME_0,
+};
+
+/*platform_device : soc-camera need  */
+struct platform_device rk29_soc_camera_pdrv_0 = {
+       .name   = "soc-camera-pdrv",
+       .id     = 0,
+       .dev    = {
+               .init_name = SENSOR_NAME_0,
+               .platform_data = &rk29_iclink_0,
+       },
+};
+#endif
+static struct i2c_board_info rk29_i2c_cam_info_1[] = {
+       {
+               I2C_BOARD_INFO(SENSOR_NAME_1, SENSOR_IIC_ADDR_1>>1)
+       },
+};
+
+struct soc_camera_link rk29_iclink_1 = {
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
+       .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
+       .board_info     = &rk29_i2c_cam_info_1[0],
+       .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_1,
+       .module_name    = SENSOR_NAME_1,
+};
+
+/*platform_device : soc-camera need  */
+struct platform_device rk29_soc_camera_pdrv_1 = {
+       .name   = "soc-camera-pdrv",
+       .id     = 1,
+       .dev    = {
+               .init_name = SENSOR_NAME_1,
+               .platform_data = &rk29_iclink_1,
+       },
+};
+
+
+static u64 rockchip_device_camera_dmamask = 0xffffffffUL;
+struct resource rk29_camera_resource[] = {
+       [0] = {
+               .start = RK29_VIP_PHYS,
+               .end   = RK29_VIP_PHYS + RK29_VIP_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_VIP,
+               .end   = IRQ_VIP,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+/*platform_device : */
+struct platform_device rk29_device_camera = {
+       .name             = RK29_CAM_DRV_NAME,
+       .id               = RK29_CAM_PLATFORM_DEV_ID,               /* This is used to put cameras on this interface */
+       .num_resources    = ARRAY_SIZE(rk29_camera_resource),
+       .resource         = rk29_camera_resource,
+       .dev            = {
+               .dma_mask = &rockchip_device_camera_dmamask,
+               .coherent_dma_mask = 0xffffffffUL,
+               .platform_data  = &rk29_camera_platform_data,
+       }
+};
 #endif\r
 /*****************************************************************************************\r
  * backlight  devices\r
@@ -933,8 +1087,8 @@ static struct regulator_init_data rk29_pwm_regulator_data = {
                .name = "PWM2",\r
                .min_uV =  950000,
                .max_uV = 1400000,\r
-               .apply_uV = 1,          
-               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,           
+               .apply_uV = 1,\r
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,\r
        },
        .num_consumer_supplies = ARRAY_SIZE(pwm_consumers),\r
        .consumer_supplies = pwm_consumers,\r
@@ -972,7 +1126,7 @@ static int rk29_sdmmc0_cfg_gpio(void)
        rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);\r
        rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);\r
        rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);\r
-       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);   \r
+       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);\r
        rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   ///GPIO5H_SDMMC0_PWR_EN);  ///GPIO5H_GPIO5D5);\r
        gpio_request(RK29_PIN5_PD5,"sdmmc");\r
        gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH);\r
@@ -1010,7 +1164,7 @@ static int rk29_sdmmc1_cfg_gpio(void)
        return 0;\r
 }\r
 
-#ifdef CONFIG_WIFI_CONTROL_FUNC 
+#ifdef CONFIG_WIFI_CONTROL_FUNC\r
 static int rk29sdk_wifi_status(struct device *dev);
 static int rk29sdk_wifi_status_register(void (*callback)(int card_presend, void *dev_id), void *dev_id);\r
 #endif
@@ -1069,27 +1223,27 @@ static int rk29sdk_wifi_bt_gpio_control_init(void)
 {
     if (gpio_request(RK29SDK_WIFI_BT_GPIO_POWER_N, "wifi_bt_power")) {
            pr_info("%s: request wifi_bt power gpio failed\n", __func__);
-           return -1; 
+           return -1;\r
     }
-   
+\r
     if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) {
            pr_info("%s: request wifi reset gpio failed\n", __func__);
            gpio_free(RK29SDK_WIFI_BT_GPIO_POWER_N);
            return -1;
     }
-   
+\r
     if (gpio_request(RK29SDK_BT_GPIO_RESET_N, "bt reset")) {
           pr_info("%s: request bt reset gpio failed\n", __func__);
           gpio_free(RK29SDK_WIFI_GPIO_RESET_N);
           return -1;
     }
-   
+\r
     gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
     gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N,    GPIO_LOW);
-    gpio_direction_output(RK29SDK_BT_GPIO_RESET_N,      GPIO_LOW); 
-    
+    gpio_direction_output(RK29SDK_BT_GPIO_RESET_N,      GPIO_LOW);\r
+\r
     pr_info("%s: init finished\n",__func__);
-   
+\r
     return 0;
 }
 
@@ -1374,7 +1528,7 @@ static struct platform_device *devices[] __initdata = {
  *****************************************************************************************/\r
 static int rk29_vmac_register_set(void)\r
 {\r
-       //config rk29 vmac as rmii, 100MHz \r
+       //config rk29 vmac as rmii, 100MHz\r
        u32 value= readl(RK29_GRF_BASE + 0xbc);\r
        value = (value & 0xfff7ff) | (0x400);\r
        writel(value, RK29_GRF_BASE + 0xbc);\r
@@ -1639,7 +1793,7 @@ static void __init machine_rk29_init_irq(void)
 static void rk29_pm_power_off(void)\r
 {\r
        printk(KERN_ERR "rk29_pm_power_off start...\n");\r
-       \r
+\r
        gpio_direction_output(POWER_ON_PIN, GPIO_LOW);\r
        while(1);\r
 }\r
@@ -1647,7 +1801,7 @@ static void rk29_pm_power_off(void)
 static void __init machine_rk29_board_init(void)\r
 {\r
         rk29_board_iomux_init();\r
-       gpio_request(POWER_ON_PIN,"poweronpin");        \r
+       gpio_request(POWER_ON_PIN,"poweronpin");\r
        gpio_set_value(POWER_ON_PIN, GPIO_HIGH);\r
        gpio_direction_output(POWER_ON_PIN, GPIO_HIGH);\r
        pm_power_off = rk29_pm_power_off;\r
index e9fb59b6e040249696161bcb5fee6b17f8027896..61a6294b7084fe1e30b9d5345ca270f47ac6b0f7 100644 (file)
@@ -552,36 +552,51 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
 #define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_OV5642                      /* back camera sensor */
 #define SENSOR_IIC_ADDR_0          0x00
 #define SENSOR_IIC_ADAPTER_ID_0    1
-#define SENSOR_POWER_PIN_0         RK29_PIN6_PB7
+#define SENSOR_POWER_PIN_0         INVALID_GPIO
 #define SENSOR_RESET_PIN_0         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_0       INVALID_GPIO
+#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_OV2655                      /* front camera sensor */
 #define SENSOR_IIC_ADDR_1          0x60
 #define SENSOR_IIC_ADAPTER_ID_1    1
-#define SENSOR_POWER_PIN_1         RK29_PIN5_PD7
+#define SENSOR_POWER_PIN_1         INVALID_GPIO
 #define SENSOR_RESET_PIN_1         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_1       RK29_PIN5_PD7
+#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_H
+#define SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
 
 static int rk29_sensor_io_init(void);
-static int rk29_sensor_io_deinit(void);
+static int rk29_sensor_io_deinit(int sensor);
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
 
 struct rk29camera_platform_data rk29_camera_platform_data = {
     .io_init = rk29_sensor_io_init,
     .io_deinit = rk29_sensor_io_deinit,
+    .sensor_ioctrl = rk29_sensor_ioctrl,
     .gpio_res = {
         {
             .gpio_reset = SENSOR_RESET_PIN_0,
             .gpio_power = SENSOR_POWER_PIN_0,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_0|SENSOR_RESETACTIVE_LEVEL_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_init = 0,
             .dev_name = SENSOR_NAME_0,
         }, {
             .gpio_reset = SENSOR_RESET_PIN_1,
             .gpio_power = SENSOR_POWER_PIN_1,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_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_init = 0,
             .dev_name = SENSOR_NAME_1,
         }
     },
@@ -598,109 +613,247 @@ static int rk29_sensor_io_init(void)
 {
     int ret = 0, i;
     unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
        unsigned int camera_ioflag;
 
     for (i=0; i<2; i++) {
         camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;
         camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;
+               camera_powerdown = rk29_camera_platform_data.gpio_res[i].gpio_powerdown;
+        camera_flash = rk29_camera_platform_data.gpio_res[i].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[i].gpio_flag;
+               rk29_camera_platform_data.gpio_res[i].gpio_init = 0;
 
         if (camera_power != INVALID_GPIO) {
             ret = gpio_request(camera_power, "camera power");
             if (ret)
-                continue;
-
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK;
             gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
             gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
 
-                       //printk("\n%s....%d  %x   \n",__FUNCTION__,__LINE__,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                       //printk("\n%s....power pin(%d) init success(0x%x)  \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
 
         }
 
         if (camera_reset != INVALID_GPIO) {
             ret = gpio_request(camera_reset, "camera reset");
-            if (ret) {
-                if (camera_power != INVALID_GPIO)
-                    gpio_free(camera_power);
-
-                continue;
-            }
-
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK;
             gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
             gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
 
-                       //printk("\n%s....%d  %x \n",__FUNCTION__,__LINE__,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                       //printk("\n%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+
+        }
+
+               if (camera_powerdown != INVALID_GPIO) {
+            ret = gpio_request(camera_powerdown, "camera powerdown");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK;
+            gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+            gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+
+                       //printk("\n%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS));
 
         }
+
+               if (camera_flash != INVALID_GPIO) {
+            ret = gpio_request(camera_flash, "camera flash");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK;
+            gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+            gpio_direction_output(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+
+                       //printk("\n%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+
+        }
+               continue;
+sensor_io_int_loop_end:
+               rk29_sensor_io_deinit(i);
+               continue;
     }
 
     return 0;
 }
 
-static int rk29_sensor_io_deinit(void)
+static int rk29_sensor_io_deinit(int sensor)
 {
     unsigned int i;
     unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
+
+    camera_reset = rk29_camera_platform_data.gpio_res[sensor].gpio_reset;
+    camera_power = rk29_camera_platform_data.gpio_res[sensor].gpio_power;
+       camera_powerdown = rk29_camera_platform_data.gpio_res[sensor].gpio_powerdown;
+    camera_flash = rk29_camera_platform_data.gpio_res[sensor].gpio_flash;
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) {
+           if (camera_power != INVALID_GPIO) {
+               gpio_direction_input(camera_power);
+               gpio_free(camera_power);
+           }
+       }
 
-    //printk("\n%s....%d    ******** ddl *********\n",__FUNCTION__,__LINE__);
-
-    for (i=0; i<2; i++) {
-        camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) {
+           if (camera_reset != INVALID_GPIO)  {
+               gpio_direction_input(camera_reset);
+               gpio_free(camera_reset);
+           }
+       }
 
-        if (camera_power != INVALID_GPIO){
-            gpio_direction_input(camera_power);
-            gpio_free(camera_power);
-        }
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {
+           if (camera_powerdown != INVALID_GPIO)  {
+               gpio_direction_input(camera_powerdown);
+               gpio_free(camera_powerdown);
+           }
+       }
 
-        if (camera_reset != INVALID_GPIO)  {
-            gpio_direction_input(camera_reset);
-            gpio_free(camera_reset);
-        }
-    }
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) {
+           if (camera_flash != INVALID_GPIO)  {
+               gpio_direction_input(camera_flash);
+               gpio_free(camera_flash);
+           }
+       }
 
+       rk29_camera_platform_data.gpio_res[sensor].gpio_init = 0;
     return 0;
 }
-
-
-static int rk29_sensor_power(struct device *dev, int on)
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on)
 {
-    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
-       unsigned int camera_ioflag;
+    unsigned int camera_power=INVALID_GPIO,camera_reset=INVALID_GPIO, camera_powerdown=INVALID_GPIO,camera_flash = INVALID_GPIO;
+       unsigned int camera_ioflag,camera_io_init;
+       int ret = RK29_CAM_IO_SUCCESS;
 
     if(rk29_camera_platform_data.gpio_res[0].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) {
-        camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;
+               camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;
+               camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[0].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[0].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[0].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[0].gpio_init;
     } else if (rk29_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk29_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) {
+       camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;
         camera_reset = rk29_camera_platform_data.gpio_res[1].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[1].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[1].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[1].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[1].gpio_init;
     }
 
-    if (camera_reset != INVALID_GPIO) {
-        gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-        //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-    }
-    if (camera_power != INVALID_GPIO)  {
-        if (on) {
-               gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-               } else {
-                       gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+       switch (cmd)
+       {
+               case Cam_Power:
+               {
+                       if (camera_power != INVALID_GPIO)  {
+                               if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {
+                               if (on) {
+                                       gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               msleep(10);
+                                       } else {
+                                               gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                       }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+               case Cam_Reset:
+               {
+                       if (camera_reset != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       } else {
+                                               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
                }
-       }
 
-    if (camera_reset != INVALID_GPIO)  {
-               if (on) {
-               msleep(3);          /* delay 3 ms */
-               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-               //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+               case Cam_PowerDown:
+               {
+                       if (camera_powerdown != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       } else {
+                                               gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_powerdown);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
                }
-    }
+
+               case Cam_Flash:
+               {
+                       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));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_flash);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+
+               default:
+               {
+                       printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);
+                       break;
+               }
+       }
+    return ret;
+}
+static int rk29_sensor_power(struct device *dev, int on)
+{
+       rk29_sensor_ioctrl(dev,Cam_Power,on);
     return 0;
 }
+static int rk29_sensor_reset(struct device *dev)
+{
+       rk29_sensor_ioctrl(dev,Cam_Reset,1);
+       msleep(2);
+       rk29_sensor_ioctrl(dev,Cam_Reset,0);
+       return 0;
+}
+static int rk29_sensor_powerdown(struct device *dev, int on)
+{
+       return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);
+}
 #if (SENSOR_IIC_ADDR_0 != 0x00)
 static struct i2c_board_info rk29_i2c_cam_info_0[] = {
        {
@@ -711,6 +864,7 @@ static struct i2c_board_info rk29_i2c_cam_info_0[] = {
 struct soc_camera_link rk29_iclink_0 = {
        .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
        .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_0[0],
        .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_0,
        .module_name    = SENSOR_NAME_0,
@@ -735,6 +889,7 @@ static struct i2c_board_info rk29_i2c_cam_info_1[] = {
 struct soc_camera_link rk29_iclink_1 = {
        .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
        .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_1[0],
        .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_1,
        .module_name    = SENSOR_NAME_1,
@@ -778,6 +933,7 @@ struct platform_device rk29_device_camera = {
        }
 };
 #endif
+
 /*****************************************************************************************
  * backlight  devices
  * author: nzy@rock-chips.com
index 1c03f403a8b32cbb98bccbb47310766c206b75af..a108c8efcf8e9a8be2c18e7cfe2dc43bf703510f 100755 (executable)
@@ -603,36 +603,51 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = {
 #define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_OV5642                      /* back camera sensor */
 #define SENSOR_IIC_ADDR_0          0x78
 #define SENSOR_IIC_ADAPTER_ID_0    1
-#define SENSOR_POWER_PIN_0         RK29_PIN6_PB7
+#define SENSOR_POWER_PIN_0         INVALID_GPIO
 #define SENSOR_RESET_PIN_0         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_0       RK29_PIN6_PB7
+#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_OV2659                      /* front camera sensor */
 #define SENSOR_IIC_ADDR_1          0x60
 #define SENSOR_IIC_ADAPTER_ID_1    1
-#define SENSOR_POWER_PIN_1         RK29_PIN5_PD7
+#define SENSOR_POWER_PIN_1         INVALID_GPIO
 #define SENSOR_RESET_PIN_1         INVALID_GPIO
+#define SENSOR_POWERDN_PIN_1       RK29_PIN5_PD7
+#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_H
+#define SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
 
 static int rk29_sensor_io_init(void);
-static int rk29_sensor_io_deinit(void);
+static int rk29_sensor_io_deinit(int sensor);
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
 
 struct rk29camera_platform_data rk29_camera_platform_data = {
     .io_init = rk29_sensor_io_init,
     .io_deinit = rk29_sensor_io_deinit,
+    .sensor_ioctrl = rk29_sensor_ioctrl,
     .gpio_res = {
         {
             .gpio_reset = SENSOR_RESET_PIN_0,
             .gpio_power = SENSOR_POWER_PIN_0,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_0|SENSOR_RESETACTIVE_LEVEL_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_init = 0,
             .dev_name = SENSOR_NAME_0,
         }, {
             .gpio_reset = SENSOR_RESET_PIN_1,
             .gpio_power = SENSOR_POWER_PIN_1,
-            .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_1|SENSOR_RESETACTIVE_LEVEL_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_init = 0,
             .dev_name = SENSOR_NAME_1,
         }
     },
@@ -649,110 +664,246 @@ static int rk29_sensor_io_init(void)
 {
     int ret = 0, i;
     unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
        unsigned int camera_ioflag;
 
     for (i=0; i<2; i++) {
         camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;
         camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;
+               camera_powerdown = rk29_camera_platform_data.gpio_res[i].gpio_powerdown;
+        camera_flash = rk29_camera_platform_data.gpio_res[i].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[i].gpio_flag;
+               rk29_camera_platform_data.gpio_res[i].gpio_init = 0;
 
         if (camera_power != INVALID_GPIO) {
             ret = gpio_request(camera_power, "camera power");
             if (ret)
-                continue;
-
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK;
             gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
             gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
 
-                       //printk("\n%s....%d  %x   \n",__FUNCTION__,__LINE__,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                       //printk("\n%s....power pin(%d) init success(0x%x)  \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
 
         }
 
         if (camera_reset != INVALID_GPIO) {
             ret = gpio_request(camera_reset, "camera reset");
-            if (ret) {
-                if (camera_power != INVALID_GPIO)
-                    gpio_free(camera_power);
-
-                continue;
-            }
-
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK;
             gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
             gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
 
-                       //printk("\n%s....%d  %x \n",__FUNCTION__,__LINE__,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                       //printk("\n%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
 
         }
-    }
 
-    return 0;
-}
+               if (camera_powerdown != INVALID_GPIO) {
+            ret = gpio_request(camera_powerdown, "camera powerdown");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK;
+            gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+            gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
 
-static int rk29_sensor_io_deinit(void)
-{
-    unsigned int i;
-    unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
+                       //printk("\n%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS));
 
-    //printk("\n%s....%d    ******** ddl *********\n",__FUNCTION__,__LINE__);
+        }
 
-    for (i=0; i<2; i++) {
-        camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;
+               if (camera_flash != INVALID_GPIO) {
+            ret = gpio_request(camera_flash, "camera flash");
+            if (ret)
+                               goto sensor_io_int_loop_end;
+                       rk29_camera_platform_data.gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK;
+            gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
+            gpio_direction_output(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
 
-        if (camera_power != INVALID_GPIO){
-            gpio_direction_input(camera_power);
-            gpio_free(camera_power);
-        }
+                       //printk("\n%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS));
 
-        if (camera_reset != INVALID_GPIO)  {
-            gpio_direction_input(camera_reset);
-            gpio_free(camera_reset);
         }
+               continue;
+sensor_io_int_loop_end:
+               rk29_sensor_io_deinit(i);
+               continue;
     }
 
     return 0;
 }
 
-
-static int rk29_sensor_power(struct device *dev, int on)
+static int rk29_sensor_io_deinit(int sensor)
 {
     unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO;
-       unsigned int camera_ioflag;
+       unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO;
+
+    camera_reset = rk29_camera_platform_data.gpio_res[sensor].gpio_reset;
+    camera_power = rk29_camera_platform_data.gpio_res[sensor].gpio_power;
+       camera_powerdown = rk29_camera_platform_data.gpio_res[sensor].gpio_powerdown;
+    camera_flash = rk29_camera_platform_data.gpio_res[sensor].gpio_flash;
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) {
+           if (camera_power != INVALID_GPIO) {
+               gpio_direction_input(camera_power);
+               gpio_free(camera_power);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) {
+           if (camera_reset != INVALID_GPIO)  {
+               gpio_direction_input(camera_reset);
+               gpio_free(camera_reset);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) {
+           if (camera_powerdown != INVALID_GPIO)  {
+               gpio_direction_input(camera_powerdown);
+               gpio_free(camera_powerdown);
+           }
+       }
+
+       if (rk29_camera_platform_data.gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) {
+           if (camera_flash != INVALID_GPIO)  {
+               gpio_direction_input(camera_flash);
+               gpio_free(camera_flash);
+           }
+       }
+
+       rk29_camera_platform_data.gpio_res[sensor].gpio_init = 0;
+    return 0;
+}
+static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on)
+{
+    unsigned int camera_power=INVALID_GPIO,camera_reset=INVALID_GPIO, camera_powerdown=INVALID_GPIO,camera_flash = INVALID_GPIO;
+       unsigned int camera_ioflag,camera_io_init;
+       int ret = RK29_CAM_IO_SUCCESS;
 
     if(rk29_camera_platform_data.gpio_res[0].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) {
-        camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;
+               camera_power = rk29_camera_platform_data.gpio_res[0].gpio_power;
+               camera_reset = rk29_camera_platform_data.gpio_res[0].gpio_reset;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[0].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[0].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[0].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[0].gpio_init;
     } else if (rk29_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk29_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) {
+       camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;
         camera_reset = rk29_camera_platform_data.gpio_res[1].gpio_reset;
-        camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power;
+        camera_powerdown = rk29_camera_platform_data.gpio_res[1].gpio_powerdown;
+               camera_flash = rk29_camera_platform_data.gpio_res[1].gpio_flash;
                camera_ioflag = rk29_camera_platform_data.gpio_res[1].gpio_flag;
+               camera_io_init = rk29_camera_platform_data.gpio_res[1].gpio_init;
     }
 
-    if (camera_reset != INVALID_GPIO) {
-        gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-        //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-    }
-    if (camera_power != INVALID_GPIO)  {
-        if (on) {
-               gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-               } else {
-                       gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-                       //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
-                       msleep(100);
+       switch (cmd)
+       {
+               case Cam_Power:
+               {
+                       if (camera_power != INVALID_GPIO)  {
+                               if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {
+                               if (on) {
+                                       gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               msleep(10);
+                                       } else {
+                                               gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                               //printk("\n%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));
+                                       }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+               case Cam_Reset:
+               {
+                       if (camera_reset != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_RESETACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       } else {
+                                               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                                       //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_reset);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
                }
-       }
 
-    if (camera_reset != INVALID_GPIO)  {
-               if (on) {
-               msleep(3);          /* delay 3 ms */
-               gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
-               //printk("\n%s..%s..ResetPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS));
+               case Cam_PowerDown:
+               {
+                       if (camera_powerdown != INVALID_GPIO) {
+                               if (camera_io_init & RK29_CAM_POWERDNACTIVE_MASK) {
+                                       if (on) {
+                                       gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,dev_name(dev),camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       } else {
+                                               gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                                       //printk("\n%s..%s..PowerDownPin= %d..PinLevel = %x   \n",__FUNCTION__,dev_name(dev), camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_powerdown);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
                }
-    }
+
+               case Cam_Flash:
+               {
+                       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));
+                               }
+                               } else {
+                                       ret = RK29_CAM_EIO_REQUESTFAIL;
+                                       printk("\n%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,dev_name(dev),camera_flash);
+                               }
+                   } else {
+                               ret = RK29_CAM_EIO_INVALID;
+                   }
+                       break;
+               }
+
+               default:
+               {
+                       printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd);
+                       break;
+               }
+       }
+    return ret;
+}
+static int rk29_sensor_power(struct device *dev, int on)
+{
+       rk29_sensor_ioctrl(dev,Cam_Power,on);
     return 0;
 }
+static int rk29_sensor_reset(struct device *dev)
+{
+       rk29_sensor_ioctrl(dev,Cam_Reset,1);
+       msleep(2);
+       rk29_sensor_ioctrl(dev,Cam_Reset,0);
+       return 0;
+}
+static int rk29_sensor_powerdown(struct device *dev, int on)
+{
+       return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);
+}
 #if (SENSOR_IIC_ADDR_0 != 0x00)
 static struct i2c_board_info rk29_i2c_cam_info_0[] = {
        {
@@ -763,6 +914,7 @@ static struct i2c_board_info rk29_i2c_cam_info_0[] = {
 struct soc_camera_link rk29_iclink_0 = {
        .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
        .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_0[0],
        .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_0,
        .module_name    = SENSOR_NAME_0,
@@ -787,6 +939,7 @@ static struct i2c_board_info rk29_i2c_cam_info_1[] = {
 struct soc_camera_link rk29_iclink_1 = {
        .bus_id         = RK29_CAM_PLATFORM_DEV_ID,
        .power          = rk29_sensor_power,
+       .powerdown  = rk29_sensor_powerdown,
        .board_info     = &rk29_i2c_cam_info_1[0],
        .i2c_adapter_id = SENSOR_IIC_ADAPTER_ID_1,
        .module_name    = SENSOR_NAME_1,
index c033e25d8656ad09ed10a970c628f2c30976000f..4e2bb358f7cfc1c49bbd413d152b33c3071e000a 100644 (file)
 #define RK29_CAM_DRV_NAME "rk29xx-camera"
 #define RK29_CAM_PLATFORM_DEV_ID 33
 
+#define INVALID_GPIO -1
+
+#define RK29_CAM_IO_SUCCESS 0
+#define RK29_CAM_EIO_INVALID -1
+#define RK29_CAM_EIO_REQUESTFAIL -2
+
 #define RK29_CAM_SENSOR_NAME_OV9650 "ov9650"
 #define RK29_CAM_SENSOR_NAME_OV2655 "ov2655"
 #define RK29_CAM_SENSOR_NAME_OV2659 "ov2659"
 #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  0x00
+#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    0x01
+#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)
+
 /* v4l2_subdev_core_ops.ioctl  ioctl_cmd macro */
 #define RK29_CAM_SUBDEV_ACTIVATE            0x00
 #define RK29_CAM_SUBDEV_DEACTIVATE          0x01
+#define RK29_CAM_SUBDEV_IOREQUEST                      0x02
+
+enum rk29camera_ioctrl_cmd
+{
+       Cam_Power,
+       Cam_Reset,
+       Cam_PowerDown,
+       Cam_Flash
+};
+
+enum rk29sensor_power_cmd
+{
+       Sensor_Reset,
+       Sensor_PowerDown,
+       Sensor_Flash
+};
 
 struct rk29camera_gpio_res {
     unsigned int gpio_reset;
     unsigned int gpio_power;
+       unsigned int gpio_powerdown;
+       unsigned int gpio_flash;
     unsigned int gpio_flag;
+       unsigned int gpio_init;
     const char *dev_name;
 };
 
@@ -60,7 +95,8 @@ struct rk29camera_mem_res {
 };
 struct rk29camera_platform_data {
     int (*io_init)(void);
-    int (*io_deinit)(void);
+    int (*io_deinit)(int sensor);
+       int (*sensor_ioctrl)(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
     struct rk29camera_gpio_res gpio_res[2];
        struct rk29camera_mem_res meminfo;
 };
index 4c346009f3be58d10c3e63f273bf7324d3c3bb0b..bf7233e73ec2a990ec0eef4632942ffc8515fab9 100755 (executable)
@@ -1438,8 +1438,11 @@ struct sensor
 #if CONFIG_SENSOR_I2C_NOSCHED
        atomic_t tasklock_cnt;
 #endif
+       struct rk29camera_platform_data *sensor_io_request;
 };
 
+static int sensor_deactivate(struct i2c_client *client);
+
 static struct sensor* to_sensor(const struct i2c_client *client)
 {
     return container_of(i2c_get_clientdata(client), struct sensor, subdev);
@@ -1596,7 +1599,49 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     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;
+
+
+       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);
+                       }
+               }
+               default:
+               {
+                       SENSOR_TR("%s power cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -1608,6 +1653,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
     /* soft reset */
        sensor_task_lock(client,1);
     ret = sensor_write(client, 0x3012, 0x80);
@@ -1710,12 +1760,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     return 0;
 sensor_INIT_ERR:
+       sensor_deactivate(client);
     return ret;
 }
 
-static int sensor_deactivate(struct v4l2_subdev *sd)
+static int sensor_deactivate(struct i2c_client *client)
 {
-       struct i2c_client *client = sd->priv;
+       struct soc_camera_device *icd = client->dev.platform_data;
 
        SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -1724,6 +1775,9 @@ static int sensor_deactivate(struct v4l2_subdev *sd)
     sensor_write(client, 0x30b0, 0x00);
        sensor_write(client, 0x30b1, 0x00);
        sensor_task_lock(client, 0);
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       msleep(100);
        return 0;
 }
 
@@ -1739,32 +1793,21 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 {
     int ret;
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct soc_camera_link *icl;
 
-
-    if (pm_msg.event == PM_EVENT_SUSPEND)
-    {
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
         SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
         ret = sensor_write_array(client, sensor_power_down_sequence) ;
-        if (ret != 0)
-        {
+        if (ret != 0) {
             SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
             return ret;
-        }
-        else
-        {
-            icl = to_soc_camera_link(icd);
-            if (icl->power) {
-                ret = icl->power(icd->pdev, 0);
-                if (ret < 0) {
-                                   SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
-                    return -EINVAL;
-                }
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
             }
         }
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
         return -EINVAL;
     }
@@ -1773,16 +1816,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 
 static int sensor_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_link *icl;
-    int ret;
+       int ret;
 
-    icl = to_soc_camera_link(icd);
-    if (icl->power) {
-        ret = icl->power(icd->pdev, 1);
-        if (ret < 0) {
-                       SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
-            return -EINVAL;
-        }
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
     }
 
        SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
@@ -2640,6 +2679,11 @@ static int sensor_video_probe(struct soc_camera_device *icd,
            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
                return -ENODEV;
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
     /* soft reset */
     ret = sensor_write(client, 0x3012, 0x80);
     if (ret != 0)
@@ -2687,16 +2731,28 @@ sensor_video_probe_err:
 }
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
+       struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
        {
                case RK29_CAM_SUBDEV_DEACTIVATE:
                {
-                       sensor_deactivate(sd);
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;
                        break;
                }
                default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
                        break;
+               }
        }
 
        return 0;
index 469b699b6b5913c7bb09d8b79253e18cf669680b..78bc37af297099156fc627f43217f0a85703d36d 100755 (executable)
@@ -1242,9 +1242,10 @@ struct sensor
 #if CONFIG_SENSOR_I2C_NOSCHED
        atomic_t tasklock_cnt;
 #endif
+       struct rk29camera_platform_data *sensor_io_request;
 };
 
-
+static int sensor_deactivate(struct i2c_client *client);
 
 static struct sensor* to_sensor(const struct i2c_client *client)
 {
@@ -1402,6 +1403,49 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar
     }
     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;
+
+
+       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);
+                       }
+               }
+               default:
+               {
+                       SENSOR_TR("%s power cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd);
+                       break;
+               }
+       }
+sensor_power_end:
+       return ret;
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -1413,6 +1457,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
     /* soft reset */
        sensor_task_lock(client,1);
     ret = sensor_write(client, 0x0103, 0x01);
@@ -1516,12 +1565,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     return 0;
 sensor_INIT_ERR:
+       sensor_deactivate(client);
     return ret;
 }
 
-static int sensor_deactivate(struct v4l2_subdev *sd)
+static int sensor_deactivate(struct i2c_client *client)
 {
-       struct i2c_client *client = sd->priv;
+       struct soc_camera_device *icd = client->dev.platform_data;
        u8 reg_val;
 
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
@@ -1532,6 +1582,10 @@ static int sensor_deactivate(struct v4l2_subdev *sd)
        sensor_read(client,0x3002,&reg_val);
        sensor_write(client, 0x3002, reg_val&0x1f);
        sensor_task_lock(client, 0);
+
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       msleep(100);
        return 0;
 }
 
@@ -1543,32 +1597,21 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 {
     int ret;
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct soc_camera_link *icl;
 
-
-    if (pm_msg.event == PM_EVENT_SUSPEND)
-    {
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
         SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
         ret = sensor_write_array(client, sensor_power_down_sequence) ;
-        if (ret != 0)
-        {
+        if (ret != 0) {
             SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
             return ret;
-        }
-        else
-        {
-            icl = to_soc_camera_link(icd);
-            if (icl->power) {
-                ret = icl->power(icd->pdev, 0);
-                if (ret < 0) {
-                                   SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
-                    return -EINVAL;
-                }
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
             }
         }
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
         return -EINVAL;
     }
@@ -1577,16 +1620,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 
 static int sensor_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_link *icl;
-    int ret;
+       int ret;
 
-    icl = to_soc_camera_link(icd);
-    if (icl->power) {
-        ret = icl->power(icd->pdev, 1);
-        if (ret < 0) {
-                       SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
-            return -EINVAL;
-        }
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
     }
 
        SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
@@ -2450,13 +2489,18 @@ static int sensor_video_probe(struct soc_camera_device *icd,
            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
                return -ENODEV;
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
+
     /* soft reset */
     ret = sensor_write(client, 0x0103, 0x01);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
-        return -ENODEV;
-    }
+        ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
     mdelay(5);          //delay 5 microseconds
 
     /* check if it is an sensor sensor */
@@ -2492,22 +2536,33 @@ static int sensor_video_probe(struct soc_camera_device *icd,
     return 0;
 
 sensor_video_probe_err:
-
     return ret;
 }
 
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
+       struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
        {
                case RK29_CAM_SUBDEV_DEACTIVATE:
                {
-                       sensor_deactivate(sd);
+                       sensor_deactivate(client);
+                       break;
+               }
+
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;
                        break;
                }
                default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
                        break;
+               }
        }
 
        return 0;
index a619c647de5ee5729b29d3b32b77279a62d90918..933cec7d4c57a57d820e3f903fcc8b63727353b8 100755 (executable)
@@ -3162,8 +3162,12 @@ struct sensor
 #if CONFIG_SENSOR_I2C_NOSCHED
        atomic_t tasklock_cnt;
 #endif
+       struct rk29camera_platform_data *sensor_io_request;
 };
 
+static int sensor_deactivate(struct i2c_client *client);
+
+
 static struct sensor* to_sensor(const struct i2c_client *client)
 {
     return container_of(i2c_get_clientdata(client), struct sensor, subdev);
@@ -3765,7 +3769,51 @@ int sensor_ae_transfer(struct i2c_client *client)
        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;
+
 
+       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 power cmd(0x%x) is unknown!",SENSOR_NAME_STRING(),cmd);
+                       break;
+               }
+       }
+
+sensor_power_end:
+       return ret;
+}
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -3777,6 +3825,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_INIT_ERR;
+       }
+
     /* soft reset */
        sensor_task_lock(client,1);
     ret = sensor_write(client, 0x3008, 0x80);
@@ -3874,12 +3927,12 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     return 0;
 sensor_INIT_ERR:
+       sensor_deactivate(client);
     return ret;
 }
-static int sensor_deactivate(struct v4l2_subdev *sd)
+static int sensor_deactivate(struct i2c_client *client)
 {
-       struct i2c_client *client = sd->priv;
-
+       struct soc_camera_device *icd = client->dev.platform_data;
        /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */
        sensor_task_lock(client, 1);
     sensor_write(client, 0x3017, 0x00);  // FREX,VSYNC,HREF,PCLK,D9-D6
@@ -3888,6 +3941,10 @@ static int sensor_deactivate(struct v4l2_subdev *sd)
        SENSOR_DG("\n%s..%s exit \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        sensor_task_lock(client, 0);
+
+       sensor_ioctrl(icd, Sensor_PowerDown, 1);
+
+       msleep(100);
        return 0;
 }
 static  struct reginfo sensor_power_down_sequence[]=
@@ -3898,56 +3955,40 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg)
 {
     int ret;
     struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
-    struct soc_camera_link *icl;
-
 
-    if (pm_msg.event == PM_EVENT_SUSPEND)
-    {
+    if (pm_msg.event == PM_EVENT_SUSPEND) {
         SENSOR_DG("\n %s Enter Suspend.. \n", SENSOR_NAME_STRING());
         ret = sensor_write_array(client, sensor_power_down_sequence) ;
-        if (ret != 0)
-        {
+        if (ret != 0) {
             SENSOR_TR("\n %s..%s WriteReg Fail.. \n", SENSOR_NAME_STRING(),__FUNCTION__);
             return ret;
-        }
-        else
-        {
-            icl = to_soc_camera_link(icd);
-            if (icl->power) {
-                ret = icl->power(icd->pdev, 0);
-                if (ret < 0) {
-                                   SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
-                    return -EINVAL;
-                }
+        } else {
+            ret = sensor_ioctrl(icd, Sensor_PowerDown, 1);
+            if (ret < 0) {
+                           SENSOR_TR("\n %s suspend fail for turn on power!\n", SENSOR_NAME_STRING());
+                return -EINVAL;
             }
         }
-    }
-    else
-    {
+    } else {
         SENSOR_TR("\n %s cann't suppout Suspend..\n",SENSOR_NAME_STRING());
         return -EINVAL;
     }
+
     return 0;
 }
 
 static int sensor_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_link *icl;
-    int ret;
+       int ret;
 
-    icl = to_soc_camera_link(icd);
-    if (icl->power) {
-        ret = icl->power(icd->pdev, 1);
-        if (ret < 0) {
-                       SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
-            return -EINVAL;
-        }
+    ret = sensor_ioctrl(icd, Sensor_PowerDown, 0);
+    if (ret < 0) {
+               SENSOR_TR("\n %s resume fail for turn on power!\n", SENSOR_NAME_STRING());
+        return -EINVAL;
     }
 
        SENSOR_DG("\n %s Enter Resume.. \n", SENSOR_NAME_STRING());
-
-    return 0;
-
+       return 0;
 }
 
 static int sensor_set_bus_param(struct soc_camera_device *icd,
@@ -5049,12 +5090,16 @@ static int sensor_video_probe(struct soc_camera_device *icd,
            to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
                return -ENODEV;
 
+       if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
+               ret = -ENODEV;
+               goto sensor_video_probe_err;
+       }
     /* soft reset */
     ret = sensor_write(client, 0x3012, 0x80);
-    if (ret != 0)
-    {
+    if (ret != 0) {
         SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING());
-        return -ENODEV;
+        ret = -ENODEV;
+               goto sensor_video_probe_err;
     }
     mdelay(5);          //delay 5 microseconds
 
@@ -5091,21 +5136,31 @@ static int sensor_video_probe(struct soc_camera_device *icd,
     return 0;
 
 sensor_video_probe_err:
-
     return ret;
 }
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
+       struct i2c_client *client = sd->priv;
+    struct sensor *sensor = to_sensor(client);
+
        SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
        switch (cmd)
        {
                case RK29_CAM_SUBDEV_DEACTIVATE:
                {
-                       sensor_deactivate(sd);
+                       sensor_deactivate(client);
+                       break;
+               }
+               case RK29_CAM_SUBDEV_IOREQUEST:
+               {
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;
                        break;
                }
                default:
+               {
+                       SENSOR_TR("%s %s cmd(0x%x) is unknown !\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd);
                        break;
+               }
        }
 
        return 0;
index e7eb720fdd82fbbfe085dd75f04249d85901981a..0d82be6aa6596aadfc238047701ac0a289c7ee55 100755 (executable)
@@ -306,7 +306,6 @@ static void rk29_videobuf_free(struct videobuf_queue *vq, struct rk29_buffer *bu
 static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field)
 {
     struct soc_camera_device *icd = vq->priv_data;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
     struct rk29_buffer *buf;
     int ret;
 
@@ -734,6 +733,7 @@ static int rk29_camera_add_device(struct soc_camera_device *icd)
     /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe  */
     if (control) {
         sd = dev_get_drvdata(control);
+               v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
         ret = v4l2_subdev_call(sd,core, init, 0);
         if (ret)
             goto ebusy;
@@ -1541,7 +1541,8 @@ static int __devexit rk29_camera_remove(struct platform_device *pdev)
     release_mem_region(res->start, res->end - res->start + 1);
 
     if (pcdev->pdata && pcdev->pdata->io_deinit) {         /* ddl@rock-chips.com : Free IO in deinit function */
-        pcdev->pdata->io_deinit();
+        pcdev->pdata->io_deinit(0);
+               pcdev->pdata->io_deinit(1);
     }
 
     kfree(pcdev);
index 705c44b33b19a7116fc51dd0052c4694e9fbe9fc..76ac70e66da22798995fcee303f25b9677b0da71 100644 (file)
@@ -119,6 +119,7 @@ struct soc_camera_link {
        /* Optional callbacks to power on or off and reset the sensor */
        int (*power)(struct device *, int);
        int (*reset)(struct device *);
+       int (*powerdown)(struct device *, int);         /* ddl@rock-chisp.com : support sensor powerdown  */
        /*
         * some platforms may support different data widths than the sensors
         * native ones due to different data line routing. Let the board code