From: ddl Date: Fri, 14 Jan 2011 05:23:10 +0000 (+0800) Subject: camera: camera io config support power/reset/powerdown/flash X-Git-Tag: firefly_0821_release~10808 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8fa52cb8d21a95231fae5c8679c904d55d14a682;p=firefly-linux-kernel-4.4.55.git camera: camera io config support power/reset/powerdown/flash --- diff --git a/arch/arm/mach-rk29/board-rk29-aigo.c b/arch/arm/mach-rk29/board-rk29-aigo.c index 8f01bce28f62..c421835d7e77 100644 --- a/arch/arm/mach-rk29/board-rk29-aigo.c +++ b/arch/arm/mach-rk29/board-rk29-aigo.c @@ -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); gpio_set_value(FB_LCD_CABC_EN_PIN, GPIO_LOW); } - + return ret; } @@ -392,28 +392,28 @@ int it7260_init_platform_hw(void) return -EIO; } - gpio_direction_output(TOUCH_PWR_PIN, 0); + gpio_direction_output(TOUCH_PWR_PIN, 0); gpio_set_value(TOUCH_PWR_PIN,GPIO_LOW); - msleep(100); + msleep(100); + + gpio_direction_output(TOUCH_INT_PIN, 0); + gpio_set_value(TOUCH_INT_PIN,GPIO_LOW); - gpio_direction_output(TOUCH_INT_PIN, 0); - gpio_set_value(TOUCH_INT_PIN,GPIO_LOW); - - msleep(100); - gpio_set_value(TOUCH_PWR_PIN,GPIO_HIGH); - msleep(100); + msleep(100); + gpio_set_value(TOUCH_PWR_PIN,GPIO_HIGH); + msleep(100); gpio_direction_output(TOUCH_RESET_PIN, 0); mdelay(100); gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); mdelay(100); gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); - - gpio_direction_output(TOUCH_INT_PIN, 1); - gpio_pull_updown(TOUCH_INT_PIN, 0); - - + + gpio_direction_output(TOUCH_INT_PIN, 1); + gpio_pull_updown(TOUCH_INT_PIN, 0); + + return 0; } @@ -518,7 +518,7 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = { .type = "stc3100", .addr = 0x70, .flags = 0, - }, + }, #endif #if defined (CONFIG_BATTERY_BQ27510) { @@ -617,235 +617,389 @@ static struct i2c_board_info __initdata board_i2c3_devices[] = { * author: ddl@rock-chips.com *****************************************************************************************/ #ifdef CONFIG_VIDEO_RK29 -#define SENSOR_NAME_0 RK29_CAM_SENSOR_NAME_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_RESET_PIN_0 INVALID_GPIO -#define SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L -#define SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_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_RESET_PIN_1 INVALID_GPIO -#define SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L -#define SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L - -static int rk29_sensor_io_init(void); -static int rk29_sensor_io_deinit(void); - -struct rk29camera_platform_data rk29_camera_platform_data = { - .io_init = rk29_sensor_io_init, - .io_deinit = rk29_sensor_io_deinit, - .gpio_res = { - { - .gpio_reset = SENSOR_RESET_PIN_0, - .gpio_power = SENSOR_POWER_PIN_0, - .gpio_flag = (SENSOR_POWERACTIVE_LEVEL_0|SENSOR_RESETACTIVE_LEVEL_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), - .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_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_ioflag = rk29_camera_platform_data.gpio_res[i].gpio_flag; - - if (camera_power != INVALID_GPIO) { - ret = gpio_request(camera_power, "camera power"); - if (ret) - continue; - - 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)); - - } - - if (camera_reset != INVALID_GPIO) { - ret = gpio_request(camera_reset, "camera reset"); - if (ret) { - if (camera_power != INVALID_GPIO) - gpio_free(camera_power); - - continue; - } - - 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)); - - } - } - - return 0; -} - -static int rk29_sensor_io_deinit(void) -{ - unsigned int i; - unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - - //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_power != INVALID_GPIO){ - gpio_direction_input(camera_power); - gpio_free(camera_power); - } - - if (camera_reset != INVALID_GPIO) { - gpio_direction_input(camera_reset); - gpio_free(camera_reset); - } - } - - return 0; -} - - -static int rk29_sensor_power(struct device *dev, int on) -{ - unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; - unsigned int camera_ioflag; - - 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_ioflag = rk29_camera_platform_data.gpio_res[0].gpio_flag; - } 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_reset = rk29_camera_platform_data.gpio_res[1].gpio_reset; - camera_power = rk29_camera_platform_data.gpio_res[1].gpio_power; - camera_ioflag = rk29_camera_platform_data.gpio_res[1].gpio_flag; - } - - 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); - } - } - - 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)); - } - } - return 0; +#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 + +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)); + + } + + 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)); + + } + + 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(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)); + 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; + } + + 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; } -#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, - .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, - .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, - } -}; +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 /***************************************************************************************** * backlight devices @@ -933,8 +1087,8 @@ static struct regulator_init_data rk29_pwm_regulator_data = { .name = "PWM2", .min_uV = 950000, .max_uV = 1400000, - .apply_uV = 1, - .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, + .apply_uV = 1, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, }, .num_consumer_supplies = ARRAY_SIZE(pwm_consumers), .consumer_supplies = pwm_consumers, @@ -972,7 +1126,7 @@ static int rk29_sdmmc0_cfg_gpio(void) rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1); rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2); rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3); - rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N); + rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N); rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5); ///GPIO5H_SDMMC0_PWR_EN); ///GPIO5H_GPIO5D5); gpio_request(RK29_PIN5_PD5,"sdmmc"); gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH); @@ -1010,7 +1164,7 @@ static int rk29_sdmmc1_cfg_gpio(void) return 0; } -#ifdef CONFIG_WIFI_CONTROL_FUNC +#ifdef CONFIG_WIFI_CONTROL_FUNC 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); #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; } - + 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; } - + 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; } - + 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); + pr_info("%s: init finished\n",__func__); - + return 0; } @@ -1374,7 +1528,7 @@ static struct platform_device *devices[] __initdata = { *****************************************************************************************/ static int rk29_vmac_register_set(void) { - //config rk29 vmac as rmii, 100MHz + //config rk29 vmac as rmii, 100MHz u32 value= readl(RK29_GRF_BASE + 0xbc); value = (value & 0xfff7ff) | (0x400); writel(value, RK29_GRF_BASE + 0xbc); @@ -1639,7 +1793,7 @@ static void __init machine_rk29_init_irq(void) static void rk29_pm_power_off(void) { printk(KERN_ERR "rk29_pm_power_off start...\n"); - + gpio_direction_output(POWER_ON_PIN, GPIO_LOW); while(1); } @@ -1647,7 +1801,7 @@ static void rk29_pm_power_off(void) static void __init machine_rk29_board_init(void) { rk29_board_iomux_init(); - gpio_request(POWER_ON_PIN,"poweronpin"); + gpio_request(POWER_ON_PIN,"poweronpin"); gpio_set_value(POWER_ON_PIN, GPIO_HIGH); gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); pm_power_off = rk29_pm_power_off; diff --git a/arch/arm/mach-rk29/board-rk29-winaccord.c b/arch/arm/mach-rk29/board-rk29-winaccord.c index e9fb59b6e040..61a6294b7084 100644 --- a/arch/arm/mach-rk29/board-rk29-winaccord.c +++ b/arch/arm/mach-rk29/board-rk29-winaccord.c @@ -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 diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 1c03f403a8b3..a108c8efcf8e 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -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, diff --git a/arch/arm/mach-rk29/include/mach/rk29_camera.h b/arch/arm/mach-rk29/include/mach/rk29_camera.h index c033e25d8656..4e2bb358f7cf 100644 --- a/arch/arm/mach-rk29/include/mach/rk29_camera.h +++ b/arch/arm/mach-rk29/include/mach/rk29_camera.h @@ -26,6 +26,12 @@ #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" @@ -42,14 +48,43 @@ #define RK29_CAM_RESETACTIVE_H (0x01<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; diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index 469b699b6b59..78bc37af2970 100755 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -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,®_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; diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index a619c647de5e..933cec7d4c57 100755 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -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; diff --git a/drivers/media/video/rk29_camera_oneframe.c b/drivers/media/video/rk29_camera_oneframe.c index e7eb720fdd82..0d82be6aa659 100755 --- a/drivers/media/video/rk29_camera_oneframe.c +++ b/drivers/media/video/rk29_camera_oneframe.c @@ -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); diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 705c44b33b19..76ac70e66da2 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -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