From dcfe4925129b7700d16d70d962d0065ed6ec68a9 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 12 Mar 2012 17:11:20 +0800 Subject: [PATCH] camera rk30:commit v0.2.6,support two cif controls. --- arch/arm/mach-rk30/board-rk30-sdk.c | 165 ++ arch/arm/mach-rk30/devices.c | 2 - arch/arm/plat-rk/include/plat/rk_camera.h | 224 ++ drivers/media/video/Kconfig | 20 +- drivers/media/video/Makefile | 7 +- drivers/media/video/gc0307.c | 116 +- drivers/media/video/gc0308.c | 115 +- drivers/media/video/gc0309.c | 117 +- drivers/media/video/gc0309_for_td8801.c | 112 +- drivers/media/video/gc2015.c | 116 +- drivers/media/video/gt2005.c | 116 +- drivers/media/video/hi253.c | 117 +- drivers/media/video/hi704.c | 116 +- drivers/media/video/mt9d112.c | 114 +- drivers/media/video/mt9d113.c | 115 +- drivers/media/video/mt9p111.c | 116 +- drivers/media/video/mt9t111.c | 116 +- drivers/media/video/nt99250.c | 117 +- drivers/media/video/ov2640.c | 1327 +---------- drivers/media/video/ov2640_rk.c | 138 +- drivers/media/video/ov2655.c | 117 +- drivers/media/video/ov2659.c | 115 +- drivers/media/video/ov3640.c | 115 +- drivers/media/video/ov5640.c | 113 +- drivers/media/video/ov5640_for_td8801.c | 113 +- drivers/media/video/ov5642.c | 112 +- drivers/media/video/ov7675.c | 114 +- drivers/media/video/ov7690.c | 117 +- drivers/media/video/rk29_camera.c | 2 - drivers/media/video/rk29_camera_oneframe.c | 26 +- drivers/media/video/rk30_camera.c | 1704 ++++++++++++++ drivers/media/video/rk30_camera_oneframe.c | 2337 ++++++++++++++++++++ drivers/media/video/s5k6aa.c | 118 +- drivers/media/video/sid130B.c | 113 +- drivers/media/video/siv120b.c | 117 +- 35 files changed, 6766 insertions(+), 1953 deletions(-) create mode 100755 arch/arm/plat-rk/include/plat/rk_camera.h mode change 100644 => 100755 drivers/media/video/gc0309_for_td8801.c mode change 100644 => 100755 drivers/media/video/mt9p111.c mode change 100644 => 100755 drivers/media/video/ov2640.c mode change 100644 => 100755 drivers/media/video/ov3640.c mode change 100644 => 100755 drivers/media/video/ov5640_for_td8801.c mode change 100644 => 100755 drivers/media/video/ov7690.c create mode 100755 drivers/media/video/rk30_camera.c create mode 100755 drivers/media/video/rk30_camera_oneframe.c mode change 100644 => 100755 drivers/media/video/s5k6aa.c mode change 100755 => 100644 drivers/media/video/sid130B.c diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c index 53feb9812e5b..de5dea56449b 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -54,6 +54,152 @@ #define RK30_FB0_MEM_SIZE 8*SZ_1M +#ifdef CONFIG_VIDEO_RK29 +/*---------------- Camera Sensor Macro Define Begin ------------------------*/ +/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/ +#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV2659//RK_CAM_SENSOR_OV5642 /* back camera sensor */ +#define CONFIG_SENSOR_IIC_ADDR_0 0x60//0x78 +#define CONFIG_SENSOR_IIC_ADAPTER_ID_0 1 +#define CONFIG_SENSOR_CIF_INDEX_0 0 +#define CONFIG_SENSOR_ORIENTATION_0 90 +#define CONFIG_SENSOR_POWER_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_RESET_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_POWERDN_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_FALSH_PIN_0 INVALID_GPIO +#define CONFIG_SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L +#define CONFIG_SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L +#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H +#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L + +#define CONFIG_SENSOR_QCIF_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_QVGA_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_CIF_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_VGA_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_480P_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_SVGA_FPS_FIXED_0 15000 +#define CONFIG_SENSOR_720P_FPS_FIXED_0 30000 + +#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659 /* front camera sensor */ +#define CONFIG_SENSOR_IIC_ADDR_1 0x60 +#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 1 +#define CONFIG_SENSOR_CIF_INDEX_1 1 +#define CONFIG_SENSOR_ORIENTATION_1 270 +#define CONFIG_SENSOR_POWER_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_RESET_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_POWERDN_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_FALSH_PIN_1 INVALID_GPIO +#define CONFIG_SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L +#define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L +#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H +#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L + +#define CONFIG_SENSOR_QCIF_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_QVGA_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_CIF_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_VGA_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_480P_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_SVGA_FPS_FIXED_1 15000 +#define CONFIG_SENSOR_720P_FPS_FIXED_1 30000 + +#define CONFIG_USE_CIF_0 1 +#define CONFIG_USE_CIF_1 0 +#endif //#ifdef CONFIG_VIDEO_RK29 +/*---------------- Camera Sensor Configuration Macro End------------------------*/ +#include "../../../drivers/media/video/rk30_camera.c" +/*---------------- Camera Sensor Macro Define End ---------*/ + +#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY +#ifdef CONFIG_VIDEO_RK29_WORK_IPP +#define MEM_CAMIPP_SIZE PMEM_CAMIPP_NECESSARY +#else +#define MEM_CAMIPP_SIZE 0 +#endif +/***************************************************************************************** + * camera devices + * author: ddl@rock-chips.com + *****************************************************************************************/ +#ifdef CONFIG_VIDEO_RK29 +#define CONFIG_SENSOR_POWER_IOCTL_USR 0 +#define CONFIG_SENSOR_RESET_IOCTL_USR 0 +#define CONFIG_SENSOR_POWERDOWN_IOCTL_USR 0 +#define CONFIG_SENSOR_FLASH_IOCTL_USR 0 + +#if CONFIG_SENSOR_POWER_IOCTL_USR +static int sensor_power_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_POWER_IOCTL_USR is 1, sensor_power_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_RESET_IOCTL_USR +static int sensor_reset_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_RESET_IOCTL_USR is 1, sensor_reset_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_POWERDOWN_IOCTL_USR +static int sensor_powerdown_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_POWERDOWN_IOCTL_USR is 1, sensor_powerdown_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_FLASH_IOCTL_USR +static int sensor_flash_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_FLASH_IOCTL_USR is 1, sensor_flash_usr_cb function must be writed!!"; +} +#endif + +static struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = { + #if CONFIG_SENSOR_POWER_IOCTL_USR + .sensor_power_cb = sensor_power_usr_cb, + #else + .sensor_power_cb = NULL, + #endif + + #if CONFIG_SENSOR_RESET_IOCTL_USR + .sensor_reset_cb = sensor_reset_usr_cb, + #else + .sensor_reset_cb = NULL, + #endif + + #if CONFIG_SENSOR_POWERDOWN_IOCTL_USR + .sensor_powerdown_cb = sensor_powerdown_usr_cb, + #else + .sensor_powerdown_cb = NULL, + #endif + + #if CONFIG_SENSOR_FLASH_IOCTL_USR + .sensor_flash_cb = sensor_flash_usr_cb, + #else + .sensor_flash_cb = NULL, + #endif +}; +static struct reginfo_t rk_init_data_sensor_reg_0[] = +{ + {0x0000, 0x00,0,0} + }; +static struct reginfo_t rk_init_data_sensor_winseqreg_0[] ={ + {0x0000, 0x00,0,0} + }; +static rk_sensor_user_init_data_s rk_init_data_sensor_0 = +{ + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_0, + .rk_sensor_init_winseq = NULL,//rk_init_data_sensor_winseqreg_0, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_0) / sizeof(struct reginfo_t), + +}; +static rk_sensor_user_init_data_s* rk_init_data_sensor_0_p = &rk_init_data_sensor_0; +static rk_sensor_user_init_data_s* rk_init_data_sensor_1_p = NULL; +#include "../../../drivers/media/video/rk30_camera.c" + +#endif #if defined(CONFIG_TOUCHSCREEN_GT8XX) #define TOUCH_RESET_PIN RK30_PIN4_PD0 @@ -722,6 +868,25 @@ static void __init rk30_reserve(void) resource_fb[2].start = board_mem_reserve_add("fb2",RK30_FB0_MEM_SIZE); resource_fb[2].end = resource_fb[2].start + RK30_FB0_MEM_SIZE - 1; #endif + +#if (MEM_CAMIPP_SIZE != 0) + #if CONFIG_USE_CIF_0 + rk_camera_platform_data.meminfo.name = "camera_ipp_mem_0"; + rk_camera_platform_data.meminfo.start = board_mem_reserve_add("camera_ipp_mem_0",MEM_CAMIPP_SIZE); + rk_camera_platform_data.meminfo.size= MEM_CAMIPP_SIZE; + #endif + #if CONFIG_USE_CIF_1 + rk_camera_platform_data.meminfo_cif1.name = "camera_ipp_mem_1"; + rk_camera_platform_data.meminfo_cif1.start =board_mem_reserve_add("camera_ipp_mem_1",MEM_CAMIPP_SIZE); + rk_camera_platform_data.meminfo_cif1.size= MEM_CAMIPP_SIZE; + #endif +#endif + +#if (PMEM_CAM_SIZE != 0) + android_pmem_cam_pdata.start = board_mem_reserve_add("camera_pmem",PMEM_CAM_SIZE); + android_pmem_cam_pdata.size = PMEM_CAM_SIZE; +#endif + board_mem_reserved(); } diff --git a/arch/arm/mach-rk30/devices.c b/arch/arm/mach-rk30/devices.c index 98ecfb42eb4a..35c0b5c88beb 100755 --- a/arch/arm/mach-rk30/devices.c +++ b/arch/arm/mach-rk30/devices.c @@ -973,7 +973,6 @@ static void __init rk30_init_sdmmc(void) platform_device_register(&device_sdmmc1); #endif } - static int __init rk30_init_devices(void) { rk30_init_dma(); @@ -1003,7 +1002,6 @@ static int __init rk30_init_devices(void) rk_serial_debug_init(DEBUG_UART_PHYS, IRQ_UART0 + CONFIG_RK_DEBUG_UART, IRQ_UART_SIGNAL, -1); #endif rk30_init_i2s(); - return 0; } arch_initcall(rk30_init_devices); diff --git a/arch/arm/plat-rk/include/plat/rk_camera.h b/arch/arm/plat-rk/include/plat/rk_camera.h new file mode 100755 index 000000000000..d6cabc46b94f --- /dev/null +++ b/arch/arm/plat-rk/include/plat/rk_camera.h @@ -0,0 +1,224 @@ +/* + camera.h - PXA camera driver header file + + Copyright (C) 2003, Intel Corporation + Copyright (C) 2008, Guennadi Liakhovetski + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ASM_ARCH_CAMERA_RK_H_ +#define __ASM_ARCH_CAMERA_RK_H_ + +#include +#include +#define RK29_CAM_DRV_NAME "rk30xx-camera" +#define RK29_CAM_PLATFORM_DEV_ID 33 +#define RK_CAM_PLATFORM_DEV_ID_0 RK29_CAM_PLATFORM_DEV_ID +#define RK_CAM_PLATFORM_DEV_ID_1 (RK_CAM_PLATFORM_DEV_ID_0+1) +#define INVALID_GPIO -1 +#define INVALID_VALUE -1 +#define RK29_CAM_IO_SUCCESS 0 +#define RK29_CAM_EIO_INVALID -1 +#define RK29_CAM_EIO_REQUESTFAIL -2 + +#define RK_CAM_NUM 2 +/*---------------- Camera Sensor Must Define Macro Begin ------------------------*/ +#define RK29_CAM_SENSOR_OV7675 ov7675 +#define RK29_CAM_SENSOR_OV9650 ov9650 +#define RK29_CAM_SENSOR_OV2640 ov2640 +#define RK29_CAM_SENSOR_OV2655 ov2655 +#define RK29_CAM_SENSOR_OV2659 ov2659 +#define RK29_CAM_SENSOR_OV7690 ov7690 +#define RK29_CAM_SENSOR_OV3640 ov3640 +#define RK29_CAM_SENSOR_OV5640 ov5640 +#define RK29_CAM_SENSOR_OV5642 ov5642 +#define RK29_CAM_SENSOR_S5K6AA s5k6aa +#define RK29_CAM_SENSOR_MT9D112 mt9d112 +#define RK29_CAM_SENSOR_MT9D113 mt9d113 +#define RK29_CAM_SENSOR_MT9P111 mt9p111 +#define RK29_CAM_SENSOR_MT9T111 mt9t111 +#define RK29_CAM_SENSOR_GT2005 gt2005 +#define RK29_CAM_SENSOR_GC0307 gc0307 +#define RK29_CAM_SENSOR_GC0308 gc0308 +#define RK29_CAM_SENSOR_GC0309 gc0309 +#define RK29_CAM_SENSOR_GC2015 gc2015 +#define RK29_CAM_SENSOR_SIV120B siv120b +#define RK29_CAM_SENSOR_SID130B sid130B +#define RK29_CAM_SENSOR_HI253 hi253 +#define RK29_CAM_SENSOR_HI704 hi704 +#define RK29_CAM_SENSOR_NT99250 nt99250 + +#define RK29_CAM_SENSOR_NAME_OV7675 "ov7675" +#define RK29_CAM_SENSOR_NAME_OV9650 "ov9650" +#define RK29_CAM_SENSOR_NAME_OV2640 "ov2640" +#define RK29_CAM_SENSOR_NAME_OV2655 "ov2655" +#define RK29_CAM_SENSOR_NAME_OV2659 "ov2659" +#define RK29_CAM_SENSOR_NAME_OV7690 "ov7690" +#define RK29_CAM_SENSOR_NAME_OV3640 "ov3640" +#define RK29_CAM_SENSOR_NAME_OV5640 "ov5640" +#define RK29_CAM_SENSOR_NAME_OV5642 "ov5642" +#define RK29_CAM_SENSOR_NAME_S5K6AA "s5k6aa" +#define RK29_CAM_SENSOR_NAME_MT9D112 "mt9d112" +#define RK29_CAM_SENSOR_NAME_MT9D113 "mt9d113" +#define RK29_CAM_SENSOR_NAME_MT9P111 "mt9p111" +#define RK29_CAM_SENSOR_NAME_MT9T111 "mt9t111" +#define RK29_CAM_SENSOR_NAME_GT2005 "gt2005" +#define RK29_CAM_SENSOR_NAME_GC0307 "gc0307" +#define RK29_CAM_SENSOR_NAME_GC0308 "gc0308" +#define RK29_CAM_SENSOR_NAME_GC0309 "gc0309" +#define RK29_CAM_SENSOR_NAME_GC2015 "gc2015" +#define RK29_CAM_SENSOR_NAME_SIV120B "siv120b" +#define RK29_CAM_SENSOR_NAME_SID130B "sid130B" +#define RK29_CAM_SENSOR_NAME_HI253 "hi253" +#define RK29_CAM_SENSOR_NAME_HI704 "hi704" +#define RK29_CAM_SENSOR_NAME_NT99250 "nt99250" + +#define ov7675_FULL_RESOLUTION 0x30000 // 0.3 megapixel +#define ov9650_FULL_RESOLUTION 0x130000 // 1.3 megapixel +#define ov2640_FULL_RESOLUTION 0x200000 // 2 megapixel +#define ov2655_FULL_RESOLUTION 0x200000 // 2 megapixel +#define ov2659_FULL_RESOLUTION 0x200000 // 2 megapixel +#define ov7690_FULL_RESOLUTION 0x300000 // 2 megapixel +#define ov3640_FULL_RESOLUTION 0x300000 // 3 megapixel +#define ov5640_FULL_RESOLUTION 0x500000 // 5 megapixel +#define ov5642_FULL_RESOLUTION 0x500000 // 5 megapixel +#define s5k6aa_FULL_RESOLUTION 0x130000 // 1.3 megapixel +#define mt9d112_FULL_RESOLUTION 0x200000 // 2 megapixel +#define mt9d113_FULL_RESOLUTION 0x200000 // 2 megapixel +#define mt9t111_FULL_RESOLUTION 0x300000 // 3 megapixel +#define mt9p111_FULL_RESOLUTION 0x500000 // 5 megapixel +#define gt2005_FULL_RESOLUTION 0x200000 // 2 megapixel +#define gc0308_FULL_RESOLUTION 0x30000 // 0.3 megapixel +#define gc0309_FULL_RESOLUTION 0x30000 // 0.3 megapixel +#define gc2015_FULL_RESOLUTION 0x200000 // 2 megapixel +#define siv120b_FULL_RESOLUTION 0x30000 // 0.3 megapixel +#define sid130B_FULL_RESOLUTION 0x200000 // 2 megapixel +#define hi253_FULL_RESOLUTION 0x200000 // 2 megapixel +#define hi704_FULL_RESOLUTION 0x30000 // 0.3 megapixel +#define nt99250_FULL_RESOLUTION 0x200000 // 2 megapixel +/*---------------- Camera Sensor Must Define Macro End ------------------------*/ + + +#define RK29_CAM_POWERACTIVE_BITPOS 0x00 +#define RK29_CAM_POWERACTIVE_MASK (1< #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -51,10 +51,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480//144 #define SENSOR_MAX_WIDTH 800//1600 #define SENSOR_MAX_HEIGHT 600//1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -74,10 +75,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1613,6 +1610,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { @@ -1621,9 +1625,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; - - + char value; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1644,7 +1702,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) mdelay(5); */ //delay 5 microseconds - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2822,20 +2880,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/gc0308.c b/drivers/media/video/gc0308.c index 67669ac38f73..b131adcc38c5 100755 --- a/drivers/media/video/gc0308.c +++ b/drivers/media/video/gc0308.c @@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -51,10 +51,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480//144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -74,10 +75,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1488,6 +1485,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { @@ -1496,8 +1500,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; - + char value; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1518,7 +1577,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) mdelay(5); */ //delay 5 microseconds - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2664,20 +2723,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/gc0309.c b/drivers/media/video/gc0309.c index dff2a47c92be..d30e026ceb8e 100755 --- a/drivers/media/video/gc0309.c +++ b/drivers/media/video/gc0309.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -100,7 +97,7 @@ struct reginfo u8 val; }; -/* init SVGA preview */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { /*init registers code.*/ @@ -1445,6 +1442,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1453,7 +1457,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { ret = -ENODEV; @@ -1488,7 +1548,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2617,20 +2677,23 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/gc0309_for_td8801.c b/drivers/media/video/gc0309_for_td8801.c old mode 100644 new mode 100755 index f23c4d81a15f..2b88daad076a --- a/drivers/media/video/gc0309_for_td8801.c +++ b/drivers/media/video/gc0309_for_td8801.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,9 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 @@ -1445,6 +1443,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1453,7 +1458,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { ret = -ENODEV; @@ -1488,7 +1548,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2618,20 +2678,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/gc2015.c b/drivers/media/video/gc2015.c index 4f9e18f7a1b8..55ca4c19e6db 100755 --- a/drivers/media/video/gc2015.c +++ b/drivers/media/video/gc2015.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800//1024 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600//768 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -100,7 +97,7 @@ struct reginfo u8 val; }; -/* init SVGA preview */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { @@ -1597,6 +1594,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1605,8 +1609,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1653,7 +1711,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2830,20 +2888,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/gt2005.c b/drivers/media/video/gt2005.c index 607be6ed8a74..c89758cd7212 100755 --- a/drivers/media/video/gt2005.c +++ b/drivers/media/video/gt2005.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -100,7 +97,7 @@ struct reginfo u8 val; }; -/* init 352X288 SVGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { {0x0101 , 0x00}, @@ -2243,6 +2240,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { @@ -2252,8 +2256,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -2300,7 +2358,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -3469,20 +3527,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/hi253.c b/drivers/media/video/hi253.c index 343a22c73c98..c096707e5c18 100755 --- a/drivers/media/video/hi253.c +++ b/drivers/media/video/hi253.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 1600 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 1200 -#define SENSOR_INIT_WINSEQADR sensor_uxga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -101,7 +98,7 @@ struct reginfo u8 val; }; -/* init SVGA preview */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { // {0x01, 0xf9}, @@ -2155,6 +2152,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 1600; +static s32 sensor_init_height = 1200; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; + static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -2163,8 +2168,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_uxga; + sensor_init_width = 1600; + sensor_init_height = 1200; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -2203,7 +2262,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } #endif - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -3370,20 +3429,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/hi704.c b/drivers/media/video/hi704.c index 6c2c2659cd36..d2e9cbe8c225 100755 --- a/drivers/media/video/hi704.c +++ b/drivers/media/video/hi704.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -101,7 +98,7 @@ struct reginfo u8 val; }; -/* init SVGA preview */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { //PAGE 0 @@ -1633,6 +1630,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1641,8 +1645,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1681,7 +1739,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } #endif - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2824,20 +2882,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/mt9d112.c b/drivers/media/video/mt9d112.c index ce7e3b709e59..9e5064a33cd3 100755 --- a/drivers/media/video/mt9d112.c +++ b/drivers/media/video/mt9d112.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include "mt9d112.h" static int debug; @@ -53,10 +54,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 240 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -77,11 +79,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1768,6 +1765,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1775,10 +1779,66 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; + int ret,i = 0,j=0; #if (SENSOR_ID_REG != SEQUENCE_END) u16 pid = 0; #endif + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1823,7 +1883,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -3119,20 +3179,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/mt9d113.c b/drivers/media/video/mt9d113.c index 66f9c8ff8f37..b497ec31cb05 100755 --- a/drivers/media/video/mt9d113.c +++ b/drivers/media/video/mt9d113.c @@ -20,7 +20,8 @@ #include #include #include -#include +#include +#include #include "mt9d113.h" static int debug; @@ -56,10 +57,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 600 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_init_data -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -79,10 +81,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 1 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_FALLING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1562,6 +1560,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1569,9 +1574,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; - u16 pid = 0; - + char value; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1625,7 +1684,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2933,20 +2992,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/mt9p111.c b/drivers/media/video/mt9p111.c old mode 100644 new mode 100755 index d65188294379..ba535af297e8 --- a/drivers/media/video/mt9p111.c +++ b/drivers/media/video/mt9p111.c @@ -22,7 +22,8 @@ #include #include #include -#include +#include +#include #include "mt9p111.h" static int debug; @@ -57,10 +58,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2592 #define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define YUV420_BUFFER_MAX_SIZE 7558272 /* 2592*1944*1.5*/ #define CONFIG_SENSOR_WhiteBalance 1 @@ -84,11 +86,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -117,7 +114,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_AF_MODE_CLOSE 5 #endif -/* init 640X480 VGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { //[Step2-PLL_Timing] @@ -2859,6 +2856,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; + static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -2868,11 +2873,66 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; #endif const struct sensor_datafmt *fmt; - int ret,pid = 0; + int ret,pid = 0,i = 0 ,j = 0; int index =0 ; #if (SENSOR_RESET_REG != SEQUENCE_END) struct reginfo reg_info; #endif + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -2923,7 +2983,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING()); - ret =sensor_write_init_data(client, sensor_init_data); + ret =sensor_write_init_data(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; @@ -4638,20 +4698,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/mt9t111.c b/drivers/media/video/mt9t111.c index 63cfb5fb4378..b7b0e6cbc6aa 100755 --- a/drivers/media/video/mt9t111.c +++ b/drivers/media/video/mt9t111.c @@ -20,7 +20,8 @@ #include #include #include -#include +#include +#include #include "mt9t111.h" static int debug; @@ -55,10 +56,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2048 #define SENSOR_MAX_HEIGHT 1536 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -82,11 +84,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -113,7 +110,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_AF_MODE_CLOSE 5 #endif -/* init 640X480 VGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { //[Step2-PLL_Timing] @@ -6692,6 +6689,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; + static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -6699,10 +6704,65 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret,pid = 0; + int ret,pid = 0,i = 0 , j = 0; #if (SENSOR_RESET_REG != SEQUENCE_END) struct reginfo reg_info; #endif + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { ret = -ENODEV; @@ -6747,7 +6807,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -8266,20 +8326,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/nt99250.c b/drivers/media/video/nt99250.c index 4aaaecee8aff..53825acd43cf 100755 --- a/drivers/media/video/nt99250.c +++ b/drivers/media/video/nt99250.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -100,7 +97,7 @@ struct reginfo u8 val; }; -/* init 352X288 SVGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { {0x3024,0x02}, //TG //0x02 @@ -1444,6 +1441,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; + static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1452,8 +1457,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1503,7 +1562,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } #endif - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2712,20 +2771,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c old mode 100644 new mode 100755 index 9b2ac56310ef..a1dbbd3bc344 --- a/drivers/media/video/ov2640.c +++ b/drivers/media/video/ov2640.c @@ -1,1216 +1,3 @@ -/* -<<<<<<< HEAD - * ov2640 Camera Driver - * - * Copyright (C) 2010 Alberto Panizzo - * - * Based on ov772x, ov9640 drivers and previous non merged implementations. - * - * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright (C) 2006, OmniVision -======= -o* Driver for MT9M001 CMOS Image Sensor from Micron - * - * Copyright (C) 2008, Guennadi Liakhovetski ->>>>>>> parent of 15f7fab... temp revert rk change - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -<<<<<<< HEAD -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VAL_SET(x, mask, rshift, lshift) \ - ((((x) >> rshift) & mask) << lshift) -/* - * DSP registers - * register offset for BANK_SEL == BANK_SEL_DSP - */ -#define R_BYPASS 0x05 /* Bypass DSP */ -#define R_BYPASS_DSP_BYPAS 0x01 /* Bypass DSP, sensor out directly */ -#define R_BYPASS_USE_DSP 0x00 /* Use the internal DSP */ -#define QS 0x44 /* Quantization Scale Factor */ -#define CTRLI 0x50 -#define CTRLI_LP_DP 0x80 -#define CTRLI_ROUND 0x40 -#define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3) -#define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0) -#define HSIZE 0x51 /* H_SIZE[7:0] (real/4) */ -#define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define VSIZE 0x52 /* V_SIZE[7:0] (real/4) */ -#define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define XOFFL 0x53 /* OFFSET_X[7:0] */ -#define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) -#define YOFFL 0x54 /* OFFSET_Y[7:0] */ -#define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) -#define VHYX 0x55 /* Offset and size completion */ -#define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7) -#define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3) -#define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4) -#define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0) -#define DPRP 0x56 -#define TEST 0x57 /* Horizontal size completion */ -#define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7) -#define ZMOW 0x5A /* Zoom: Out Width OUTW[7:0] (real/4) */ -#define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define ZMOH 0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */ -#define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define ZMHH 0x5C /* Zoom: Speed and H&W completion */ -#define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4) -#define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2) -#define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0) -#define BPADDR 0x7C /* SDE Indirect Register Access: Address */ -#define BPDATA 0x7D /* SDE Indirect Register Access: Data */ -#define CTRL2 0x86 /* DSP Module enable 2 */ -#define CTRL2_DCW_EN 0x20 -#define CTRL2_SDE_EN 0x10 -#define CTRL2_UV_ADJ_EN 0x08 -#define CTRL2_UV_AVG_EN 0x04 -#define CTRL2_CMX_EN 0x01 -#define CTRL3 0x87 /* DSP Module enable 3 */ -#define CTRL3_BPC_EN 0x80 -#define CTRL3_WPC_EN 0x40 -#define SIZEL 0x8C /* Image Size Completion */ -#define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6) -#define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3) -#define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0) -#define HSIZE8 0xC0 /* Image Horizontal Size HSIZE[10:3] */ -#define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) -#define VSIZE8 0xC1 /* Image Vertical Size VSIZE[10:3] */ -#define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) -#define CTRL0 0xC2 /* DSP Module enable 0 */ -#define CTRL0_AEC_EN 0x80 -#define CTRL0_AEC_SEL 0x40 -#define CTRL0_STAT_SEL 0x20 -#define CTRL0_VFIRST 0x10 -#define CTRL0_YUV422 0x08 -#define CTRL0_YUV_EN 0x04 -#define CTRL0_RGB_EN 0x02 -#define CTRL0_RAW_EN 0x01 -#define CTRL1 0xC3 /* DSP Module enable 1 */ -#define CTRL1_CIP 0x80 -#define CTRL1_DMY 0x40 -#define CTRL1_RAW_GMA 0x20 -#define CTRL1_DG 0x10 -#define CTRL1_AWB 0x08 -#define CTRL1_AWB_GAIN 0x04 -#define CTRL1_LENC 0x02 -#define CTRL1_PRE 0x01 -#define R_DVP_SP 0xD3 /* DVP output speed control */ -#define R_DVP_SP_AUTO_MODE 0x80 -#define R_DVP_SP_DVP_MASK 0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0); - * = sysclk (48)/(2*[6:0]) (RAW);*/ -#define IMAGE_MODE 0xDA /* Image Output Format Select */ -#define IMAGE_MODE_Y8_DVP_EN 0x40 -#define IMAGE_MODE_JPEG_EN 0x10 -#define IMAGE_MODE_YUV422 0x00 -#define IMAGE_MODE_RAW10 0x04 /* (DVP) */ -#define IMAGE_MODE_RGB565 0x08 -#define IMAGE_MODE_HREF_VSYNC 0x02 /* HREF timing select in DVP JPEG output - * mode (0 for HREF is same as sensor) */ -#define IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP - * 1: Low byte first UYVY (C2[4] =0) - * VYUY (C2[4] =1) - * 0: High byte first YUYV (C2[4]=0) - * YVYU (C2[4] = 1) */ -#define RESET 0xE0 /* Reset */ -#define RESET_MICROC 0x40 -#define RESET_SCCB 0x20 -#define RESET_JPEG 0x10 -#define RESET_DVP 0x04 -#define RESET_IPU 0x02 -#define RESET_CIF 0x01 -#define REGED 0xED /* Register ED */ -#define REGED_CLK_OUT_DIS 0x10 -#define MS_SP 0xF0 /* SCCB Master Speed */ -#define SS_ID 0xF7 /* SCCB Slave ID */ -#define SS_CTRL 0xF8 /* SCCB Slave Control */ -#define SS_CTRL_ADD_AUTO_INC 0x20 -#define SS_CTRL_EN 0x08 -#define SS_CTRL_DELAY_CLK 0x04 -#define SS_CTRL_ACC_EN 0x02 -#define SS_CTRL_SEN_PASS_THR 0x01 -#define MC_BIST 0xF9 /* Microcontroller misc register */ -#define MC_BIST_RESET 0x80 /* Microcontroller Reset */ -#define MC_BIST_BOOT_ROM_SEL 0x40 -#define MC_BIST_12KB_SEL 0x20 -#define MC_BIST_12KB_MASK 0x30 -#define MC_BIST_512KB_SEL 0x08 -#define MC_BIST_512KB_MASK 0x0C -#define MC_BIST_BUSY_BIT_R 0x02 -#define MC_BIST_MC_RES_ONE_SH_W 0x02 -#define MC_BIST_LAUNCH 0x01 -#define BANK_SEL 0xFF /* Register Bank Select */ -#define BANK_SEL_DSP 0x00 -#define BANK_SEL_SENS 0x01 - -/* - * Sensor registers - * register offset for BANK_SEL == BANK_SEL_SENS - */ -#define GAIN 0x00 /* AGC - Gain control gain setting */ -#define COM1 0x03 /* Common control 1 */ -#define COM1_1_DUMMY_FR 0x40 -#define COM1_3_DUMMY_FR 0x80 -#define COM1_7_DUMMY_FR 0xC0 -#define COM1_VWIN_LSB_UXGA 0x0F -#define COM1_VWIN_LSB_SVGA 0x0A -#define COM1_VWIN_LSB_CIF 0x06 -#define REG04 0x04 /* Register 04 */ -#define REG04_DEF 0x20 /* Always set */ -#define REG04_HFLIP_IMG 0x80 /* Horizontal mirror image ON/OFF */ -#define REG04_VFLIP_IMG 0x40 /* Vertical flip image ON/OFF */ -#define REG04_VREF_EN 0x10 -#define REG04_HREF_EN 0x08 -#define REG04_AEC_SET(x) VAL_SET(x, 0x3, 0, 0) -#define REG08 0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */ -#define COM2 0x09 /* Common control 2 */ -#define COM2_SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */ - /* Output drive capability */ -#define COM2_OCAP_Nx_SET(N) (((N) - 1) & 0x03) /* N = [1x .. 4x] */ -#define PID 0x0A /* Product ID Number MSB */ -#define VER 0x0B /* Product ID Number LSB */ -#define COM3 0x0C /* Common control 3 */ -#define COM3_BAND_50H 0x04 /* 0 For Banding at 60H */ -#define COM3_BAND_AUTO 0x02 /* Auto Banding */ -#define COM3_SING_FR_SNAPSH 0x01 /* 0 For enable live video output after the - * snapshot sequence*/ -#define AEC 0x10 /* AEC[9:2] Exposure Value */ -#define CLKRC 0x11 /* Internal clock */ -#define CLKRC_EN 0x80 -#define CLKRC_DIV_SET(x) (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */ -#define COM7 0x12 /* Common control 7 */ -#define COM7_SRST 0x80 /* Initiates system reset. All registers are - * set to factory default values after which - * the chip resumes normal operation */ -#define COM7_RES_UXGA 0x00 /* Resolution selectors for UXGA */ -#define COM7_RES_SVGA 0x40 /* SVGA */ -#define COM7_RES_CIF 0x20 /* CIF */ -#define COM7_ZOOM_EN 0x04 /* Enable Zoom mode */ -#define COM7_COLOR_BAR_TEST 0x02 /* Enable Color Bar Test Pattern */ -#define COM8 0x13 /* Common control 8 */ -#define COM8_DEF 0xC0 /* Banding filter ON/OFF */ -#define COM8_BNDF_EN 0x20 /* Banding filter ON/OFF */ -#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ -#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ -#define COM9 0x14 /* Common control 9 - * Automatic gain ceiling - maximum AGC value [7:5]*/ -#define COM9_AGC_GAIN_2x 0x00 /* 000 : 2x */ -#define COM9_AGC_GAIN_4x 0x20 /* 001 : 4x */ -#define COM9_AGC_GAIN_8x 0x40 /* 010 : 8x */ -#define COM9_AGC_GAIN_16x 0x60 /* 011 : 16x */ -#define COM9_AGC_GAIN_32x 0x80 /* 100 : 32x */ -#define COM9_AGC_GAIN_64x 0xA0 /* 101 : 64x */ -#define COM9_AGC_GAIN_128x 0xC0 /* 110 : 128x */ -#define COM10 0x15 /* Common control 10 */ -#define COM10_PCLK_HREF 0x20 /* PCLK output qualified by HREF */ -#define COM10_PCLK_RISE 0x10 /* Data is updated at the rising edge of - * PCLK (user can latch data at the next - * falling edge of PCLK). - * 0 otherwise. */ -#define COM10_HREF_INV 0x08 /* Invert HREF polarity: - * HREF negative for valid data*/ -#define COM10_VSINC_INV 0x02 /* Invert VSYNC polarity */ -#define HSTART 0x17 /* Horizontal Window start MSB 8 bit */ -#define HEND 0x18 /* Horizontal Window end MSB 8 bit */ -#define VSTART 0x19 /* Vertical Window start MSB 8 bit */ -#define VEND 0x1A /* Vertical Window end MSB 8 bit */ -#define MIDH 0x1C /* Manufacturer ID byte - high */ -#define MIDL 0x1D /* Manufacturer ID byte - low */ -#define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */ -#define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */ -#define VV 0x26 /* AGC/AEC Fast mode operating region */ -#define VV_HIGH_TH_SET(x) VAL_SET(x, 0xF, 0, 4) -#define VV_LOW_TH_SET(x) VAL_SET(x, 0xF, 0, 0) -#define REG2A 0x2A /* Dummy pixel insert MSB */ -#define FRARL 0x2B /* Dummy pixel insert LSB */ -#define ADDVFL 0x2D /* LSB of insert dummy lines in Vertical direction */ -#define ADDVFH 0x2E /* MSB of insert dummy lines in Vertical direction */ -#define YAVG 0x2F /* Y/G Channel Average value */ -#define REG32 0x32 /* Common Control 32 */ -#define REG32_PCLK_DIV_2 0x80 /* PCLK freq divided by 2 */ -#define REG32_PCLK_DIV_4 0xC0 /* PCLK freq divided by 4 */ -#define ARCOM2 0x34 /* Zoom: Horizontal start point */ -#define REG45 0x45 /* Register 45 */ -#define FLL 0x46 /* Frame Length Adjustment LSBs */ -#define FLH 0x47 /* Frame Length Adjustment MSBs */ -#define COM19 0x48 /* Zoom: Vertical start point */ -#define ZOOMS 0x49 /* Zoom: Vertical start point */ -#define COM22 0x4B /* Flash light control */ -#define COM25 0x4E /* For Banding operations */ -#define BD50 0x4F /* 50Hz Banding AEC 8 LSBs */ -#define BD60 0x50 /* 60Hz Banding AEC 8 LSBs */ -#define REG5D 0x5D /* AVGsel[7:0], 16-zone average weight option */ -#define REG5E 0x5E /* AVGsel[15:8], 16-zone average weight option */ -#define REG5F 0x5F /* AVGsel[23:16], 16-zone average weight option */ -#define REG60 0x60 /* AVGsel[31:24], 16-zone average weight option */ -#define HISTO_LOW 0x61 /* Histogram Algorithm Low Level */ -#define HISTO_HIGH 0x62 /* Histogram Algorithm High Level */ - -/* - * ID - */ -#define MANUFACTURER_ID 0x7FA2 -#define PID_OV2640 0x2642 -#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF)) - -/* - * Struct - */ -struct regval_list { - u8 reg_num; - u8 value; -}; - -/* Supported resolutions */ -enum ov2640_width { - W_QCIF = 176, - W_QVGA = 320, - W_CIF = 352, - W_VGA = 640, - W_SVGA = 800, - W_XGA = 1024, - W_SXGA = 1280, - W_UXGA = 1600, -}; - -enum ov2640_height { - H_QCIF = 144, - H_QVGA = 240, - H_CIF = 288, - H_VGA = 480, - H_SVGA = 600, - H_XGA = 768, - H_SXGA = 1024, - H_UXGA = 1200, -}; - -struct ov2640_win_size { - char *name; - enum ov2640_width width; - enum ov2640_height height; - const struct regval_list *regs; -}; - - -struct ov2640_priv { - struct v4l2_subdev subdev; - struct ov2640_camera_info *info; - enum v4l2_mbus_pixelcode cfmt_code; - const struct ov2640_win_size *win; - int model; - u16 flag_vflip:1; - u16 flag_hflip:1; -}; - -/* - * Registers settings - */ - -#define ENDMARKER { 0xff, 0xff } - -static const struct regval_list ov2640_init_regs[] = { - { BANK_SEL, BANK_SEL_DSP }, - { 0x2c, 0xff }, - { 0x2e, 0xdf }, - { BANK_SEL, BANK_SEL_SENS }, - { 0x3c, 0x32 }, - { CLKRC, CLKRC_DIV_SET(1) }, - { COM2, COM2_OCAP_Nx_SET(3) }, - { REG04, REG04_DEF | REG04_HREF_EN }, - { COM8, COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN }, - { COM9, COM9_AGC_GAIN_8x | 0x08}, - { 0x2c, 0x0c }, - { 0x33, 0x78 }, - { 0x3a, 0x33 }, - { 0x3b, 0xfb }, - { 0x3e, 0x00 }, - { 0x43, 0x11 }, - { 0x16, 0x10 }, - { 0x39, 0x02 }, - { 0x35, 0x88 }, - { 0x22, 0x0a }, - { 0x37, 0x40 }, - { 0x23, 0x00 }, - { ARCOM2, 0xa0 }, - { 0x06, 0x02 }, - { 0x06, 0x88 }, - { 0x07, 0xc0 }, - { 0x0d, 0xb7 }, - { 0x0e, 0x01 }, - { 0x4c, 0x00 }, - { 0x4a, 0x81 }, - { 0x21, 0x99 }, - { AEW, 0x40 }, - { AEB, 0x38 }, - { VV, VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) }, - { 0x5c, 0x00 }, - { 0x63, 0x00 }, - { FLL, 0x22 }, - { COM3, 0x38 | COM3_BAND_AUTO }, - { REG5D, 0x55 }, - { REG5E, 0x7d }, - { REG5F, 0x7d }, - { REG60, 0x55 }, - { HISTO_LOW, 0x70 }, - { HISTO_HIGH, 0x80 }, - { 0x7c, 0x05 }, - { 0x20, 0x80 }, - { 0x28, 0x30 }, - { 0x6c, 0x00 }, - { 0x6d, 0x80 }, - { 0x6e, 0x00 }, - { 0x70, 0x02 }, - { 0x71, 0x94 }, - { 0x73, 0xc1 }, - { 0x3d, 0x34 }, - { COM7, COM7_RES_UXGA | COM7_ZOOM_EN }, - { 0x5a, 0x57 }, - { BD50, 0xbb }, - { BD60, 0x9c }, - { BANK_SEL, BANK_SEL_DSP }, - { 0xe5, 0x7f }, - { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL }, - { 0x41, 0x24 }, - { RESET, RESET_JPEG | RESET_DVP }, - { 0x76, 0xff }, - { 0x33, 0xa0 }, - { 0x42, 0x20 }, - { 0x43, 0x18 }, - { 0x4c, 0x00 }, - { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 }, - { 0x88, 0x3f }, - { 0xd7, 0x03 }, - { 0xd9, 0x10 }, - { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 }, - { 0xc8, 0x08 }, - { 0xc9, 0x80 }, - { BPADDR, 0x00 }, - { BPDATA, 0x00 }, - { BPADDR, 0x03 }, - { BPDATA, 0x48 }, - { BPDATA, 0x48 }, - { BPADDR, 0x08 }, - { BPDATA, 0x20 }, - { BPDATA, 0x10 }, - { BPDATA, 0x0e }, - { 0x90, 0x00 }, - { 0x91, 0x0e }, - { 0x91, 0x1a }, - { 0x91, 0x31 }, - { 0x91, 0x5a }, - { 0x91, 0x69 }, - { 0x91, 0x75 }, - { 0x91, 0x7e }, - { 0x91, 0x88 }, - { 0x91, 0x8f }, - { 0x91, 0x96 }, - { 0x91, 0xa3 }, - { 0x91, 0xaf }, - { 0x91, 0xc4 }, - { 0x91, 0xd7 }, - { 0x91, 0xe8 }, - { 0x91, 0x20 }, - { 0x92, 0x00 }, - { 0x93, 0x06 }, - { 0x93, 0xe3 }, - { 0x93, 0x03 }, - { 0x93, 0x03 }, - { 0x93, 0x00 }, - { 0x93, 0x02 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x93, 0x00 }, - { 0x96, 0x00 }, - { 0x97, 0x08 }, - { 0x97, 0x19 }, - { 0x97, 0x02 }, - { 0x97, 0x0c }, - { 0x97, 0x24 }, - { 0x97, 0x30 }, - { 0x97, 0x28 }, - { 0x97, 0x26 }, - { 0x97, 0x02 }, - { 0x97, 0x98 }, - { 0x97, 0x80 }, - { 0x97, 0x00 }, - { 0x97, 0x00 }, - { 0xa4, 0x00 }, - { 0xa8, 0x00 }, - { 0xc5, 0x11 }, - { 0xc6, 0x51 }, - { 0xbf, 0x80 }, - { 0xc7, 0x10 }, - { 0xb6, 0x66 }, - { 0xb8, 0xA5 }, - { 0xb7, 0x64 }, - { 0xb9, 0x7C }, - { 0xb3, 0xaf }, - { 0xb4, 0x97 }, - { 0xb5, 0xFF }, - { 0xb0, 0xC5 }, - { 0xb1, 0x94 }, - { 0xb2, 0x0f }, - { 0xc4, 0x5c }, - { 0xa6, 0x00 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x1b }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x19 }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0xa7, 0x20 }, - { 0xa7, 0xd8 }, - { 0xa7, 0x19 }, - { 0xa7, 0x31 }, - { 0xa7, 0x00 }, - { 0xa7, 0x18 }, - { 0x7f, 0x00 }, - { 0xe5, 0x1f }, - { 0xe1, 0x77 }, - { 0xdd, 0x7f }, - { CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN }, - ENDMARKER, -}; - -/* - * Register settings for window size - * The preamble, setup the internal DSP to input an UXGA (1600x1200) image. - * Then the different zooming configurations will setup the output image size. - */ -static const struct regval_list ov2640_size_change_preamble_regs[] = { - { BANK_SEL, BANK_SEL_DSP }, - { RESET, RESET_DVP }, - { HSIZE8, HSIZE8_SET(W_UXGA) }, - { VSIZE8, VSIZE8_SET(H_UXGA) }, - { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | - CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN }, - { HSIZE, HSIZE_SET(W_UXGA) }, - { VSIZE, VSIZE_SET(H_UXGA) }, - { XOFFL, XOFFL_SET(0) }, - { YOFFL, YOFFL_SET(0) }, - { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) | - VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)}, - { TEST, TEST_HSIZE_SET(W_UXGA) }, - ENDMARKER, -}; - -#define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div) \ - { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \ - CTRLI_H_DIV_SET(h_div)}, \ - { ZMOW, ZMOW_OUTW_SET(x) }, \ - { ZMOH, ZMOH_OUTH_SET(y) }, \ - { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) }, \ - { R_DVP_SP, pclk_div }, \ - { RESET, 0x00} - -static const struct regval_list ov2640_qcif_regs[] = { - PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4), - ENDMARKER, -}; - -static const struct regval_list ov2640_qvga_regs[] = { - PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4), - ENDMARKER, -}; - -static const struct regval_list ov2640_cif_regs[] = { - PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8), - ENDMARKER, -}; - -static const struct regval_list ov2640_vga_regs[] = { - PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2), - ENDMARKER, -}; - -static const struct regval_list ov2640_svga_regs[] = { - PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2), - ENDMARKER, -}; - -static const struct regval_list ov2640_xga_regs[] = { - PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2), - { CTRLI, 0x00}, - ENDMARKER, -}; - -static const struct regval_list ov2640_sxga_regs[] = { - PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2), - { CTRLI, 0x00}, - { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE }, - ENDMARKER, -}; - -static const struct regval_list ov2640_uxga_regs[] = { - PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0), - { CTRLI, 0x00}, - { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE }, - ENDMARKER, -}; - -#define OV2640_SIZE(n, w, h, r) \ - {.name = n, .width = w , .height = h, .regs = r } - -static const struct ov2640_win_size ov2640_supported_win_sizes[] = { - OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs), - OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs), - OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs), - OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs), - OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs), - OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs), - OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs), - OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs), -}; - -/* - * Register settings for pixel formats - */ -static const struct regval_list ov2640_format_change_preamble_regs[] = { - { BANK_SEL, BANK_SEL_DSP }, - { R_BYPASS, R_BYPASS_USE_DSP }, - ENDMARKER, -}; - -static const struct regval_list ov2640_yuv422_regs[] = { - { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 }, - { 0xD7, 0x01 }, - { 0x33, 0xa0 }, - { 0xe1, 0x67 }, - { RESET, 0x00 }, - { R_BYPASS, R_BYPASS_USE_DSP }, - ENDMARKER, -}; - -static const struct regval_list ov2640_rgb565_regs[] = { - { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 }, - { 0xd7, 0x03 }, - { RESET, 0x00 }, - { R_BYPASS, R_BYPASS_USE_DSP }, - ENDMARKER, -}; - -static enum v4l2_mbus_pixelcode ov2640_codes[] = { - V4L2_MBUS_FMT_UYVY8_2X8, - V4L2_MBUS_FMT_RGB565_2X8_LE, -}; - -/* - * Supported controls - */ -static const struct v4l2_queryctrl ov2640_controls[] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Vertically", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Horizontally", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, -}; - -/* - * General functions - */ -static struct ov2640_priv *to_ov2640(const struct i2c_client *client) -{ - return container_of(i2c_get_clientdata(client), struct ov2640_priv, - subdev); -} - -static int ov2640_write_array(struct i2c_client *client, - const struct regval_list *vals) -{ - int ret; - - while ((vals->reg_num != 0xff) || (vals->value != 0xff)) { - ret = i2c_smbus_write_byte_data(client, - vals->reg_num, vals->value); - dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x", - vals->reg_num, vals->value); - - if (ret < 0) - return ret; - vals++; - } - return 0; -} - -static int ov2640_mask_set(struct i2c_client *client, - u8 reg, u8 mask, u8 set) -{ - s32 val = i2c_smbus_read_byte_data(client, reg); - if (val < 0) - return val; - - val &= ~mask; - val |= set & mask; - - dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val); - - return i2c_smbus_write_byte_data(client, reg, val); -} - -static int ov2640_reset(struct i2c_client *client) -{ - int ret; - const struct regval_list reset_seq[] = { - {BANK_SEL, BANK_SEL_SENS}, - {COM7, COM7_SRST}, - ENDMARKER, - }; - - ret = ov2640_write_array(client, reset_seq); - if (ret) - goto err; - - msleep(5); -err: - dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret); - return ret; -} - -/* - * soc_camera_ops functions - */ -static int ov2640_s_stream(struct v4l2_subdev *sd, int enable) -{ - return 0; -} - -static int ov2640_set_bus_param(struct soc_camera_device *icd, - unsigned long flags) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; - - /* Only one width bit may be set */ - if (!is_power_of_2(width_flag)) - return -EINVAL; - - if (icl->set_bus_param) - return icl->set_bus_param(icl, width_flag); - - /* - * Without board specific bus width settings we support only the - * sensors native bus width witch are tested working - */ - if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8)) - return 0; - - return 0; -} - -static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd) -{ - struct soc_camera_link *icl = to_soc_camera_link(icd); - unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | - SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH; - - if (icl->query_bus_param) - flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK; - else - flags |= SOCAM_DATAWIDTH_10; - - return soc_camera_apply_sensor_flags(icl, flags); -} - -static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - ctrl->value = priv->flag_vflip; - break; - case V4L2_CID_HFLIP: - ctrl->value = priv->flag_hflip; - break; - } - return 0; -} - -static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - int ret = 0; - u8 val; - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - val = ctrl->value ? REG04_VFLIP_IMG : 0x00; - priv->flag_vflip = ctrl->value ? 1 : 0; - ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val); - break; - case V4L2_CID_HFLIP: - val = ctrl->value ? REG04_HFLIP_IMG : 0x00; - priv->flag_hflip = ctrl->value ? 1 : 0; - ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val); - break; - } - - return ret; -} - -static int ov2640_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - - id->ident = priv->model; - id->revision = 0; - - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int ov2640_g_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - reg->size = 1; - if (reg->reg > 0xff) - return -EINVAL; - - ret = i2c_smbus_read_byte_data(client, reg->reg); - if (ret < 0) - return ret; - - reg->val = ret; - - return 0; -} - -static int ov2640_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (reg->reg > 0xff || - reg->val > 0xff) - return -EINVAL; - - return i2c_smbus_write_byte_data(client, reg->reg, reg->val); -} -#endif - -/* Select the nearest higher resolution for capture */ -static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height) -{ - int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1; - - for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) { - if (ov2640_supported_win_sizes[i].width >= *width && - ov2640_supported_win_sizes[i].height >= *height) { - *width = ov2640_supported_win_sizes[i].width; - *height = ov2640_supported_win_sizes[i].height; - return &ov2640_supported_win_sizes[i]; - } - } - - *width = ov2640_supported_win_sizes[default_size].width; - *height = ov2640_supported_win_sizes[default_size].height; - return &ov2640_supported_win_sizes[default_size]; -} - -static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height, - enum v4l2_mbus_pixelcode code) -{ - struct ov2640_priv *priv = to_ov2640(client); - const struct regval_list *selected_cfmt_regs; - int ret; - - /* select win */ - priv->win = ov2640_select_win(width, height); - - /* select format */ - priv->cfmt_code = 0; - switch (code) { - case V4L2_MBUS_FMT_RGB565_2X8_LE: - dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__); - selected_cfmt_regs = ov2640_rgb565_regs; - break; - default: - case V4L2_MBUS_FMT_UYVY8_2X8: - dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__); - selected_cfmt_regs = ov2640_yuv422_regs; - } - - /* reset hardware */ - ov2640_reset(client); - - /* initialize the sensor with default data */ - dev_dbg(&client->dev, "%s: Init default", __func__); - ret = ov2640_write_array(client, ov2640_init_regs); - if (ret < 0) - goto err; - - /* select preamble */ - dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name); - ret = ov2640_write_array(client, ov2640_size_change_preamble_regs); - if (ret < 0) - goto err; - - /* set size win */ - ret = ov2640_write_array(client, priv->win->regs); - if (ret < 0) - goto err; - - /* cfmt preamble */ - dev_dbg(&client->dev, "%s: Set cfmt", __func__); - ret = ov2640_write_array(client, ov2640_format_change_preamble_regs); - if (ret < 0) - goto err; - - /* set cfmt */ - ret = ov2640_write_array(client, selected_cfmt_regs); - if (ret < 0) - goto err; - - priv->cfmt_code = code; - *width = priv->win->width; - *height = priv->win->height; - - return 0; - -err: - dev_err(&client->dev, "%s: Error %d", __func__, ret); - ov2640_reset(client); - priv->win = NULL; - - return ret; -} - -static int ov2640_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - - if (!priv->win) { - u32 width = W_SVGA, height = H_SVGA; - int ret = ov2640_set_params(client, &width, &height, - V4L2_MBUS_FMT_UYVY8_2X8); - if (ret < 0) - return ret; - } - - mf->width = priv->win->width; - mf->height = priv->win->height; - mf->code = priv->cfmt_code; - - switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_LE: - mf->colorspace = V4L2_COLORSPACE_SRGB; - break; - default: - case V4L2_MBUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; - } - mf->field = V4L2_FIELD_NONE; - - return 0; -} - -static int ov2640_s_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - - switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_LE: - mf->colorspace = V4L2_COLORSPACE_SRGB; - break; - default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; - } - - ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code); - - return ret; -} - -static int ov2640_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) -{ - const struct ov2640_win_size *win; - - /* - * select suitable win - */ - win = ov2640_select_win(&mf->width, &mf->height); - - mf->field = V4L2_FIELD_NONE; - - switch (mf->code) { - case V4L2_MBUS_FMT_RGB565_2X8_LE: - mf->colorspace = V4L2_COLORSPACE_SRGB; - break; - default: - mf->code = V4L2_MBUS_FMT_UYVY8_2X8; - case V4L2_MBUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; - } - - return 0; -} - -static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) -{ - if (index >= ARRAY_SIZE(ov2640_codes)) - return -EINVAL; - - *code = ov2640_codes[index]; - return 0; -} - -static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) -{ - a->c.left = 0; - a->c.top = 0; - a->c.width = W_UXGA; - a->c.height = H_UXGA; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = W_UXGA; - a->bounds.height = H_UXGA; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; -} - -static int ov2640_video_probe(struct soc_camera_device *icd, - struct i2c_client *client) -{ - struct ov2640_priv *priv = to_ov2640(client); - u8 pid, ver, midh, midl; - const char *devname; - int ret; - - /* - * we must have a parent by now. And it cannot be a wrong one. - * So this entire test is completely redundant. - */ - if (!icd->dev.parent || - to_soc_camera_host(icd->dev.parent)->nr != icd->iface) { - dev_err(&client->dev, "Parent missing or invalid!\n"); - ret = -ENODEV; - goto err; - } - - /* - * check and show product ID and manufacturer ID - */ - i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS); - pid = i2c_smbus_read_byte_data(client, PID); - ver = i2c_smbus_read_byte_data(client, VER); - midh = i2c_smbus_read_byte_data(client, MIDH); - midl = i2c_smbus_read_byte_data(client, MIDL); - - switch (VERSION(pid, ver)) { - case PID_OV2640: - devname = "ov2640"; - priv->model = V4L2_IDENT_OV2640; - break; - default: - dev_err(&client->dev, - "Product ID error %x:%x\n", pid, ver); - ret = -ENODEV; - goto err; - } - - dev_info(&client->dev, - "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", - devname, pid, ver, midh, midl); - - return 0; - -err: - return ret; -} - -static struct soc_camera_ops ov2640_ops = { - .set_bus_param = ov2640_set_bus_param, - .query_bus_param = ov2640_query_bus_param, - .controls = ov2640_controls, - .num_controls = ARRAY_SIZE(ov2640_controls), -}; - -static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { - .g_ctrl = ov2640_g_ctrl, - .s_ctrl = ov2640_s_ctrl, - .g_chip_ident = ov2640_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = ov2640_g_register, - .s_register = ov2640_s_register, -#endif -}; - -static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { - .s_stream = ov2640_s_stream, - .g_mbus_fmt = ov2640_g_fmt, - .s_mbus_fmt = ov2640_s_fmt, - .try_mbus_fmt = ov2640_try_fmt, - .cropcap = ov2640_cropcap, - .g_crop = ov2640_g_crop, - .enum_mbus_fmt = ov2640_enum_fmt, -}; - -static struct v4l2_subdev_ops ov2640_subdev_ops = { - .core = &ov2640_subdev_core_ops, - .video = &ov2640_subdev_video_ops, -}; - -/* - * i2c_driver functions - */ -static int ov2640_probe(struct i2c_client *client, - const struct i2c_device_id *did) -{ - struct ov2640_priv *priv; - struct soc_camera_device *icd = client->dev.platform_data; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; - int ret; - - if (!icd) { - dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n"); - return -EINVAL; - } - - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&adapter->dev, - "OV2640: Missing platform_data for driver\n"); - return -EINVAL; - } - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&adapter->dev, - "OV2640: I2C-Adapter doesn't support SMBUS\n"); - return -EIO; - } - - priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL); - if (!priv) { - dev_err(&adapter->dev, - "Failed to allocate memory for private data!\n"); - return -ENOMEM; - } - - priv->info = icl->priv; - - v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); - - icd->ops = &ov2640_ops; - - ret = ov2640_video_probe(icd, client); - if (ret) { - icd->ops = NULL; - kfree(priv); - } else { - dev_info(&adapter->dev, "OV2640 Probed\n"); - } - - return ret; -} - -static int ov2640_remove(struct i2c_client *client) -{ - struct ov2640_priv *priv = to_ov2640(client); - struct soc_camera_device *icd = client->dev.platform_data; - - icd->ops = NULL; - kfree(priv); - return 0; -} - -static const struct i2c_device_id ov2640_id[] = { - { "ov2640", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, ov2640_id); - -static struct i2c_driver ov2640_i2c_driver = { - .driver = { - .name = "ov2640", - }, - .probe = ov2640_probe, - .remove = ov2640_remove, - .id_table = ov2640_id, -}; - -/* - * Module functions - */ -static int __init ov2640_module_init(void) -{ - return i2c_add_driver(&ov2640_i2c_driver); -} - -static void __exit ov2640_module_exit(void) -{ - i2c_del_driver(&ov2640_i2c_driver); -} - -module_init(ov2640_module_init); -module_exit(ov2640_module_exit); - -MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor"); -MODULE_AUTHOR("Alberto Panizzo"); -MODULE_LICENSE("GPL v2"); -======= #include #include #include @@ -1222,8 +9,8 @@ MODULE_LICENSE("GPL v2"); #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -1254,10 +41,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 1 @@ -1277,10 +65,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -2766,6 +1550,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = sd->priv; @@ -2774,8 +1565,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -2824,7 +1669,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -3998,20 +2843,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov2640_rk.c b/drivers/media/video/ov2640_rk.c index d6b1e385668a..4b77bc0282e7 100755 --- a/drivers/media/video/ov2640_rk.c +++ b/drivers/media/video/ov2640_rk.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -9,8 +9,8 @@ #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -25,6 +25,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) + #define __STR(x) #x #define _STR(x) __STR(x) #define STR(x) _STR(x) @@ -41,10 +42,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 1 @@ -64,9 +66,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 @@ -1553,15 +1552,78 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = sensor_init_data; +static struct reginfo* sensor_init_winseq_p = sensor_svga; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; + int ret,pid = 0,i = 0,j=0; + //if val ==1,mean that sensor need to be reinit + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1611,7 +1673,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -1766,7 +1828,7 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); @@ -1815,7 +1877,7 @@ static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefm } static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; @@ -1995,7 +2057,7 @@ sensor_s_fmt_end: static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); const struct sensor_datafmt *fmt; int ret = 0; @@ -2023,7 +2085,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; @@ -2307,7 +2369,7 @@ static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_que static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; @@ -2366,7 +2428,7 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); struct soc_camera_device *icd = client->dev.platform_data; const struct v4l2_queryctrl *qctrl; @@ -2656,7 +2718,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; int i, error_cnt=0, error_idx=-1; @@ -2681,7 +2743,7 @@ static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; int i, error_cnt=0, error_idx=-1; @@ -2769,7 +2831,7 @@ sensor_video_probe_err: static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); int ret = 0; @@ -2785,20 +2847,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash @@ -2953,4 +3017,4 @@ module_exit(sensor_mod_exit); MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver)); MODULE_AUTHOR("ddl "); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/ov2655.c b/drivers/media/video/ov2655.c index 6d7853134ed5..3e03bddaac98 100755 --- a/drivers/media/video/ov2655.c +++ b/drivers/media/video/ov2655.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 1 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -97,7 +94,7 @@ struct reginfo u8 val; }; -/* init 352X288 SVGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { {0x308c, 0x80}, @@ -1684,6 +1681,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; + static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1692,8 +1697,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1744,7 +1803,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2915,20 +2974,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index 85f5c20e7b8f..02259502ecc5 100755 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 600 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1461,7 +1458,8 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd { struct soc_camera_link *icl = to_soc_camera_link(icd); int ret = 0; - + //for fpga debug ,not control io + //return 0; SENSOR_DG("%s %s cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on); switch (cmd) { @@ -1501,6 +1499,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = sensor_init_data; +static struct reginfo* sensor_init_winseq_p = sensor_svga; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1509,8 +1514,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + //if val ==1,mean that sensor need to be reinit + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1558,7 +1618,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2775,18 +2835,21 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov3640.c b/drivers/media/video/ov3640.c old mode 100644 new mode 100755 index 366516658510..0024ece10919 --- a/drivers/media/video/ov3640.c +++ b/drivers/media/video/ov3640.c @@ -19,7 +19,9 @@ #include #include #include -#include +#include +#include +#include #include "ov3640.h" static int debug; @@ -50,10 +52,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2048 #define SENSOR_MAX_HEIGHT 1536 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_init_data -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -78,11 +81,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -2542,6 +2540,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = sd->priv; @@ -2550,8 +2555,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -2600,7 +2659,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -3985,20 +4044,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov5640.c b/drivers/media/video/ov5640.c index 055ab274d045..30f9ec75279d 100755 --- a/drivers/media/video/ov5640.c +++ b/drivers/media/video/ov5640.c @@ -19,9 +19,9 @@ #include #include #include -#include +#include #include "ov5640.h" - +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2592 #define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -81,9 +82,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_WRITE_REGS 1 #define WRITE_REGS_NUM 100 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 @@ -2363,6 +2361,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = sensor_init_data; +static struct reginfo* sensor_init_winseq_p = sensor_svga; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -2371,7 +2376,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; + int ret,pid = 0,i = 0,j=0; + //if val ==1,mean that sensor need to be reinit + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -2419,7 +2480,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; @@ -3786,20 +3847,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov5640_for_td8801.c b/drivers/media/video/ov5640_for_td8801.c old mode 100644 new mode 100755 index 69be80bf4c54..f9f71e3ea290 --- a/drivers/media/video/ov5640_for_td8801.c +++ b/drivers/media/video/ov5640_for_td8801.c @@ -19,9 +19,9 @@ #include #include #include -#include +#include #include "ov5640.h" - +#include static int debug = 1; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2592 #define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -81,9 +82,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_WRITE_REGS 1 #define WRITE_REGS_NUM 100 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 @@ -2363,6 +2361,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = sensor_init_data; +static struct reginfo* sensor_init_winseq_p = sensor_svga; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -2371,7 +2376,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; + int ret,pid = 0,i = 0,j=0; + //if val ==1,mean that sensor need to be reinit + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -2419,7 +2480,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; @@ -3786,20 +3847,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index 98816754ee17..701558c2f606 100755 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include "ov5642.h" static int debug; @@ -50,10 +51,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 2592 #define SENSOR_MAX_HEIGHT 1944 -#define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 600 -#define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -78,11 +80,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -164,7 +161,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define StepFocus_Nearest_Tag 0x04 #define StepFocus_Spec_Tag 0x10 #endif - /* init 800X600 SVGA */ static struct reginfo sensor_init_data[] = { @@ -4243,6 +4239,14 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } + +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -4251,8 +4255,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; char value; - int ret,pid = 0; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && (i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -4299,7 +4357,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; @@ -5706,18 +5764,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ diff --git a/drivers/media/video/ov7675.c b/drivers/media/video/ov7675.c index 03d19f88929f..814299f64cc6 100755 --- a/drivers/media/video/ov7675.c +++ b/drivers/media/video/ov7675.c @@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -51,10 +51,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480//144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -74,10 +75,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -95,8 +92,7 @@ struct reginfo u8 reg; u8 val; }; - -/* init 640X480 VGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { {0x12, 0x80}, @@ -1383,6 +1379,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 800; +static s32 sensor_init_height = 600; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1390,7 +1393,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_svga; + sensor_init_width = 800; + sensor_init_height = 600; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1412,7 +1470,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) mdelay(5); //delay 5 microseconds - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2570,19 +2628,21 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/ov7690.c b/drivers/media/video/ov7690.c old mode 100644 new mode 100755 index 3e9884ec330b..d197720f4bd3 --- a/drivers/media/video/ov7690.c +++ b/drivers/media/video/ov7690.c @@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +50,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,10 +74,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -94,7 +91,8 @@ struct reginfo u8 reg; u8 val; }; -/* init 640X480 VGA */ + +/* init 640*480 VGA */ static struct reginfo sensor_init_data[] = { {0x12, 0x80}, @@ -1179,6 +1177,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1186,8 +1191,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; - + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1207,7 +1266,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } mdelay(5); //delay 5 microseconds - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2386,20 +2445,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/rk29_camera.c b/drivers/media/video/rk29_camera.c index e8c4898f4f94..e5efd4a76731 100755 --- a/drivers/media/video/rk29_camera.c +++ b/drivers/media/video/rk29_camera.c @@ -1551,7 +1551,6 @@ static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, { struct rk29camera_gpio_res *res = NULL; 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)) { res = (struct rk29camera_gpio_res *)&rk29_camera_platform_data.gpio_res[0]; } 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)) { @@ -1561,7 +1560,6 @@ static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, ret = RK29_CAM_EIO_INVALID; goto rk29_sensor_ioctrl_end; } - switch (cmd) { case Cam_Power: diff --git a/drivers/media/video/rk29_camera_oneframe.c b/drivers/media/video/rk29_camera_oneframe.c index 53232ef559e1..80b98127b6e7 100755 --- a/drivers/media/video/rk29_camera_oneframe.c +++ b/drivers/media/video/rk29_camera_oneframe.c @@ -9,7 +9,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ - +#if CONFIG_ARCH_RK29 #include #include #include @@ -553,7 +553,6 @@ static void rk29_camera_capture_process(struct work_struct *work) vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; src_y_size = pcdev->host_width*pcdev->host_height; dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height; - for (h=0; hstate = VIDEOBUF_ERROR; spin_unlock_irqrestore(&pcdev->lock, flags); - RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i); - RK29CAMERA_TR("widx:%d hidx:%d ",w,h); - RK29CAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height); - RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst); - RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h); - RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt); - RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst); - RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h); - RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt); - RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w); - RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag); + printk("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i); + printk("widx:%d hidx:%d ",w,h); + printk("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height); + printk("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst); + printk("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h); + printk("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt); + printk("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst); + printk("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h); + printk("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt); + printk("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w); + printk("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag); goto do_ipp_err; } @@ -2231,3 +2230,4 @@ module_exit(rk29_camera_exit); MODULE_DESCRIPTION("RK29 Soc Camera Host driver"); MODULE_AUTHOR("ddl "); MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/media/video/rk30_camera.c b/drivers/media/video/rk30_camera.c new file mode 100755 index 000000000000..768ee708dd08 --- /dev/null +++ b/drivers/media/video/rk30_camera.c @@ -0,0 +1,1704 @@ +#include +#include +#include +#include +#ifndef PMEM_CAM_SIZE +#ifdef CONFIG_VIDEO_RK29 +/*---------------- Camera Sensor Fixed Macro Begin ------------------------*/ +// Below Macro is fixed, programer don't change it!!!!!! +#define _CONS(a,b) a##b +#define CONS(a,b) _CONS(a,b) + +#define __STR(x) #x +#define _STR(x) __STR(x) +#define STR(x) _STR(x) + +#if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00) +#define PMEM_SENSOR_FULL_RESOLUTION_0 CONS(CONFIG_SENSOR_0,_FULL_RESOLUTION) +#define SENSOR_CIF_BUSID_0 CONS(RK_CAM_PLATFORM_DEV_ID_,CONFIG_SENSOR_CIF_INDEX_0) +#if !(PMEM_SENSOR_FULL_RESOLUTION_0) +#undef PMEM_SENSOR_FULL_RESOLUTION_0 +#define PMEM_SENSOR_FULL_RESOLUTION_0 0x500000 +#endif +#else +#define PMEM_SENSOR_FULL_RESOLUTION_0 0x00 +#endif + +#if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00) +#define PMEM_SENSOR_FULL_RESOLUTION_1 CONS(CONFIG_SENSOR_1,_FULL_RESOLUTION) +#define SENSOR_CIF_BUSID_1 CONS(RK_CAM_PLATFORM_DEV_ID_,CONFIG_SENSOR_CIF_INDEX_1) +#if !(PMEM_SENSOR_FULL_RESOLUTION_1) +#undef PMEM_SENSOR_FULL_RESOLUTION_1 +#define PMEM_SENSOR_FULL_RESOLUTION_1 0x500000 +#endif +#else +#define PMEM_SENSOR_FULL_RESOLUTION_1 0x00 +#endif + +#if (PMEM_SENSOR_FULL_RESOLUTION_0 > PMEM_SENSOR_FULL_RESOLUTION_1) +#define PMEM_CAM_FULL_RESOLUTION PMEM_SENSOR_FULL_RESOLUTION_0 +#else +#define PMEM_CAM_FULL_RESOLUTION PMEM_SENSOR_FULL_RESOLUTION_1 +#endif + +#if (PMEM_CAM_FULL_RESOLUTION == 0x500000) +#define PMEM_CAM_NECESSARY 0x1400000 /* 1280*720*1.5*4(preview) + 7.5M(capture raw) + 4M(jpeg encode output) */ +#define PMEM_CAMIPP_NECESSARY 0x800000 +#elif (PMEM_CAM_FULL_RESOLUTION == 0x300000) +#define PMEM_CAM_NECESSARY 0xe00000 /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */ +#define PMEM_CAMIPP_NECESSARY 0x500000 +#elif (PMEM_CAM_FULL_RESOLUTION == 0x200000) /* 1280*720*1.5*4(preview) + 3M(capture raw) + 3M(jpeg encode output) */ +#define PMEM_CAM_NECESSARY 0xc00000 +#define PMEM_CAMIPP_NECESSARY 0x400000 +#elif ((PMEM_CAM_FULL_RESOLUTION == 0x100000) || (PMEM_CAM_FULL_RESOLUTION == 0x130000)) +#define PMEM_CAM_NECESSARY 0x800000 /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */ +#define PMEM_CAMIPP_NECESSARY 0x400000 +#elif (PMEM_CAM_FULL_RESOLUTION == 0x30000) +#define PMEM_CAM_NECESSARY 0x400000 /* 640*480*1.5*4(preview) + 1M(capture raw) + 1M(jpeg encode output) */ +#define PMEM_CAMIPP_NECESSARY 0x400000 +#else +#define PMEM_CAM_NECESSARY 0x1200000 +#define PMEM_CAMIPP_NECESSARY 0x800000 +#endif +/*---------------- Camera Sensor Fixed Macro End ------------------------*/ +#else //#ifdef CONFIG_VIDEO_RK +#define PMEM_CAM_NECESSARY 0x00000000 +#endif +#else // #ifdef PMEM_CAM_SIZE + +/***************************************************************************************** + * camera devices + * author: ddl@rock-chips.com + *****************************************************************************************/ +#ifdef CONFIG_VIDEO_RK29 +static int camera_debug; +module_param(camera_debug, int, S_IRUGO|S_IWUSR); + +#define ddprintk(level, fmt, arg...) do { \ + if (camera_debug >= level) \ + printk(KERN_WARNING"rk_cam_io: " fmt , ## arg); } while (0) + +#define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__) + +#define SENSOR_NAME_0 STR(CONFIG_SENSOR_0) /* back camera sensor */ +#define SENSOR_NAME_1 STR(CONFIG_SENSOR_1) /* front camera sensor */ +#define SENSOR_DEVICE_NAME_0 STR(CONS(CONFIG_SENSOR_0, _back)) +#define SENSOR_DEVICE_NAME_1 STR(CONS(CONFIG_SENSOR_1, _front)) + +static int rk_sensor_io_init(void); +static int rk_sensor_io_deinit(int sensor); +static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on); +static int rk_sensor_power(struct device *dev, int on); +static int rk_sensor_reset(struct device *dev); +static int rk_sensor_powerdown(struct device *dev, int on); +static struct rk29camera_platform_data rk_camera_platform_data = { + .io_init = rk_sensor_io_init, + .io_deinit = rk_sensor_io_deinit, + .sensor_ioctrl = rk_sensor_ioctrl, + + .gpio_res[0] = { + .gpio_reset = INVALID_GPIO, + .gpio_power = INVALID_GPIO, + .gpio_powerdown = INVALID_GPIO, + .gpio_flash = INVALID_GPIO, + .gpio_flag = 0, + .gpio_init = 0, + .dev_name = NULL, + }, + .gpio_res[1] = { + .gpio_reset = INVALID_GPIO, + .gpio_power = INVALID_GPIO, + .gpio_powerdown = INVALID_GPIO, + .gpio_flash = INVALID_GPIO, + .gpio_flag = 0, + .gpio_init = 0, + .dev_name = NULL, + }, + .info[0] = { + .dev_name = NULL, + .orientation = 0, + }, + .info[1] = { + .dev_name = NULL, + .orientation = 0, + }, + .sensor_init_data[0] = NULL, + .sensor_init_data[1] = NULL, +}; + +#if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00) +static struct i2c_board_info rk_i2c_cam_info_0[] = { + { + I2C_BOARD_INFO(SENSOR_NAME_0, CONFIG_SENSOR_IIC_ADDR_0>>1) + }, +}; + +static struct soc_camera_link rk_iclink_0 = { + .bus_id= SENSOR_CIF_BUSID_0, + .power = rk_sensor_power, +#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) + .reset = rk_sensor_reset, +#endif + .powerdown = rk_sensor_powerdown, + .board_info = &rk_i2c_cam_info_0[0], + + .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_0, + .module_name = SENSOR_NAME_0, +}; + +/*platform_device: soc-camera need */ + struct platform_device rk_soc_camera_pdrv_0 = { + .name = "soc-camera-pdrv", + .id = 0, + .dev = { + .init_name = SENSOR_DEVICE_NAME_0, + .platform_data = &rk_iclink_0, + }, +}; +#else + struct platform_device rk_soc_camera_pdrv_0 = { + .name = NULL, +}; +#endif +#if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00) +static struct i2c_board_info rk_i2c_cam_info_1[] = { + { + I2C_BOARD_INFO(SENSOR_NAME_1, CONFIG_SENSOR_IIC_ADDR_1>>1) + }, +}; + +static struct soc_camera_link rk_iclink_1 = { + .bus_id = SENSOR_CIF_BUSID_1, + .power = rk_sensor_power, +#if (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) + .reset = rk_sensor_reset, +#endif + .powerdown = rk_sensor_powerdown, + .board_info = &rk_i2c_cam_info_1[0], + .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_1, + .module_name = SENSOR_NAME_1, +}; + +/*platform_device : soc-camera need */ + struct platform_device rk_soc_camera_pdrv_1 = { + .name = "soc-camera-pdrv", + .id = 1, + .dev = { + .init_name = SENSOR_DEVICE_NAME_1, + .platform_data = &rk_iclink_1, + }, +}; +#else + struct platform_device rk_soc_camera_pdrv_1 = { + .name = NULL, +}; +#endif + +static u64 rockchip_device_camera_dmamask = 0xffffffffUL; +static struct resource rk_camera_resource_host_0[] = { + [0] = { + .start = RK30_CIF0_PHYS, + .end = RK30_CIF0_PHYS + RK30_CIF0_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CIF0, + .end = IRQ_CIF0, + .flags = IORESOURCE_IRQ, + } +}; +static struct resource rk_camera_resource_host_1[] = { + [0] = { + .start = RK30_CIF1_PHYS, + .end = RK30_CIF1_PHYS + RK30_CIF1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_CIF1, + .end = IRQ_CIF1, + .flags = IORESOURCE_IRQ, + } +}; +/*platform_device : */ + struct platform_device rk_device_camera_host_0 = { + .name = RK29_CAM_DRV_NAME, + .id = RK_CAM_PLATFORM_DEV_ID_0, /* This is used to put cameras on this interface */ + .num_resources = ARRAY_SIZE(rk_camera_resource_host_0), + .resource = rk_camera_resource_host_0, + .dev = { + .dma_mask = &rockchip_device_camera_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &rk_camera_platform_data, + } +}; +/*platform_device : */ + struct platform_device rk_device_camera_host_1 = { + .name = RK29_CAM_DRV_NAME, + .id = RK_CAM_PLATFORM_DEV_ID_1, /* This is used to put cameras on this interface */ + .num_resources = ARRAY_SIZE(rk_camera_resource_host_1), + .resource = rk_camera_resource_host_1, + .dev = { + .dma_mask = &rockchip_device_camera_dmamask, + .coherent_dma_mask = 0xffffffffUL, + .platform_data = &rk_camera_platform_data, + } +}; + +static void rk_init_camera_plateform_data(void) +{ + struct rk29camera_platform_data* tmp_host_plateform_data = &rk_camera_platform_data; + int cam_index_in = 0; +#if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00) + if(cam_index_in < RK_CAM_NUM){ + tmp_host_plateform_data->sensor_init_data[cam_index_in] = rk_init_data_sensor_0_p; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_reset= CONFIG_SENSOR_RESET_PIN_0; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_power= CONFIG_SENSOR_POWER_PIN_0; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_powerdown= CONFIG_SENSOR_POWERDN_PIN_0; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_flash= CONFIG_SENSOR_FALSH_PIN_0; + tmp_host_plateform_data->gpio_res[cam_index_in].dev_name= SENSOR_DEVICE_NAME_0; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_flag= (CONFIG_SENSOR_POWERACTIVE_LEVEL_0|CONFIG_SENSOR_RESETACTIVE_LEVEL_0|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0|CONFIG_SENSOR_FLASHACTIVE_LEVEL_0); + tmp_host_plateform_data->gpio_res[cam_index_in].dev_name= SENSOR_DEVICE_NAME_0; + tmp_host_plateform_data->info[cam_index_in].dev_name= SENSOR_DEVICE_NAME_0; + tmp_host_plateform_data->info[cam_index_in].orientation= CONFIG_SENSOR_ORIENTATION_0; + } + cam_index_in++; +#endif +#if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00) + if(cam_index_in < RK_CAM_NUM){ + tmp_host_plateform_data->sensor_init_data[cam_index_in] = rk_init_data_sensor_1_p; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_reset= CONFIG_SENSOR_RESET_PIN_1; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_power= CONFIG_SENSOR_POWER_PIN_1; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_powerdown= CONFIG_SENSOR_POWERDN_PIN_1; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_flash= CONFIG_SENSOR_FALSH_PIN_1; + tmp_host_plateform_data->gpio_res[cam_index_in].dev_name= SENSOR_DEVICE_NAME_1; + tmp_host_plateform_data->gpio_res[cam_index_in].gpio_flag= (CONFIG_SENSOR_POWERACTIVE_LEVEL_1|CONFIG_SENSOR_RESETACTIVE_LEVEL_1|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1|CONFIG_SENSOR_FLASHACTIVE_LEVEL_1); + tmp_host_plateform_data->gpio_res[cam_index_in].dev_name= SENSOR_DEVICE_NAME_1; + tmp_host_plateform_data->info[cam_index_in].dev_name= SENSOR_DEVICE_NAME_1; + tmp_host_plateform_data->info[cam_index_in].orientation= CONFIG_SENSOR_ORIENTATION_1; + } + cam_index_in++; +#endif +} + +static int rk_sensor_iomux(int pin) +{ + switch (pin) + { + case RK30_PIN0_PA0: + { + rk30_mux_api_set(GPIO0A0_HDMIHOTPLUGIN_NAME,0); + break; + } + case RK30_PIN0_PA1: + { + rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME,0); + break; + } + case RK30_PIN0_PA2: + { + rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME,0); + break; + } + case RK30_PIN0_PA3: + { + rk30_mux_api_set(GPIO0A3_PWM0_NAME,0); + break; + } + case RK30_PIN0_PA4: + { + rk30_mux_api_set(GPIO0A4_PWM1_NAME,0); + break; + } + case RK30_PIN0_PA5: + { + rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME,0); + break; + } + case RK30_PIN0_PA6: + { + rk30_mux_api_set(GPIO0A6_HOSTDRVVBUS_NAME,0); + break; + } + case RK30_PIN0_PA7: + { + rk30_mux_api_set(GPIO0A7_I2S8CHSDI_NAME,0); + break; + } + case RK30_PIN0_PB0: + { + rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME,0); + break; + } + case RK30_PIN0_PB1: + { + rk30_mux_api_set(GPIO0B1_I2S8CHSCLK_NAME,0); + break; + } + case RK30_PIN0_PB2: + { + rk30_mux_api_set(GPIO0B2_I2S8CHLRCKRX_NAME,0); + break; + } + case RK30_PIN0_PB3: + { + rk30_mux_api_set(GPIO0B3_I2S8CHLRCKTX_NAME,0); + break; + } + case RK30_PIN0_PB4: + { + rk30_mux_api_set(GPIO0B4_I2S8CHSDO0_NAME,0); + break; + } + case RK30_PIN0_PB5: + { + rk30_mux_api_set(GPIO0B5_I2S8CHSDO1_NAME,0); + break; + } + case RK30_PIN0_PB6: + { + rk30_mux_api_set(GPIO0B6_I2S8CHSDO2_NAME,0); + break; + } + case RK30_PIN0_PB7: + { + rk30_mux_api_set(GPIO0B7_I2S8CHSDO3_NAME,0); + break; + } + case RK30_PIN0_PC0: + { + rk30_mux_api_set(GPIO0C0_I2S12CHCLK_NAME,0); + break; + } + case RK30_PIN0_PC1: + { + rk30_mux_api_set(GPIO0C1_I2S12CHSCLK_NAME,0); + break; + } + case RK30_PIN0_PC2: + { + rk30_mux_api_set(GPIO0C2_I2S12CHLRCKRX_NAME,0); + break; + } + case RK30_PIN0_PC3: + { + rk30_mux_api_set(GPIO0C3_I2S12CHLRCKTX_NAME,0); + break; + } + case RK30_PIN0_PC4: + { + rk30_mux_api_set(GPIO0C4_I2S12CHSDI_NAME,0); + break; + } + case RK30_PIN0_PC5: + { + rk30_mux_api_set(GPIO0C5_I2S12CHSDO_NAME,0); + break; + } + case RK30_PIN0_PC6: + { + rk30_mux_api_set(GPIO0C6_TRACECLK_SMCADDR2_NAME,0); + break; + } + case RK30_PIN0_PC7: + { + rk30_mux_api_set(GPIO0C7_TRACECTL_SMCADDR3_NAME,0); + break; + } + case RK30_PIN0_PD0: + { + rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME,0); + break; + } + case RK30_PIN0_PD1: + { + rk30_mux_api_set(GPIO0D1_I2S22CHSCLK_SMCWEN_NAME,0); + break; + } + case RK30_PIN0_PD2: + { + rk30_mux_api_set(GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME,0); + break; + } + case RK30_PIN0_PD3: + { + rk30_mux_api_set(GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME,0); + break; + } + case RK30_PIN0_PD4: + { + rk30_mux_api_set(GPIO0D4_I2S22CHSDI_SMCADDR0_NAME,0); + break; + } + case RK30_PIN0_PD5: + { + rk30_mux_api_set(GPIO0D5_I2S22CHSDO_SMCADDR1_NAME,0); + break; + } + case RK30_PIN0_PD6: + { + rk30_mux_api_set(GPIO0D6_PWM2_NAME,0); + break; + } + case RK30_PIN0_PD7: + { + rk30_mux_api_set(GPIO0D7_PWM3_NAME,0); + break; + } + case RK30_PIN1_PA0: + { + rk30_mux_api_set(GPIO1A0_UART0SIN_NAME,0); + break; + } + case RK30_PIN1_PA1: + { + rk30_mux_api_set(GPIO1A1_UART0SOUT_NAME,0); + break; + } + case RK30_PIN1_PA2: + { + rk30_mux_api_set(GPIO1A2_UART0CTSN_NAME,0); + break; + } + case RK30_PIN1_PA3: + { + rk30_mux_api_set(GPIO1A3_UART0RTSN_NAME,0); + break; + } + case RK30_PIN1_PA4: + { + rk30_mux_api_set(GPIO1A4_UART1SIN_SPI0CSN0_NAME,0); + break; + } + case RK30_PIN1_PA5: + { + rk30_mux_api_set(GPIO1A5_UART1SOUT_SPI0CLK_NAME,0); + break; + } + case RK30_PIN1_PA6: + { + rk30_mux_api_set(GPIO1A6_UART1CTSN_SPI0RXD_NAME,0); + break; + } + case RK30_PIN1_PA7: + { + rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME,0); + break; + } + case RK30_PIN1_PB0: + { + rk30_mux_api_set(GPIO1B0_UART2SIN_NAME,0); + break; + } + case RK30_PIN1_PB1: + { + rk30_mux_api_set(GPIO1B1_UART2SOUT_NAME,0); + break; + } + case RK30_PIN1_PB2: + { + rk30_mux_api_set(GPIO1B2_SPDIFTX_NAME,0); + break; + } + case RK30_PIN1_PB3: + { + rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME,0); + break; + } + case RK30_PIN1_PB4: + { + rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME,0); + break; + } + case RK30_PIN1_PB5: + { + rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME,0); + break; + } + case RK30_PIN1_PB6: + { + rk30_mux_api_set(GPIO1B6_CIFDATA10_NAME,0); + break; + } + case RK30_PIN1_PB7: + { + rk30_mux_api_set(GPIO1B7_CIFDATA11_NAME,0); + break; + } + case RK30_PIN1_PC0: + { + rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,0); + break; + } + case RK30_PIN1_PC1: + { + rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,0); + break; + } + case RK30_PIN1_PC2: + { + rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,0); + break; + } + case RK30_PIN1_PC3: + { + rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,0); + break; + } + case RK30_PIN1_PC4: + { + rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,0); + break; + } + case RK30_PIN1_PC5: + { + rk29_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,0); + break; + } + case RK30_PIN1_PC6: + { + rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,0); + break; + } + case RK30_PIN1_PC7: + { + rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,0); + break; + } + case RK30_PIN1_PD0: + { + rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,0); + break; + } + case RK30_PIN1_PD1: + { + rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,0); + break; + } + case RK30_PIN1_PD2: + { + rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,0); + break; + } + case RK30_PIN1_PD3: + { + rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,0); + break; + } + case RK30_PIN1_PD4: + { + rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,0); + break; + } + case RK30_PIN1_PD5: + { + rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,0); + break; + } + case RK30_PIN1_PD6: + { + rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,0); + break; + } + case RK30_PIN1_PD7: + { + rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,0); + break; + } + case RK30_PIN2_PA0: + { + rk30_mux_api_set(GPIO2A0_LCDC1DATA0_SMCADDR4_NAME,0); + break; + } + case RK30_PIN2_PA1: + { + rk30_mux_api_set(GPIO2A1_LCDC1DATA1_SMCADDR5_NAME,0); + break; + } + case RK30_PIN2_PA2: + { + rk30_mux_api_set(GPIO2A2_LCDCDATA2_SMCADDR6_NAME,0); + break; + } + case RK30_PIN2_PA3: + { + rk30_mux_api_set(GPIO2A3_LCDCDATA3_SMCADDR7_NAME,0); + break; + } + case RK30_PIN2_PA4: + { + rk30_mux_api_set(GPIO2A4_LCDC1DATA4_SMCADDR8_NAME,0); + break; + } + case RK30_PIN2_PA5: + { + rk30_mux_api_set(GPIO2A5_LCDC1DATA5_SMCADDR9_NAME,0); + break; + } + case RK30_PIN2_PA6: + { + rk30_mux_api_set(GPIO2A6_LCDC1DATA6_SMCADDR10_NAME,0); + break; + } + case RK30_PIN2_PA7: + { + rk30_mux_api_set(GPIO2A7_LCDC1DATA7_SMCADDR11_NAME,0); + break; + } + case RK30_PIN2_PB0: + { + rk30_mux_api_set(GPIO2B0_LCDC1DATA8_SMCADDR12_NAME,0); + break; + } + case RK30_PIN2_PB1: + { + rk30_mux_api_set(GPIO2B1_LCDC1DATA9_SMCADDR13_NAME,0); + break; + } + case RK30_PIN2_PB2: + { + rk30_mux_api_set(GPIO2B2_LCDC1DATA10_SMCADDR14_NAME,0); + break; + } + case RK30_PIN2_PB3: + { + rk30_mux_api_set(GPIO2B3_LCDC1DATA11_SMCADDR15_NAME,0); + break; + } + case RK30_PIN2_PB4: + { + rk30_mux_api_set(GPIO2B4_LCDC1DATA12_SMCADDR16_HSADCDATA9_NAME,0); + break; + } + case RK30_PIN2_PB5: + { + rk30_mux_api_set(GPIO2B5_LCDC1DATA13_SMCADDR17_HSADCDATA8_NAME,0); + break; + } + case RK30_PIN2_PB6: + { + rk30_mux_api_set(GPIO2B6_LCDC1DATA14_SMCADDR18_TSSYNC_NAME,0); + break; + } + case RK30_PIN2_PB7: + { + rk30_mux_api_set(GPIO2B7_LCDC1DATA15_SMCADDR19_HSADCDATA7_NAME,0); + break; + } + case RK30_PIN2_PC0: + { + rk30_mux_api_set(GPIO2C0_LCDCDATA16_GPSCLK_HSADCCLKOUT_NAME,0); + break; + } + case RK30_PIN2_PC1: + { + rk30_mux_api_set(GPIO2C1_LCDC1DATA17_SMCBLSN0_HSADCDATA6_NAME,0); + break; + } + case RK30_PIN2_PC2: + { + rk30_mux_api_set(GPIO2C2_LCDC1DATA18_SMCBLSN1_HSADCDATA5_NAME,0); + break; + } + case RK30_PIN2_PC3: + { + rk29_mux_api_set(GPIO2C3_LCDC1DATA19_SPI1CLK_HSADCDATA0_NAME,0); + break; + } + case RK30_PIN2_PC4: + { + rk30_mux_api_set(GPIO2C4_LCDC1DATA20_SPI1CSN0_HSADCDATA1_NAME,0); + break; + } + case RK30_PIN2_PC5: + { + rk30_mux_api_set(GPIO2C5_LCDC1DATA21_SPI1TXD_HSADCDATA2_NAME,0); + break; + } + case RK30_PIN2_PC6: + { + rk30_mux_api_set(GPIO2C6_LCDC1DATA22_SPI1RXD_HSADCDATA3_NAME,0); + break; + } + case RK30_PIN2_PC7: + { + rk30_mux_api_set(GPIO2C7_LCDC1DATA23_SPI1CSN1_HSADCDATA4_NAME,0); + break; + } + case RK30_PIN2_PD0: + { + rk30_mux_api_set(GPIO2D0_LCDC1DCLK_NAME,0); + break; + } + case RK30_PIN2_PD1: + { + rk30_mux_api_set(GPIO2D1_LCDC1DEN_SMCCSN1_NAME,0); + break; + } + case RK30_PIN2_PD2: + { + rk30_mux_api_set(GPIO2D2_LCDC1HSYNC_NAME,0); + break; + } + case RK30_PIN2_PD3: + { + rk30_mux_api_set(GPIO2D3_LCDC1VSYNC_NAME,0); + break; + } + case RK30_PIN2_PD4: + { + rk30_mux_api_set(GPIO2D4_I2C0SDA_NAME,0); + break; + } + case RK30_PIN2_PD5: + { + rk30_mux_api_set(GPIO2D5_I2C0SCL_NAME,0); + break; + } + case RK30_PIN2_PD6: + { + rk30_mux_api_set(GPIO2D6_I2C1SDA_NAME,0); + break; + } + case RK30_PIN2_PD7: + { + rk30_mux_api_set(GPIO2D7_I2C1SCL_NAME,0); + break; + } + case RK30_PIN3_PA0: + { + rk30_mux_api_set(GPIO3A0_I2C2SDA_NAME,0); + break; + } + case RK30_PIN3_PA1: + { + rk30_mux_api_set(GPIO3A1_I2C2SCL_NAME,0); + break; + } + case RK30_PIN3_PA2: + { + rk30_mux_api_set(GPIO3A2_I2C3SDA_NAME,0); + break; + } + case RK30_PIN3_PA3: + { + rk30_mux_api_set(GPIO3A3_I2C3SCL_NAME,0); + break; + } + case RK30_PIN3_PA4: + { + rk30_mux_api_set(GPIO3A4_I2C4SDA_NAME,0); + break; + } + case RK30_PIN3_PA5: + { + rk30_mux_api_set(GPIO3A5_I2C4SCL_NAME,0); + break; + } + case RK30_PIN3_PA6: + { + rk30_mux_api_set(GPIO3A6_SDMMC0RSTNOUT_NAME,0); + break; + } + case RK30_PIN3_PA7: + { + rk30_mux_api_set(GPIO3A7_SDMMC0WRITEPRT_NAME,0); + break; + } + case RK30_PIN3_PB0: + { + rk30_mux_api_set(GPIO3B0_SDMMC0CLKOUT_NAME,0); + break; + } + case RK30_PIN3_PB1: + { + rk30_mux_api_set(GPIO3B1_SDMMC0CMD_NAME,0); + break; + } + case RK30_PIN3_PB2: + { + rk30_mux_api_set(GPIO3B2_SDMMC0DATA0_NAME,0); + break; + } + case RK30_PIN3_PB3: + { + rk30_mux_api_set(GPIO3B3_SDMMC0DATA1_NAME,0); + break; + } + case RK30_PIN3_PB4: + { + rk30_mux_api_set(GPIO3B4_SDMMC0DATA2_NAME,0); + break; + } + case RK30_PIN3_PB5: + { + rk30_mux_api_set(GPIO3B5_SDMMC0DATA3_NAME,0); + break; + } + case RK30_PIN3_PB6: + { + rk30_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME,0); + break; + } + case RK30_PIN3_PB7: + { + rk30_mux_api_set(GPIO3B7_SDMMC0WRITEPRT_NAME,0); + break; + } + case RK30_PIN3_PC0: + { + rk30_mux_api_set(GPIO3C0_SMMC1CMD_NAME,0); + break; + } + case RK30_PIN3_PC1: + { + rk30_mux_api_set(GPIO3C1_SDMMC1DATA0_NAME,0); + break; + } + case RK30_PIN3_PC2: + { + rk30_mux_api_set(GPIO3C2_SDMMC1DATA1_NAME,0); + break; + } + case RK30_PIN3_PC3: + { + rk30_mux_api_set(GPIO3C3_SDMMC1DATA2_NAME,0); + break; + } + case RK30_PIN3_PC4: + { + rk30_mux_api_set(GPIO3C4_SDMMC1DATA3_NAME,0); + break; + } + case RK30_PIN3_PC5: + { + rk30_mux_api_set(GPIO3C5_SDMMC1CLKOUT_NAME,0); + break; + } + case RK30_PIN3_PC6: + { + rk30_mux_api_set(GPIO3C6_SDMMC1DETECTN_NAME,0); + break; + } + case RK30_PIN3_PC7: + { + rk30_mux_api_set(GPIO3C7_SDMMC1WRITEPRT_NAME,0); + break; + } + case RK30_PIN3_PD0: + { + rk30_mux_api_set(GPIO3D0_SDMMC1PWREN_NAME,0); + break; + } + case RK30_PIN3_PD1: + { + rk30_mux_api_set(GPIO3D1_SDMMC1BACKENDPWR_NAME,0); + break; + } + case RK30_PIN3_PD2: + { + rk30_mux_api_set(GPIO3D2_SDMMC1INTN_NAME,0); + break; + } + case RK30_PIN3_PD3: + { + rk30_mux_api_set(GPIO3D3_UART3SIN_NAME,0); + break; + } + case RK30_PIN3_PD4: + { + rk30_mux_api_set(GPIO3D4_UART3SOUT_NAME,0); + break; + } + case RK30_PIN3_PD5: + { + rk30_mux_api_set(GPIO3D5_UART3CTSN_NAME,0); + break; + } + case RK30_PIN3_PD6: + { + rk30_mux_api_set(GPIO3D6_UART3RTSN_NAME,0); + break; + } + case RK30_PIN3_PD7: + { + rk30_mux_api_set(GPIO3D7_FLASHDQS_EMMCCLKOUT_NAME,0); + break; + } + case RK30_PIN4_PA0: + { + rk30_mux_api_set(GPIO4A0_FLASHDATA8_NAME,0); + break; + } + case RK30_PIN4_PA1: + { + rk30_mux_api_set(GPIO4A1_FLASHDATA9_NAME,0); + break; + } + case RK30_PIN4_PA2: + { + rk30_mux_api_set(GPIO4A2_FLASHDATA10_NAME,0); + break; + } + + case RK30_PIN4_PA3: + { + rk30_mux_api_set(GPIO4A3_FLASHDATA11_NAME,0); + break; + } + case RK30_PIN4_PA4: + { + rk30_mux_api_set(GPIO4A4_FLASHDATA12_NAME,0); + break; + } + case RK30_PIN4_PA5: + { + rk30_mux_api_set(GPIO4A5_FLASHDATA13_NAME,0); + break; + } + case RK30_PIN4_PA6: + { + rk30_mux_api_set(GPIO4A6_FLASHDATA14_NAME,0); + break; + } + case RK30_PIN4_PA7: + { + rk30_mux_api_set(GPIO4A7_FLASHDATA15_NAME,0); + break; + } + case RK30_PIN4_PB0: + { + rk30_mux_api_set(GPIO4B0_FLASHCSN1_NAME,0); + break; + } + case RK30_PIN4_PB1: + { + rk30_mux_api_set(GPIO4B1_FLASHCSN2_EMMCCMD_NAME,0); + break; + } + case RK30_PIN4_PB2: + { + rk30_mux_api_set(GPIO4B2_FLASHCSN3_EMMCRSTNOUT_NAME,0); + break; + } + case RK30_PIN4_PB3: + { + rk30_mux_api_set(GPIO4B3_FLASHCSN4_NAME,0); + break; + } + case RK30_PIN4_PB4: + { + rk30_mux_api_set(GPIO4B4_FLASHCSN5_NAME,0); + break; + } + case RK30_PIN4_PB5: + { + rk30_mux_api_set(GPIO4B5_FLASHCSN6_NAME,0); + break; + } + case RK30_PIN4_PB6: + { + rk30_mux_api_set(GPIO4B6_FLASHCSN7_NAME ,0); + break; + } + case RK30_PIN4_PB7: + { + rk30_mux_api_set(GPIO4B7_SPI0CSN1_NAME,0); + break; + } + case RK30_PIN4_PC0: + { + rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME,0); + break; + } + case RK30_PIN4_PC1: + { + rk30_mux_api_set(GPIO4C1_SMCDATA1_TRACEDATA1_NAME,0); + break; + } + case RK30_PIN4_PC2: + { + rk30_mux_api_set(GPIO4C2_SMCDATA2_TRACEDATA2_NAME,0); + break; + } + case RK30_PIN4_PC3: + { + rk30_mux_api_set(GPIO4C3_SMCDATA3_TRACEDATA3_NAME,0); + break; + } + case RK30_PIN4_PC4: + { + rk30_mux_api_set(GPIO4C4_SMCDATA4_TRACEDATA4_NAME,0); + break; + } + case RK30_PIN4_PC5: + { + rk30_mux_api_set(GPIO4C5_SMCDATA5_TRACEDATA5_NAME,0); + break; + } + case RK30_PIN4_PC6: + { + rk30_mux_api_set(GPIO4C6_SMCDATA6_TRACEDATA6_NAME,0); + break; + } + + + case RK30_PIN4_PC7: + { + rk30_mux_api_set(GPIO4C7_SMCDATA7_TRACEDATA7_NAME,0); + break; + } + case RK30_PIN4_PD0: + { + rk30_mux_api_set(GPIO4D0_SMCDATA8_TRACEDATA8_NAME,0); + break; + } + case RK30_PIN4_PD1: + { + rk30_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME,0); + break; + } + case RK30_PIN4_PD2: + { + rk30_mux_api_set(GPIO4D2_SMCDATA10_TRACEDATA10_NAME,0); + break; + } + case RK30_PIN4_PD3: + { + rk30_mux_api_set(GPIO4D3_SMCDATA11_TRACEDATA11_NAME,0); + break; + } + case RK30_PIN4_PD4: + { + rk30_mux_api_set(GPIO4D4_SMCDATA12_TRACEDATA12_NAME,0); + break; + } + case RK30_PIN4_PD5: + { + rk30_mux_api_set(GPIO4D5_SMCDATA13_TRACEDATA13_NAME,0); + break; + } + case RK30_PIN4_PD6: + { + rk30_mux_api_set(GPIO4D6_SMCDATA14_TRACEDATA14_NAME,0); + break; + } + case RK30_PIN4_PD7: + { + rk30_mux_api_set(GPIO4D7_SMCDATA15_TRACEDATA15_NAME,0); + break; + } + case RK30_PIN6_PA0: + case RK30_PIN6_PA1: + case RK30_PIN6_PA2: + case RK30_PIN6_PA3: + case RK30_PIN6_PA4: + case RK30_PIN6_PA5: + case RK30_PIN6_PA6: + case RK30_PIN6_PA7: + case RK30_PIN6_PB0: + case RK30_PIN6_PB1: + case RK30_PIN6_PB2: + case RK30_PIN6_PB3: + case RK30_PIN6_PB4: + case RK30_PIN6_PB5: + case RK30_PIN6_PB6: + break; + case RK30_PIN6_PB7: + { + rk30_mux_api_set(GPIO6B7_TESTCLOCKOUT_NAME,0); + break; + } + default: + { + printk("Pin=%d isn't RK GPIO, Please init it's iomux yourself!",pin); + break; + } + } + return 0; +} + +static int sensor_power_default_cb (struct rk29camera_gpio_res *res, int on) +{ + int camera_power = res->gpio_power; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + 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)); + dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + msleep(10); + } else { + gpio_set_value(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + dprintk("%s..%s..PowerPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + printk("%s..%s..PowerPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_power); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + +static int sensor_reset_default_cb (struct rk29camera_gpio_res *res, int on) +{ + int camera_reset = res->gpio_reset; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + 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)); + dprintk("%s..%s..ResetPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + } else { + gpio_set_value(camera_reset,(((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + dprintk("%s..%s..ResetPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_reset, (((~camera_ioflag)&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + printk("%s..%s..ResetPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_reset); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + + return ret; +} + +static int sensor_powerdown_default_cb (struct rk29camera_gpio_res *res, int on) +{ + int camera_powerdown = res->gpio_powerdown; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + 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)); + dprintk("%s..%s..PowerDownPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + } else { + gpio_set_value(camera_powerdown,(((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + dprintk("%s..%s..PowerDownPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_powerdown, (((~camera_ioflag)&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + dprintk("%s..%s..PowerDownPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_powerdown); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + return ret; +} + + +static int sensor_flash_default_cb (struct rk29camera_gpio_res *res, int on) +{ + int camera_flash = res->gpio_flash; + int camera_ioflag = res->gpio_flag; + int camera_io_init = res->gpio_init; + int ret = 0; + + if (camera_flash != INVALID_GPIO) { + if (camera_io_init & RK29_CAM_FLASHACTIVE_MASK) { + switch (on) + { + case Flash_Off: + { + gpio_set_value(camera_flash,(((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("\n%s..%s..FlashPin= %d..PinLevel = %x \n",__FUNCTION__,res->dev_name, camera_flash, (((~camera_ioflag)&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + case Flash_On: + { + gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + case Flash_Torch: + { + gpio_set_value(camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + dprintk("%s..%s..FlashPin=%d ..PinLevel = %x \n",__FUNCTION__,res->dev_name,camera_flash, ((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + break; + } + + default: + { + printk("%s..%s..Flash command(%d) is invalidate \n",__FUNCTION__,res->dev_name,on); + break; + } + } + } else { + ret = RK29_CAM_EIO_REQUESTFAIL; + printk("%s..%s..FlashPin=%d request failed!\n",__FUNCTION__,res->dev_name,camera_flash); + } + } else { + ret = RK29_CAM_EIO_INVALID; + } + return ret; +} + + +static int rk_sensor_io_init(void) +{ + int ret = 0, i,j; + unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; + unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO; + unsigned int camera_ioflag; + static bool is_init = false; + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + if(is_init){ + //printk("sensor io has been initialized \n"); + return 0; + } + else + is_init = true; + if (sensor_ioctl_cb.sensor_power_cb == NULL) + sensor_ioctl_cb.sensor_power_cb = sensor_power_default_cb; + if (sensor_ioctl_cb.sensor_reset_cb == NULL) + sensor_ioctl_cb.sensor_reset_cb = sensor_reset_default_cb; + if (sensor_ioctl_cb.sensor_powerdown_cb == NULL) + sensor_ioctl_cb.sensor_powerdown_cb = sensor_powerdown_default_cb; + if (sensor_ioctl_cb.sensor_flash_cb == NULL) + sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb; + for(i = 0;i < RK_CAM_NUM; i++){ + camera_reset = plat_data->gpio_res[i].gpio_reset; + camera_power = plat_data->gpio_res[i].gpio_power; + camera_powerdown = plat_data->gpio_res[i].gpio_powerdown; + camera_flash = plat_data->gpio_res[i].gpio_flash; + camera_ioflag = plat_data->gpio_res[i].gpio_flag; + plat_data->gpio_res[i].gpio_init = 0; + + if (camera_power != INVALID_GPIO) { + ret = gpio_request(camera_power, "camera power"); + if (ret) { + if (i == 0) { + printk("%s..%s..power pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power); + goto sensor_io_init_erro; + } else { + if (camera_power != plat_data->gpio_res[i].gpio_power) { + printk("%s..%s..power pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power); + goto sensor_io_init_erro; + } + } + } + + if (rk_sensor_iomux(camera_power) < 0) { + printk(KERN_ERR "%s..%s..power pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_power); + goto sensor_io_init_erro; + } + + plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERACTIVE_MASK; + gpio_set_value(camera_reset, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + gpio_direction_output(camera_power, (((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + + dprintk("%s....power pin(%d) init success(0x%x) \n",__FUNCTION__,camera_power,(((~camera_ioflag)&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS)); + + } + + if (camera_reset != INVALID_GPIO) { + ret = gpio_request(camera_reset, "camera reset"); + if (ret) { + printk("%s..%s..reset pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_reset); + goto sensor_io_init_erro; + } + + if (rk_sensor_iomux(camera_reset) < 0) { + printk(KERN_ERR "%s..%s..reset pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_reset); + goto sensor_io_init_erro; + } + + plat_data->gpio_res[i].gpio_init |= RK29_CAM_RESETACTIVE_MASK; + gpio_set_value(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + gpio_direction_output(camera_reset, ((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + + dprintk("%s....reset pin(%d) init success(0x%x)\n",__FUNCTION__,camera_reset,((camera_ioflag&RK29_CAM_RESETACTIVE_MASK)>>RK29_CAM_RESETACTIVE_BITPOS)); + + } + + if (camera_powerdown != INVALID_GPIO) { + ret = gpio_request(camera_powerdown, "camera powerdown"); + if (ret) { + printk("%s..%s..powerdown pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_powerdown); + goto sensor_io_init_erro; + } + + if (rk_sensor_iomux(camera_powerdown) < 0) { + printk(KERN_ERR "%s..%s..powerdown pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_powerdown); + goto sensor_io_init_erro; + } + + plat_data->gpio_res[i].gpio_init |= RK29_CAM_POWERDNACTIVE_MASK; + gpio_set_value(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + gpio_direction_output(camera_powerdown, ((camera_ioflag&RK29_CAM_POWERDNACTIVE_MASK)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + + dprintk("%s....powerdown pin(%d) init success(0x%x) \n",__FUNCTION__,camera_powerdown,((camera_ioflag&RK29_CAM_POWERDNACTIVE_BITPOS)>>RK29_CAM_POWERDNACTIVE_BITPOS)); + + } + + if (camera_flash != INVALID_GPIO) { + ret = gpio_request(camera_flash, "camera flash"); + if (ret) { + printk("%s..%s..flash pin(%d) init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_flash); + goto sensor_io_init_erro; + } + + if (rk_sensor_iomux(camera_flash) < 0) { + printk(KERN_ERR "%s..%s..flash pin(%d) iomux init failed\n",__FUNCTION__,plat_data->gpio_res[i].dev_name,camera_flash); + } + + plat_data->gpio_res[i].gpio_init |= RK29_CAM_FLASHACTIVE_MASK; + gpio_set_value(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); /* falsh off */ + gpio_direction_output(camera_flash, ((~camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + + dprintk("%s....flash pin(%d) init success(0x%x) \n",__FUNCTION__,camera_flash,((camera_ioflag&RK29_CAM_FLASHACTIVE_MASK)>>RK29_CAM_FLASHACTIVE_BITPOS)); + + } + + + for (j=0; j<10; j++) { + memset(&plat_data->info[i].fival[j],0x00,sizeof(struct v4l2_frmivalenum)); + } + j=0; + if (plat_data->info[i].dev_name && strstr(plat_data->info[i].dev_name,"_back")) { + + #if CONFIG_SENSOR_QCIF_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QCIF_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 176; + plat_data->info[i].fival[j].height = 144; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_QVGA_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QVGA_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 320; + plat_data->info[i].fival[j].height = 240; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_CIF_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_CIF_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 352; + plat_data->info[i].fival[j].height = 288; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_VGA_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_VGA_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 640; + plat_data->info[i].fival[j].height = 480; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_480P_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_480P_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 720; + plat_data->info[i].fival[j].height = 480; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_SVGA_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_SVGA_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 800; + plat_data->info[i].fival[j].height = 600; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_720P_FPS_FIXED_0 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_720P_FPS_FIXED_0; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 1280; + plat_data->info[i].fival[j].height = 720; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + } else { + #if CONFIG_SENSOR_QCIF_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QCIF_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 176; + plat_data->info[i].fival[j].height = 144; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_QVGA_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QVGA_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 320; + plat_data->info[i].fival[j].height = 240; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_CIF_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_CIF_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 352; + plat_data->info[i].fival[j].height = 288; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_VGA_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_VGA_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 640; + plat_data->info[i].fival[j].height = 480; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_480P_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_480P_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 720; + plat_data->info[i].fival[j].height = 480; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_SVGA_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_SVGA_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 800; + plat_data->info[i].fival[j].height = 600; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + + #if CONFIG_SENSOR_720P_FPS_FIXED_1 + plat_data->info[i].fival[j].discrete.denominator = CONFIG_SENSOR_720P_FPS_FIXED_1; + plat_data->info[i].fival[j].discrete.numerator= 1; + plat_data->info[i].fival[j].index = 0; + plat_data->info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12; + plat_data->info[i].fival[j].width = 1280; + plat_data->info[i].fival[j].height = 720; + plat_data->info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE; + j++; + #endif + } + continue; + sensor_io_init_erro: + rk_sensor_io_deinit(i); + } + return 0; +} + +static int rk_sensor_io_deinit(int sensor) +{ + unsigned int camera_reset = INVALID_GPIO, camera_power = INVALID_GPIO; + unsigned int camera_powerdown = INVALID_GPIO, camera_flash = INVALID_GPIO; + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + camera_reset = plat_data->gpio_res[sensor].gpio_reset; + camera_power = plat_data->gpio_res[sensor].gpio_power; + camera_powerdown = plat_data->gpio_res[sensor].gpio_powerdown; + camera_flash = plat_data->gpio_res[sensor].gpio_flash; + + printk("%s..%s enter..\n",__FUNCTION__,plat_data->gpio_res[sensor].dev_name); + + if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERACTIVE_MASK) { + if (camera_power != INVALID_GPIO) { + gpio_direction_input(camera_power); + gpio_free(camera_power); + } + } + + if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_RESETACTIVE_MASK) { + if (camera_reset != INVALID_GPIO) { + gpio_direction_input(camera_reset); + gpio_free(camera_reset); + } + } + + if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_POWERDNACTIVE_MASK) { + if (camera_powerdown != INVALID_GPIO) { + gpio_direction_input(camera_powerdown); + gpio_free(camera_powerdown); + } + } + + if (plat_data->gpio_res[sensor].gpio_init & RK29_CAM_FLASHACTIVE_MASK) { + if (camera_flash != INVALID_GPIO) { + gpio_direction_input(camera_flash); + gpio_free(camera_flash); + } + } + plat_data->gpio_res[sensor].gpio_init = 0; + + return 0; +} +static int rk_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on) +{ + struct rk29camera_gpio_res *res = NULL; + int ret = RK29_CAM_IO_SUCCESS,i = 0; + + struct rk29camera_platform_data* plat_data = &rk_camera_platform_data; + //for test reg + for(i = 0;i < RK_CAM_NUM;i++){ + if(plat_data->gpio_res[i].dev_name && (strcmp(plat_data->gpio_res[i].dev_name, dev_name(dev)) == 0)) { + res = (struct rk29camera_gpio_res *)&plat_data->gpio_res[i]; + break; + } + } + if(i == RK_CAM_NUM){ + ret = RK29_CAM_EIO_INVALID; + goto rk_sensor_ioctrl_end; + } + + switch (cmd) + { + case Cam_Power: + { + if (sensor_ioctl_cb.sensor_power_cb) { + ret = sensor_ioctl_cb.sensor_power_cb(res, on); + } else { + printk(KERN_ERR "sensor_ioctl_cb.sensor_power_cb is NULL"); + WARN_ON(1); + } + break; + } + case Cam_Reset: + { + if (sensor_ioctl_cb.sensor_reset_cb) { + ret = sensor_ioctl_cb.sensor_reset_cb(res, on); + } else { + printk(KERN_ERR "sensor_ioctl_cb.sensor_reset_cb is NULL"); + WARN_ON(1); + } + break; + } + + case Cam_PowerDown: + { + if (sensor_ioctl_cb.sensor_powerdown_cb) { + ret = sensor_ioctl_cb.sensor_powerdown_cb(res, on); + } else { + printk(KERN_ERR "sensor_ioctl_cb.sensor_powerdown_cb is NULL"); + WARN_ON(1); + } + break; + } + + case Cam_Flash: + { + if (sensor_ioctl_cb.sensor_flash_cb) { + ret = sensor_ioctl_cb.sensor_flash_cb(res, on); + } else { + printk(KERN_ERR "sensor_ioctl_cb.sensor_flash_cb is NULL!"); + WARN_ON(1); + } + break; + } + default: + { + printk("%s cmd(0x%x) is unknown!\n",__FUNCTION__, cmd); + break; + } + } +rk_sensor_ioctrl_end: + return ret; +} +static int rk_sensor_power(struct device *dev, int on) +{ + rk_sensor_ioctrl(dev,Cam_Power,on); + return 0; +} +#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO) +static int rk_sensor_reset(struct device *dev) +{ + rk_sensor_ioctrl(dev,Cam_Reset,1); + msleep(2); + rk_sensor_ioctrl(dev,Cam_Reset,0); + return 0; +} +#endif +static int rk_sensor_powerdown(struct device *dev, int on) +{ + return rk_sensor_ioctrl(dev,Cam_PowerDown,on); +} + +static struct android_pmem_platform_data android_pmem_cam_pdata = { + .name = "pmem_cam", + //.start = PMEM_CAM_BASE, + .size = 0, + .no_allocator = 1, + .cached = 1, +}; + + struct platform_device android_pmem_cam_device = { + .name = "android_pmem", + .id = 1, + .dev = { + .platform_data = &android_pmem_cam_pdata, + }, +}; + +static void rk_register_camera_devices(void) +{ + rk_init_camera_plateform_data(); +#if CONFIG_USE_CIF_0 + platform_device_register(&rk_device_camera_host_0); +#endif +#if CONFIG_USE_CIF_1 + platform_device_register(&rk_device_camera_host_1); +#endif + if(rk_soc_camera_pdrv_0.name) + platform_device_register(&rk_soc_camera_pdrv_0); + if(rk_soc_camera_pdrv_1.name) + platform_device_register(&rk_soc_camera_pdrv_1); + if(((struct android_pmem_platform_data*)(android_pmem_cam_device.dev.platform_data))->size) + platform_device_register(&android_pmem_cam_device); +} +module_init(rk_register_camera_devices); +#endif + +#endif //#ifdef CONFIG_VIDEO_RK diff --git a/drivers/media/video/rk30_camera_oneframe.c b/drivers/media/video/rk30_camera_oneframe.c new file mode 100755 index 000000000000..ee071f553f17 --- /dev/null +++ b/drivers/media/video/rk30_camera_oneframe.c @@ -0,0 +1,2337 @@ +/* + * V4L2 Driver for RK28 camera host + * + * Copyright (C) 2006, Sascha Hauer, Pengutronix + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#if CONFIG_ARCH_RK30 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0) + +#define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) +#define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) + +// CIF Reg Offset +#define CIF_CIF_CTRL 0x00 +#define CIF_CIF_INTEN 0x04 +#define CIF_CIF_INTSTAT 0x08 +#define CIF_CIF_FOR 0x0c +#define CIF_CIF_LINE_NUM_ADDR 0x10 +#define CIF_CIF_FRM0_ADDR_Y 0x14 +#define CIF_CIF_FRM0_ADDR_UV 0x18 +#define CIF_CIF_FRM1_ADDR_Y 0x1c +#define CIF_CIF_FRM1_ADDR_UV 0x20 +#define CIF_CIF_VIR_LINE_WIDTH 0x24 +#define CIF_CIF_SET_SIZE 0x28 +#define CIF_CIF_SCM_ADDR_Y 0x2c +#define CIF_CIF_SCM_ADDR_U 0x30 +#define CIF_CIF_SCM_ADDR_V 0x34 +#define CIF_CIF_WB_UP_FILTER 0x38 +#define CIF_CIF_WB_LOW_FILTER 0x3c +#define CIF_CIF_WBC_CNT 0x40 +#define CIF_CIF_CROP 0x44 +#define CIF_CIF_SCL_CTRL 0x48 +#define CIF_CIF_SCL_DST 0x4c +#define CIF_CIF_SCL_FCT 0x50 +#define CIF_CIF_SCL_VALID_NUM 0x54 +#define CIF_CIF_LINE_LOOP_CTR 0x58 +#define CIF_CIF_FRAME_STATUS 0x60 +#define CIF_CIF_CUR_DST 0x64 +#define CIF_CIF_LAST_LINE 0x68 +#define CIF_CIF_LAST_PIX 0x6c + +//The key register bit descrition +// CIF_CTRL Reg , ignore SCM,WBC,ISP, +#define DISABLE_CAPTURE (0x00<<0) +#define ENABLE_CAPTURE (0x01<<0) +#define MODE_ONEFRAME (0x00<<1) +#define MODE_PINGPONG (0x01<<1) +#define MODE_LINELOOP (0x02<<1) +#define AXI_BURST_16 (0x0F << 12) + +//CIF_CIF_INTEN +#define FRAME_END_EN (0x01<<1) +#define BUS_ERR_EN (0x01<<6) +#define SCL_ERR_EN (0x01<<7) + +//CIF_CIF_FOR +#define VSY_HIGH_ACTIVE (0x01<<0) +#define VSY_LOW_ACTIVE (0x00<<0) +#define HSY_LOW_ACTIVE (0x01<<1) +#define HSY_HIGH_ACTIVE (0x00<<1) +#define INPUT_MODE_YUV (0x00<<2) +#define INPUT_MODE_PAL (0x02<<2) +#define INPUT_MODE_NTSC (0x03<<2) +#define INPUT_MODE_RAW (0x04<<2) +#define INPUT_MODE_JPEG (0x05<<2) +#define INPUT_MODE_MIPI (0x06<<2) +#define YUV_INPUT_ORDER_UYVY (0x00<<5) +#define YUV_INPUT_ORDER_YVYU (0x01<<5) +#define YUV_INPUT_ORDER_VYUY (0x02<<5) +#define YUV_INPUT_ORDER_YUYV (0x03<<5) +#define YUV_INPUT_422 (0x00<<7) +#define YUV_INPUT_420 (0x01<<7) +#define INPUT_420_ORDER_EVEN (0x00<<8) +#define INPUT_420_ORDER_ODD (0x01<<8) +#define CCIR_INPUT_ORDER_ODD (0x00<<9) +#define CCIR_INPUT_ORDER_EVEN (0x01<<9) +#define RAW_DATA_WIDTH_8 (0x00<<11) +#define RAW_DATA_WIDTH_10 (0x01<<11) +#define RAW_DATA_WIDTH_12 (0x02<<11) +#define YUV_OUTPUT_422 (0x00<<16) +#define YUV_OUTPUT_420 (0x01<<16) +#define OUTPUT_420_ORDER_EVEN (0x00<<17) +#define OUTPUT_420_ORDER_ODD (0x01<<17) +#define RAWD_DATA_LITTLE_ENDIAN (0x00<<18) +#define RAWD_DATA_BIG_ENDIAN (0x01<<18) +#define UV_STORAGE_ORDER_UVUV (0x00<<19) +#define UV_STORAGE_ORDER_VUVU (0x01<<19) + +//CIF_CIF_SCL_CTRL +#define ENABLE_SCL_DOWN (0x01<<0) +#define DISABLE_SCL_DOWN (0x00<<0) +#define ENABLE_SCL_UP (0x01<<1) +#define DISABLE_SCL_UP (0x00<<1) +#define ENABLE_YUV_16BIT_BYPASS (0x01<<4) +#define DISABLE_YUV_16BIT_BYPASS (0x00<<4) +#define ENABLE_RAW_16BIT_BYPASS (0x01<<5) +#define DISABLE_RAW_16BIT_BYPASS (0x00<<5) +#define ENABLE_32BIT_BYPASS (0x01<<6) +#define DISABLE_32BIT_BYPASS (0x00<<6) + +//CRU,PIXCLOCK +#define CRU_PCLK_REG30 0xbc +#define ENANABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x1<<8)) +#define DISABLE_INVERT_PCLK_CIF0 ((0x1<<24)|(0x0<<8)) +#define ENANABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x1<<12)) +#define DISABLE_INVERT_PCLK_CIF1 ((0x1<<28)|(0x0<<12)) + +#define MIN(x,y) ((xy) ? x: y) +#define RK_SENSOR_24MHZ 24 /* MHz */ +#define RK_SENSOR_48MHZ 48 + +#define write_cif_reg(base,addr, val) __raw_writel(val, addr+(base)) +#define read_cif_reg(base,addr) __raw_readl(addr+(base)) +#define mask_cif_reg(addr, msk, val) write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr))) + +#define write_cru_reg(addr, val) __raw_writel(val, addr+RK30_CRU_BASE) +#define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE) +#define mask_cru_reg(addr, msk, val) write_cif_reg(addr+RK30_CRU_BASE, (val)|((~(msk))&read_cif_reg(addr+RK30_CRU_BASE))) + +#ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF +#define CAM_WORKQUEUE_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\ + || (pcdev->icd_cb.sensor_cb)) +#define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) +#else +#define CAM_WORKQUEUE_IS_EN() (true) +#define CAM_IPPWORK_IS_EN() ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height)) +#endif + +#define IS_CIF0() (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0) +//Configure Macro +/* +* Driver Version Note +* +*v0.0.x : this driver is 2.6.32 kernel driver; +*v0.1.x : this driver is 3.0.8 kernel driver; +* +*v0.x.1 : this driver first support rk2918; +*v0.x.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420 +* and V4L2_PIX_FMT_YUV422P; +*v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS; +*v0.x.4 : this driver support digital zoom; +*v0.x.5 : this driver support test framerate and query framerate from board file configuration; +*v0.x.6 : this driver improve test framerate method; +*/ +#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 2, 6) + +/* limit to rk29 hardware capabilities */ +#define RK_CAM_BUS_PARAM (SOCAM_MASTER |\ + SOCAM_HSYNC_ACTIVE_HIGH |\ + SOCAM_HSYNC_ACTIVE_LOW |\ + SOCAM_VSYNC_ACTIVE_HIGH |\ + SOCAM_VSYNC_ACTIVE_LOW |\ + SOCAM_PCLK_SAMPLE_RISING |\ + SOCAM_PCLK_SAMPLE_FALLING|\ + SOCAM_DATA_ACTIVE_HIGH |\ + SOCAM_DATA_ACTIVE_LOW|\ + SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\ + SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ) + +#define RK_CAM_W_MIN 48 +#define RK_CAM_H_MIN 32 +#define RK_CAM_W_MAX 3856 /* ddl@rock-chips.com : 10M Pixel */ +#define RK_CAM_H_MAX 2764 +#define RK_CAM_FRAME_INVAL_INIT 3 +#define RK_CAM_FRAME_INVAL_DC 3 /* ddl@rock-chips.com : */ + +extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf); +extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); + +/* buffer for one video frame */ +struct rk_camera_buffer +{ + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + enum v4l2_mbus_pixelcode code; + int inwork; +}; +enum rk_camera_reg_state +{ + Reg_Invalidate, + Reg_Validate +}; + +struct rk_camera_reg +{ + unsigned int cifCtrl; + unsigned int cifCrop; + unsigned int cifFs; + unsigned int cifIntEn; + unsigned int cifFmt; +// unsigned int VipCrm; + enum rk_camera_reg_state Inval; +}; +struct rk_camera_work +{ + struct videobuf_buffer *vb; + struct rk_camera_dev *pcdev; + struct work_struct work; +}; +struct rk_camera_frmivalenum +{ + struct v4l2_frmivalenum fival; + struct rk_camera_frmivalenum *nxt; +}; +struct rk_camera_frmivalinfo +{ + struct soc_camera_device *icd; + struct rk_camera_frmivalenum *fival_list; +}; +struct rk_camera_zoominfo +{ + struct semaphore sem; + struct v4l2_crop a; + int zoom_rate; +}; +struct rk_camera_timer{ + struct rk_camera_dev *pcdev; + struct hrtimer timer; + }; +struct rk_camera_dev +{ + struct soc_camera_host soc_host; + struct device *dev; + /* RK2827x is only supposed to handle one camera on its Quick Capture + * interface. If anyone ever builds hardware to enable more than + * one camera, they will have to modify this driver too */ + struct soc_camera_device *icd; + + //************must modify start************/ + struct clk *aclk_ddr_lcdc; + struct clk *aclk_disp_matrix; + + struct clk *hclk_cpu_display; + struct clk *vip_slave; + + struct clk *vip_out; + struct clk *vip_input; + struct clk *vip_bus; + + struct clk *hclk_disp_matrix; + struct clk *vip_matrix; + + struct clk *pd_display; + //************must modify end************/ + void __iomem *base; + int frame_inval; /* ddl@rock-chips.com : The first frames is invalidate */ + unsigned int irq; + unsigned int fps; + unsigned int pixfmt; + //for ipp + unsigned int vipmem_phybase; + unsigned int vipmem_size; + unsigned int vipmem_bsize; + + int host_width; //croped size + int host_height; + int host_left; //sensor output size ? + int host_top; + int hostid; + + struct rk29camera_platform_data *pdata; + struct resource *res; + struct list_head capture; + struct rk_camera_zoominfo zoominfo; + + spinlock_t lock; + + struct videobuf_buffer *active; + struct rk_camera_reg reginfo_suspend; + struct workqueue_struct *camera_wq; + struct rk_camera_work *camera_work; + unsigned int camera_work_count; + struct rk_camera_timer fps_timer; + struct rk_camera_work camera_reinit_work; + int icd_init; + rk29_camera_sensor_cb_s icd_cb; + struct rk_camera_frmivalinfo icd_frmival[2]; +}; + +static const struct v4l2_queryctrl rk_camera_controls[] = +{ + #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON + { + .id = V4L2_CID_ZOOM_ABSOLUTE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "DigitalZoom Control", + .minimum = 100, + .maximum = 300, + .step = 5, + .default_value = 100, + }, + #endif +}; + +static DEFINE_MUTEX(camera_lock); +static const char *rk_cam_driver_description = "RK_Camera"; + +static int rk_camera_s_stream(struct soc_camera_device *icd, int enable); + + +/* + * Videobuf operations + */ +static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + int bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width, + icd->current_fmt->host_fmt); + + dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); + + if (bytes_per_line_host < 0) + return bytes_per_line_host; + + /* planar capture requires Y, U and V buffers to be page aligned */ + //*size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/ + *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/ + pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height); + + + if (CAM_WORKQUEUE_IS_EN()) { + #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF + if (CAM_IPPWORK_IS_EN()) + #endif + { + BUG_ON(pcdev->vipmem_sizevipmem_bsize); + if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) { /* Buffers must be limited, when this resolution is genered by IPP */ + *count = pcdev->vipmem_size/pcdev->vipmem_bsize; + } + } + if ((pcdev->camera_work_count != *count) && pcdev->camera_work) { + kfree(pcdev->camera_work); + pcdev->camera_work = NULL; + pcdev->camera_work_count = 0; + } + + if (pcdev->camera_work == NULL) { + pcdev->camera_work = kmalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL); + if (pcdev->camera_work == NULL) { + RKCAMERA_TR("\n %s kmalloc fail\n", __FUNCTION__); + BUG(); + } + pcdev->camera_work_count = *count; + } + } + + RKCAMERA_DG("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count); + + return 0; +} +static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer *buf) +{ + struct soc_camera_device *icd = vq->priv_data; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, + &buf->vb, buf->vb.baddr, buf->vb.bsize); + + /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/ + if (buf->vb.state == VIDEOBUF_NEEDS_INIT) + return; + + if (in_interrupt()) + BUG(); + /* + * This waits until this buffer is out of danger, i.e., until it is no + * longer in STATE_QUEUED or STATE_ACTIVE + */ + //videobuf_waiton(vq, &buf->vb, 0, 0); + videobuf_dma_contig_free(vq, &buf->vb); + dev_dbg(&icd->dev, "%s freed\n", __func__); + buf->vb.state = VIDEOBUF_NEEDS_INIT; + return; +} +static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) +{ + struct soc_camera_device *icd = vq->priv_data; + struct rk_camera_buffer *buf; + int ret; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + if (bytes_per_line < 0) + return bytes_per_line; + + buf = container_of(vb, struct rk_camera_buffer, vb); + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, + vb, vb->baddr, vb->bsize); + + //RK29CAMERA_TR("\n%s..%d.. \n",__FUNCTION__,__LINE__); + + /* Added list head initialization on alloc */ + WARN_ON(!list_empty(&vb->queue)); + + /* This can be useful if you want to see if we actually fill + * the buffer with something */ + //memset((void *)vb->baddr, 0xaa, vb->bsize); + + BUG_ON(NULL == icd->current_fmt); + + if (buf->code != icd->current_fmt->code || + vb->width != icd->user_width || + vb->height != icd->user_height || + vb->field != field) { + buf->code = icd->current_fmt->code; + vb->width = icd->user_width; + vb->height = icd->user_height; + vb->field = field; + vb->state = VIDEOBUF_NEEDS_INIT; + } + + vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */ + if (0 != vb->baddr && vb->bsize < vb->size) { + ret = -EINVAL; + goto out; + } + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + ret = videobuf_iolock(vq, vb, NULL); + if (ret) { + goto fail; + } + vb->state = VIDEOBUF_PREPARED; + } + //RK29CAMERA_TR("\n%s..%d.. \n",__FUNCTION__,__LINE__); + return 0; +fail: + rk_videobuf_free(vq, buf); +out: + return ret; +} + +static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev) +{ + unsigned int y_addr,uv_addr; + struct rk_camera_dev *pcdev = rk_pcdev; + + if (vb) { + if (CAM_WORKQUEUE_IS_EN()) { + y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; + uv_addr = y_addr + pcdev->host_width*pcdev->host_height; + if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) { + RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height, + pcdev->icd->user_width,pcdev->icd->user_height, vb->i); + BUG(); + } + } else { + y_addr = vb->boff; + uv_addr = y_addr + vb->width * vb->height; + } + write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr); + write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr); + //printk("y_addr = 0x%x, uv_addr = 0x%x \n",read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y),read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV)); + write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr); + write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr); + write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000002);//frame1 has been ready to receive data,frame 2 is not used + } +} +/* Locking: Caller holds q->irqlock */ +static void rk_videobuf_queue(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, + vb, vb->baddr, vb->bsize); + + vb->state = VIDEOBUF_QUEUED; + + if (list_empty(&pcdev->capture)) { + list_add_tail(&vb->queue, &pcdev->capture); + } else { + if (list_entry(pcdev->capture.next, struct videobuf_buffer, queue) != vb) + list_add_tail(&vb->queue, &pcdev->capture); + else + BUG(); /* ddl@rock-chips.com : The same videobuffer queue again */ + } + if (!pcdev->active) { + pcdev->active = vb; + rk_videobuf_capture(vb,pcdev); + } +} +static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt) +{ + switch (pixfmt) + { + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + { + *ippfmt = IPP_Y_CBCR_H2V1; + break; + } + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + { + *ippfmt = IPP_Y_CBCR_H2V2; + break; + } + default: + goto rk_pixfmt2ippfmt_err; + } + + return 0; +rk_pixfmt2ippfmt_err: + return -1; +} +static void rk_camera_capture_process(struct work_struct *work) +{ + struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work); + struct videobuf_buffer *vb = camera_work->vb; + struct rk_camera_dev *pcdev = camera_work->pcdev; + struct rk29_ipp_req ipp_req; + unsigned long int flags; + int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size; + int scale_times,w,h,vipdata_base; + + /* + *ddl@rock-chips.com: + * IPP Dest image resolution is 2047x1088, so scale operation break up some times + */ + if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) { + scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430)); + scale_times++; + } else { + scale_times = 1; + } + + memset(&ipp_req, 0, sizeof(struct rk29_ipp_req)); + + down(&pcdev->zoominfo.sem); + + ipp_req.timeout = 100; + ipp_req.flag = IPP_ROT_0; + ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times; + ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times; + ipp_req.src_vir_w = pcdev->zoominfo.a.c.width; + rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt); + ipp_req.dst0.w = pcdev->icd->user_width/scale_times; + ipp_req.dst0.h = pcdev->icd->user_height/scale_times; + ipp_req.dst_vir_w = pcdev->icd->user_width; + rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt); + vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize; + src_y_size = pcdev->zoominfo.a.c.width*pcdev->zoominfo.a.c.height; + dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height; + for (h=0; hzoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.a.c.width + + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times; + src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.a.c.width/2 + + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times; + + dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times; + dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times; + + ipp_req.src0.YrgbMst = vipdata_base + src_y_offset; + ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset; + ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset; + ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset; + + if (ipp_blit_sync(&ipp_req)) { + spin_lock_irqsave(&pcdev->lock, flags); + vb->state = VIDEOBUF_ERROR; + spin_unlock_irqrestore(&pcdev->lock, flags); + + RKCAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i); + RKCAMERA_TR("widx:%d hidx:%d ",w,h); + RKCAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height); + RKCAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst); + RKCAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h); + RKCAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt); + RKCAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst); + RKCAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h); + RKCAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt); + RKCAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w); + RKCAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag); + + goto do_ipp_err; + } + } + } + + if (pcdev->icd_cb.sensor_cb) + (pcdev->icd_cb.sensor_cb)(vb); + +do_ipp_err: + up(&pcdev->zoominfo.sem); + wake_up(&(camera_work->vb->done)); + return; +} +static irqreturn_t rk_camera_irq(int irq, void *data) +{ + struct rk_camera_dev *pcdev = data; + struct videobuf_buffer *vb; + struct rk_camera_work *wk; + write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); /* clear vip interrupte single */ + /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */ + if (read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS) & 0x01) { + pcdev->fps++; + if (!pcdev->active) + goto RK_CAMERA_IRQ_END; + + if (pcdev->frame_inval>0) { + pcdev->frame_inval--; + rk_videobuf_capture(pcdev->active,pcdev); + goto RK_CAMERA_IRQ_END; + } else if (pcdev->frame_inval) { + RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval); + pcdev->frame_inval = 0; + } + + vb = pcdev->active; + /* ddl@rock-chips.com : this vb may be deleted from queue */ + if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) { + list_del_init(&vb->queue); + } + + pcdev->active = NULL; + if (!list_empty(&pcdev->capture)) { + pcdev->active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue); + if (pcdev->active) { + rk_videobuf_capture(pcdev->active,pcdev); + } + } + + if (pcdev->active == NULL) { + RKCAMERA_DG("%s video_buf queue is empty!\n",__FUNCTION__); + } + + if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) { + vb->state = VIDEOBUF_DONE; + do_gettimeofday(&vb->ts); + vb->field_count++; + } + + if (CAM_WORKQUEUE_IS_EN()) { + wk = pcdev->camera_work + vb->i; + INIT_WORK(&(wk->work), rk_camera_capture_process); + wk->vb = vb; + wk->pcdev = pcdev; + queue_work(pcdev->camera_wq, &(wk->work)); + + } else { + wake_up(&vb->done); + } + + } + +RK_CAMERA_IRQ_END: + return IRQ_HANDLED; +} + + +static void rk_videobuf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb); + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; +#ifdef DEBUG + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + vb, vb->baddr, vb->bsize); + + switch (vb->state) + { + case VIDEOBUF_ACTIVE: + dev_dbg(&icd->dev, "%s (active)\n", __func__); + break; + case VIDEOBUF_QUEUED: + dev_dbg(&icd->dev, "%s (queued)\n", __func__); + break; + case VIDEOBUF_PREPARED: + dev_dbg(&icd->dev, "%s (prepared)\n", __func__); + break; + default: + dev_dbg(&icd->dev, "%s (unknown)\n", __func__); + break; + } +#endif + if (vb == pcdev->active) { + RKCAMERA_DG("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb); + interruptible_sleep_on_timeout(&vb->done, 100); + RKCAMERA_DG("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb); + } + rk_videobuf_free(vq, buf); +} + +static struct videobuf_queue_ops rk_videobuf_ops = +{ + .buf_setup = rk_videobuf_setup, + .buf_prepare = rk_videobuf_prepare, + .buf_queue = rk_videobuf_queue, + .buf_release = rk_videobuf_release, +}; + +static void rk_camera_init_videobuf(struct videobuf_queue *q, + struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + + /* We must pass NULL as dev pointer, then all pci_* dma operations + * transform to normal dma_* ones. */ + videobuf_queue_dma_contig_init(q, + &rk_videobuf_ops, + ici->v4l2_dev.dev, &pcdev->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_NONE, + sizeof(struct rk_camera_buffer), + icd,&icd->video_lock); +} +static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd) +{ + unsigned long sensor_bus_flags = SOCAM_MCLK_24MHZ; + struct clk *parent; + + RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__); + #if 0 + if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix || !pcdev->hclk_cpu_display || + !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display || + IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) || IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) || + IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) { + + RKCAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n"); + goto RK_CAMERA_ACTIVE_ERR; + } + RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__); + if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix || + IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix)) { + + RKCAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n"); + goto RK_CAMERA_ACTIVE_ERR; + } + clk_enable(pcdev->pd_display); + + clk_enable(pcdev->aclk_ddr_lcdc); + clk_enable(pcdev->aclk_disp_matrix); + + clk_enable(pcdev->hclk_cpu_display); + clk_enable(pcdev->vip_slave); + RK29CAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__); + + clk_enable(pcdev->vip_input); + clk_enable(pcdev->vip_bus); + + //if (icd->ops->query_bus_param) /* ddl@rock-chips.com : Query Sensor's xclk */ + //sensor_bus_flags = icd->ops->query_bus_param(icd); + + if (sensor_bus_flags & SOCAM_MCLK_48MHZ) { + parent = clk_get(NULL, "clk48m"); + if (!parent || IS_ERR(parent)) + goto RK_CAMERA_ACTIVE_ERR; + } else if (sensor_bus_flags & SOCAM_MCLK_27MHZ) { + parent = clk_get(NULL, "extclk"); + if (!parent || IS_ERR(parent)) + goto RK_CAMERA_ACTIVE_ERR; + } else { + parent = clk_get(NULL, "xin24m"); + if (!parent || IS_ERR(parent)) + goto RK_CAMERA_ACTIVE_ERR; + } + clk_set_parent(pcdev->vip_out, parent); + + clk_enable(pcdev->vip_out); + // rk30_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_VIP_CLKOUT); + ndelay(10); + + ndelay(10); +// write_vip_reg(pcdev->base,RK29_VIP_RESET, 0x76543210); /* ddl@rock-chips.com : vip software reset */ +// udelay(10); +#endif + write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_ONEFRAME|DISABLE_CAPTURE); /* ddl@rock-chips.com : vip ahb burst 16 */ + write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01); //capture complete interrupt enable + RKCAMERA_TR("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL)); + return 0; +RK_CAMERA_ACTIVE_ERR: + return -ENODEV; +} + +static void rk_camera_deactivate(struct rk_camera_dev *pcdev) +{ + //pcdev->active = NULL; +#if 0 + write_cif_reg(pcdev->base,CIF_CIF_CTRL, 0); + read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); //clear vip interrupte single + +// rk29_mux_api_set(GPIO1B4_VIPCLKOUT_NAME, GPIO1L_GPIO1B4); + clk_disable(pcdev->vip_out); + + clk_disable(pcdev->vip_input); + clk_disable(pcdev->vip_bus); + + + clk_disable(pcdev->hclk_cpu_display); + clk_disable(pcdev->vip_slave); + + clk_disable(pcdev->aclk_ddr_lcdc); + clk_disable(pcdev->aclk_disp_matrix); + + clk_disable(pcdev->pd_display); + #endif + return; +} + +/* The following two functions absolutely depend on the fact, that + * there can be only one camera on RK28 quick capture interface */ +static int rk_camera_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct device *control = to_soc_camera_control(icd); + struct v4l2_subdev *sd; + int ret,i,icd_catch; + struct rk_camera_frmivalenum *fival_list,*fival_nxt; + + mutex_lock(&camera_lock); + + if (pcdev->icd) { + ret = -EBUSY; + goto ebusy; + } + + dev_info(&icd->dev, "RK Camera driver attached to camera%d(%s)\n", + icd->devnum,dev_name(icd->pdev)); + + pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT; + pcdev->active = NULL; + pcdev->icd = NULL; + pcdev->reginfo_suspend.Inval = Reg_Invalidate; + pcdev->zoominfo.zoom_rate = 100; + + /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty, + * if app havn't dequeue all videobuf before close camera device; + */ + INIT_LIST_HEAD(&pcdev->capture); + + ret = rk_camera_activate(pcdev,icd); + if (ret) + goto ebusy; + /* 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); + #if 0 + ret = v4l2_subdev_call(sd,core, init, 0); + if (ret) + goto ebusy; + #endif + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb)); + } + pcdev->icd = icd; + pcdev->icd_init = 0; + + icd_catch = 0; + for (i=0; i<2; i++) { + if (pcdev->icd_frmival[i].icd == icd) + icd_catch = 1; + if (pcdev->icd_frmival[i].icd == NULL) { + pcdev->icd_frmival[i].icd = icd; + icd_catch = 1; + } + } + if (icd_catch == 0) { + fival_list = pcdev->icd_frmival[0].fival_list; + fival_nxt = fival_list; + while(fival_nxt != NULL) { + fival_nxt = fival_list->nxt; + kfree(fival_list); + fival_list = fival_nxt; + } + pcdev->icd_frmival[0].icd = icd; + pcdev->icd_frmival[0].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL); + } + RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__); +ebusy: + mutex_unlock(&camera_lock); + + return ret; +} +static void rk_camera_remove_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + + mutex_lock(&camera_lock); + BUG_ON(icd != pcdev->icd); + + dev_info(&icd->dev, "RK Camera driver detached from camera%d(%s)\n", + icd->devnum,dev_name(icd->pdev)); + + /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but + stream may be turn on again before close device, if suspend and resume happened. */ + if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) { + rk_camera_s_stream(icd,0); + } + + v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL); + rk_camera_deactivate(pcdev); + + if (pcdev->camera_work) { + kfree(pcdev->camera_work); + pcdev->camera_work = NULL; + pcdev->camera_work_count = 0; + } + + pcdev->active = NULL; + pcdev->icd = NULL; + pcdev->icd_cb.sensor_cb = NULL; + pcdev->reginfo_suspend.Inval = Reg_Invalidate; + /* ddl@rock-chips.com: capture list must be reset, because this list may be not empty, + * if app havn't dequeue all videobuf before close camera device; + */ + INIT_LIST_HEAD(&pcdev->capture); + + mutex_unlock(&camera_lock); + RKCAMERA_DG("%s exit\n",__FUNCTION__); + + return; +} +static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) +{ + unsigned long bus_flags, camera_flags, common_flags; + unsigned int cif_ctrl_val = 0; + const struct soc_mbus_pixelfmt *fmt; + int ret = 0; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + RKCAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__); + + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); + if (!fmt) + return -EINVAL; + + bus_flags = RK_CAM_BUS_PARAM; + /* If requested data width is supported by the platform, use it */ + switch (fmt->bits_per_sample) { + case 10: + if (!(bus_flags & SOCAM_DATAWIDTH_10)) + return -EINVAL; + break; + case 9: + if (!(bus_flags & SOCAM_DATAWIDTH_9)) + return -EINVAL; + break; + case 8: + if (!(bus_flags & SOCAM_DATAWIDTH_8)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + if (icd->ops->query_bus_param) + camera_flags = icd->ops->query_bus_param(icd); + else + camera_flags = 0; + + common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); + if (!common_flags) { + ret = -EINVAL; + goto RK_CAMERA_SET_BUS_PARAM_END; + } + + ret = icd->ops->set_bus_param(icd, common_flags); + if (ret < 0) + goto RK_CAMERA_SET_BUS_PARAM_END; + + cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR); + RKCAMERA_DG("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val); + if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) { + if(IS_CIF0()) + { + RKCAMERA_DG("%s..%d.. before set CRU_PCLK_REG30 = 0X%x\n",__FUNCTION__,__LINE__,read_cru_reg(CRU_PCLK_REG30)); + write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0); + RKCAMERA_DG("%s..%d.. after set CRU_PCLK_REG30 = 0X%x\n",__FUNCTION__,__LINE__,read_cru_reg(CRU_PCLK_REG30)); + } + else + { + write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1); + } + } else { + if(IS_CIF0()) + { + RKCAMERA_DG("%s..%d.. before set CRU_PCLK_REG30 = 0X%x\n",__FUNCTION__,__LINE__,read_cru_reg(CRU_PCLK_REG30)); + write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF ) | DISABLE_INVERT_PCLK_CIF0); + RKCAMERA_DG("%s..%d.. after set CRU_PCLK_REG30 = 0X%x\n",__FUNCTION__,__LINE__,read_cru_reg(CRU_PCLK_REG30)); + } + else + { + write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1); + } + } + if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) { + cif_ctrl_val |= HSY_LOW_ACTIVE; + } else { + cif_ctrl_val &= ~HSY_LOW_ACTIVE; + } + if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) { + cif_ctrl_val |= VSY_HIGH_ACTIVE; + } else { + cif_ctrl_val &= ~VSY_HIGH_ACTIVE; + } + + /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */ + //vip_ctrl_val |= ENABLE_CAPTURE; + write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val); + RKCAMERA_DG("%s..ctrl:0x%x CIF_CIF_FOR=%x \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR)); + +RK_CAMERA_SET_BUS_PARAM_END: + if (ret) + RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); + return ret; +} + +static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt) +{ + unsigned long bus_flags, camera_flags; + int ret; + + bus_flags = RK_CAM_BUS_PARAM; + if (icd->ops->query_bus_param) { + camera_flags = icd->ops->query_bus_param(icd); + } else { + camera_flags = 0; + } + ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ; + + if (ret < 0) + dev_warn(icd->dev.parent, + "Flags incompatible: camera %lx, host %lx\n", + camera_flags, bus_flags); + return ret; +} + +static const struct soc_mbus_pixelfmt rk_camera_formats[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .name = "YUV420 NV12", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_1_5X8, + .order = SOC_MBUS_ORDER_LE, + },{ + .fourcc = V4L2_PIX_FMT_NV16, + .name = "YUV422 NV16", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + },{ + .fourcc = V4L2_PIX_FMT_NV21, + .name = "YUV420 NV21", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_1_5X8, + .order = SOC_MBUS_ORDER_LE, + },{ + .fourcc = V4L2_PIX_FMT_NV61, + .name = "YUV422 NV61", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + } +}; + +static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + unsigned int cif_fs = 0,cif_crop = 0; + unsigned int cif_fmt_val = INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN; + switch (host_pixfmt) + { + case V4L2_PIX_FMT_NV16: + cif_fmt_val |= YUV_OUTPUT_422; + cif_fmt_val |= UV_STORAGE_ORDER_UVUV; + pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC; + pcdev->pixfmt = host_pixfmt; + break; + case V4L2_PIX_FMT_NV61: + cif_fmt_val |= YUV_OUTPUT_422; + cif_fmt_val |= UV_STORAGE_ORDER_VUVU; + pcdev->frame_inval = RK_CAM_FRAME_INVAL_DC; + pcdev->pixfmt = host_pixfmt; + break; + case V4L2_PIX_FMT_NV12: + cif_fmt_val |= YUV_OUTPUT_420; + cif_fmt_val |= UV_STORAGE_ORDER_UVUV; + if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT) + pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT; + pcdev->pixfmt = host_pixfmt; + break; + case V4L2_PIX_FMT_NV21: + cif_fmt_val |= YUV_OUTPUT_420; + cif_fmt_val |= UV_STORAGE_ORDER_VUVU; + if (pcdev->frame_inval != RK_CAM_FRAME_INVAL_INIT) + pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT; + pcdev->pixfmt = host_pixfmt; + break; + default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */ + cif_fmt_val |= YUV_OUTPUT_422; + break; + } + switch (icd_code) + { + case V4L2_MBUS_FMT_UYVY8_2X8: + cif_fmt_val |= YUV_INPUT_ORDER_UYVY; + break; + case V4L2_MBUS_FMT_YUYV8_2X8: + cif_fmt_val |= YUV_INPUT_ORDER_YUYV; + break; + case V4L2_MBUS_FMT_YVYU8_2X8: + cif_fmt_val |= YUV_INPUT_ORDER_YVYU; + break; + case V4L2_MBUS_FMT_VYUY8_2X8: + cif_fmt_val |= YUV_INPUT_ORDER_VYUY; + break; + default : + cif_fmt_val |= YUV_INPUT_ORDER_YUYV; + break; + } + write_cif_reg(pcdev->base,CIF_CIF_FOR, read_cif_reg(pcdev->base,CIF_CIF_FOR) |cif_fmt_val); /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */ + + // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT); /* clear vip interrupte single */ + write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); + if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG) + ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) // it is one frame mode + { + BUG(); + } + else{ // this is one frame mode + cif_crop = (rect->left+ (rect->top<<16)); + cif_fs = ((rect->width ) + (rect->height<<16)); + } + RKCAMERA_TR("%s..%d.. \n",__FUNCTION__,__LINE__); + + write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop); + write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs); + write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width); + write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS, 0x00000003); + //MUST bypass scale + write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10); + //pcdev->host_width = rect->width; +// pcdev->host_height = rect->height; + RKCAMERA_DG("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR)); + return; +} + +static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, + struct soc_camera_format_xlate *xlate) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct device *dev = icd->dev.parent; + int formats = 0, ret; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *fmt; + + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + if (ret < 0) + /* No more formats */ + return 0; + + fmt = soc_mbus_get_fmtdesc(code); + if (!fmt) { + dev_err(dev, "Invalid format code #%u: %d\n", idx, code); + return 0; + } + + ret = rk_camera_try_bus_param(icd, fmt->bits_per_sample); + if (ret < 0) + return 0; + + switch (code) { + case V4L2_MBUS_FMT_UYVY8_2X8: + case V4L2_MBUS_FMT_YUYV8_2X8: + case V4L2_MBUS_FMT_YVYU8_2X8: + case V4L2_MBUS_FMT_VYUY8_2X8: + formats++; + if (xlate) { + xlate->host_fmt = &rk_camera_formats[0]; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %s using code %d\n", + rk_camera_formats[0].name,code); + } + + formats++; + if (xlate) { + xlate->host_fmt = &rk_camera_formats[1]; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %s using code %d\n", + rk_camera_formats[1].name,code); + } + + formats++; + if (xlate) { + xlate->host_fmt = &rk_camera_formats[2]; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %s using code %d\n", + rk_camera_formats[2].name,code); + } + + formats++; + if (xlate) { + xlate->host_fmt = &rk_camera_formats[3]; + xlate->code = code; + xlate++; + dev_dbg(dev, "Providing format %s using code %d\n", + rk_camera_formats[3].name,code); + } + break; + default: + break; + } + + return formats; +} + +static void rk_camera_put_formats(struct soc_camera_device *icd) +{ + return; +} + +static int rk_camera_set_crop(struct soc_camera_device *icd, + struct v4l2_crop *a) +{ + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_mbus_framefmt mf; + u32 fourcc = icd->current_fmt->host_fmt->fourcc; + int ret; + + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); + if (ret < 0) + return ret; + + if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) { + + mf.width = a->c.left + a->c.width; + mf.height = a->c.top + a->c.height; + + v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1, + &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0, + fourcc == V4L2_PIX_FMT_NV16 ?4 : 0); + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + if (ret < 0) + return ret; + } + + rk_camera_setup_format(icd, fourcc, mf.code, &a->c); + + icd->user_width = mf.width; + icd->user_height = mf.height; + + return 0; +} + +static int rk_camera_set_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct device *dev = icd->dev.parent; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + const struct soc_camera_format_xlate *xlate = NULL; + struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_mbus_framefmt mf; + struct v4l2_rect rect; + int ret,usr_w,usr_h; + int stream_on = 0; + + usr_w = pix->width; + usr_h = pix->height; + RKCAMERA_TR("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); + if (!xlate) { + dev_err(dev, "Format %x not found\n", pix->pixelformat); + ret = -EINVAL; + goto RK_CAMERA_SET_FMT_END; + } + + /* ddl@rock-chips.com: sensor init code transmit in here after open */ + if (pcdev->icd_init == 0) { + v4l2_subdev_call(sd,core, init, (u32)pcdev->pdata); + pcdev->icd_init = 1; + } + stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL); + if (stream_on & ENABLE_CAPTURE) + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (stream_on & (~ENABLE_CAPTURE))); + + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + + if (mf.code != xlate->code) + return -EINVAL; + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if ((mf.width != usr_w) || (mf.height != usr_h)) { + int ratio; + if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) { + RKCAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height); + ret = -EINVAL; + goto RK_CAMERA_SET_FMT_END; + } + if (unlikely((usr_w <16)||(usr_h < 16))) { + RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h); + ret = -EINVAL; + goto RK_CAMERA_SET_FMT_END; + } + //need crop ? + if(1/*(mf.width/mf.height) != (usr_w/usr_h)*/){ + ratio = ((mf.width/usr_w) >= (mf.height/usr_h))?(mf.height/usr_h):(mf.width/usr_w); + pcdev->host_width = ratio*usr_w; + pcdev->host_height = ratio*usr_h; + printk("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height); + } + else{ // needn't crop ,just scaled by ipp + pcdev->host_width = usr_w; + pcdev->host_height = usr_h; + } + } + else{ + pcdev->host_width = usr_w; + pcdev->host_height = usr_h; + } + #else + //according to crop and scale capability to change , here just cropt to user needed + pcdev->host_width = usr_w; + pcdev->host_height = usr_h; + #endif + icd->sense = NULL; + if (!ret) { + rect.left = ((mf.width - pcdev->host_width )>>1)&(~0x01); + rect.top = ((mf.height - pcdev->host_height )>>1)&(~0x01); + pcdev->host_left = rect.left; + pcdev->host_top = rect.top; + // rect.left = 0; + // rect.top = 0; + rect.width = pcdev->host_width; + rect.height = pcdev->host_height; + RKCAMERA_DG("%s..%d.. host:%d*%d , sensor output:%d*%d,user demand:%d*%d\n",__FUNCTION__,__LINE__, + pcdev->host_width,pcdev->host_height,mf.width,mf.height,usr_w,usr_h); + down(&pcdev->zoominfo.sem); + pcdev->zoominfo.a.c.width = rect.width*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.width &= ~0x03; + pcdev->zoominfo.a.c.height = rect.height*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.height &= ~0x03; + //pcdev->zoominfo.a.c.left = ((rect.width - pcdev->zoominfo.a.c.width)>>1)&(~0x01); + //pcdev->zoominfo.a.c.top = ((rect.height - pcdev->zoominfo.a.c.height)>>1)&(~0x01); + pcdev->zoominfo.a.c.left = 0; + pcdev->zoominfo.a.c.top = 0; + up(&pcdev->zoominfo.sem); + + /* ddl@rock-chips.com: IPP work limit check */ + if ((pcdev->zoominfo.a.c.width != usr_w) || (pcdev->zoominfo.a.c.height != usr_h)) { + if (usr_w > 0x7f0) { + if (((usr_w>>1)&0x3f) && (((usr_w>>1)&0x3f) <= 8)) { + RKCAMERA_TR("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f)); + ret = -EINVAL; + goto RK_CAMERA_SET_FMT_END; + } + } else { + if ((usr_w&0x3f) && ((usr_w&0x3f) <= 8)) { + RKCAMERA_TR("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f)); + ret = -EINVAL; + goto RK_CAMERA_SET_FMT_END; + } + } + } + RKCAMERA_DG("%s..%s icd width:%d host width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name, + rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top, + pix->width, pix->height); + rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); + + if (CAM_IPPWORK_IS_EN()) { + BUG_ON(pcdev->vipmem_phybase == 0); + } + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + icd->current_fmt = xlate; + } + +RK_CAMERA_SET_FMT_END: + if (stream_on & ENABLE_CAPTURE) + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE)); + if (ret) + RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); + return ret; +} +static bool rk_camera_fmt_capturechk(struct v4l2_format *f) +{ + bool ret = false; + + if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + ret = true; + } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + ret = true; + } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + ret = true; + } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + ret = true; + } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + ret = true; + } + + if (ret == true) + RKCAMERA_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + return ret; +} +static int rk_camera_try_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + const struct soc_camera_format_xlate *xlate; + struct v4l2_pix_format *pix = &f->fmt.pix; + __u32 pixfmt = pix->pixelformat; + int ret,usr_w,usr_h,i; + bool is_capture = rk_camera_fmt_capturechk(f); + bool vipmem_is_overflow = false; + struct v4l2_mbus_framefmt mf; + + usr_w = pix->width; + usr_h = pix->height; + RKCAMERA_DG("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); + + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF, + (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF); + ret = -EINVAL; + RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16, + (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff)); + for (i = 0; i < icd->num_user_formats; i++) + RKCAMERA_TR("(%c%c%c%c)-%s\n", + icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF, + (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF, + icd->user_formats[i].host_fmt->name); + goto RK_CAMERA_TRY_FMT_END; + } + /* limit to rk29 hardware capabilities */ + v4l_bound_align_image(&pix->width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1, + &pix->height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0, + pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0); + + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, + xlate->host_fmt); + if (pix->bytesperline < 0) + return pix->bytesperline; + + /* limit to sensor capabilities */ + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + if (ret < 0) + goto RK_CAMERA_TRY_FMT_END; + RKCAMERA_DG("%s mf.width:%d mf.height:%d\n",__FUNCTION__,mf.width,mf.height); + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if ((mf.width > usr_w) && (mf.height > usr_h)) { + if (is_capture) { + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size); + } else { + /* Assume preview buffer minimum is 4 */ + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size); + } + if (vipmem_is_overflow == false) { + pix->width = usr_w; + pix->height = usr_h; + } else { + RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h); + pix->width = mf.width; + pix->height = mf.height; + } + } else if ((mf.width < usr_w) && (mf.height < usr_h)) { + if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) { + if (is_capture) { + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size); + } else { + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size); + } + if (vipmem_is_overflow == false) { + pix->width = usr_w; + pix->height = usr_h; + } else { + RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h); + pix->width = mf.width; + pix->height = mf.height; + } + } else { + RKCAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h); + pix->width = mf.width; + pix->height = mf.height; + } + } + #else + //need to change according to crop and scale capablicity + pix->width = mf.width; + pix->height = mf.height; + #endif + pix->colorspace = mf.colorspace; + + switch (mf.field) { + case V4L2_FIELD_ANY: + case V4L2_FIELD_NONE: + pix->field = V4L2_FIELD_NONE; + break; + default: + /* TODO: support interlaced at least in pass-through mode */ + dev_err(icd->dev.parent, "Field type %d unsupported.\n", + mf.field); + goto RK_CAMERA_TRY_FMT_END; + } + +RK_CAMERA_TRY_FMT_END: + if (ret) + RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); + return ret; +} + +static int rk_camera_reqbufs(struct soc_camera_device *icd, + struct v4l2_requestbuffers *p) +{ + int i; + + /* This is for locking debugging only. I removed spinlocks and now I + * check whether .prepare is ever called on a linked buffer, or whether + * a dma IRQ can occur for an in-work or unlinked buffer. Until now + * it hadn't triggered */ + for (i = 0; i < p->count; i++) { + struct rk_camera_buffer *buf = container_of(icd->vb_vidq.bufs[i], + struct rk_camera_buffer, vb); + buf->inwork = 0; + INIT_LIST_HEAD(&buf->vb.queue); + } + + return 0; +} + +static unsigned int rk_camera_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_device *icd = file->private_data; + struct rk_camera_buffer *buf; + + buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer, + vb.stream); + + poll_wait(file, &buf->vb.done, pt); + + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) + return POLLIN|POLLRDNORM; + + return 0; +} + +static int rk_camera_querycap(struct soc_camera_host *ici, + struct v4l2_capability *cap) +{ + struct rk_camera_dev *pcdev = ici->priv; + char orientation[5]; + + strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card)); + if (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[0].dev_name) == 0) { + sprintf(orientation,"-%d",pcdev->pdata->info[0].orientation); + } else { + sprintf(orientation,"-%d",pcdev->pdata->info[1].orientation); + } + strcat(cap->card,orientation); + cap->version = RK_CAM_VERSION_CODE; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + + return 0; +} + +static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd; + int ret = 0,tmp; + + mutex_lock(&camera_lock); + if ((pcdev->icd == icd) && (icd->ops->suspend)) { + rk_camera_s_stream(icd, 0); + sd = soc_camera_to_subdev(icd); + v4l2_subdev_call(sd, video, s_stream, 0); + ret = icd->ops->suspend(icd, state); + + pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL); + pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP); + pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE); + pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN); + pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR); + //pcdev->reginfo_suspend.VipCrm = read_vip_reg(pcdev->base,RK29_VIP_CRM); + + tmp = pcdev->reginfo_suspend.cifFs>>16; /* ddl@rock-chips.com */ + tmp += pcdev->reginfo_suspend.cifCrop>>16; + pcdev->reginfo_suspend.cifFs = (pcdev->reginfo_suspend.cifFs & 0xffff) | (tmp<<16); + + pcdev->reginfo_suspend.Inval = Reg_Validate; + rk_camera_deactivate(pcdev); + + RKCAMERA_DG("%s Enter Success...\n", __FUNCTION__); + } else { + RKCAMERA_DG("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__); + } + mutex_unlock(&camera_lock); + return ret; +} + +static int rk_camera_resume(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct v4l2_subdev *sd; + int ret = 0; + + mutex_lock(&camera_lock); + if ((pcdev->icd == icd) && (icd->ops->resume)) { + if (pcdev->reginfo_suspend.Inval == Reg_Validate) { + rk_camera_activate(pcdev, icd); + write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn); + //write_cif_reg(pcdev->base,RK29_VIP_CRM, pcdev->reginfo_suspend.VipCrm); + write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE); + write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop); + write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs); + write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt); + + rk_videobuf_capture(pcdev->active,pcdev); + rk_camera_s_stream(icd, 1); + pcdev->reginfo_suspend.Inval = Reg_Invalidate; + } else { + RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n"); + goto rk_camera_resume_end; + } + + ret = icd->ops->resume(icd); + sd = soc_camera_to_subdev(icd); + v4l2_subdev_call(sd, video, s_stream, 1); + + RKCAMERA_DG("%s Enter success\n",__FUNCTION__); + } else { + RKCAMERA_DG("%s icd has been deattach, don't need enter resume\n", __FUNCTION__); + } + +rk_camera_resume_end: + mutex_unlock(&camera_lock); + return ret; +} + +static void rk_camera_reinit_work(struct work_struct *work) +{ + struct device *control; + struct v4l2_subdev *sd; + struct v4l2_mbus_framefmt mf; + const struct soc_camera_format_xlate *xlate; + int ret; + struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work); + struct rk_camera_dev *pcdev = camera_work->pcdev; + //dump regs + { + RKCAMERA_TR("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL)); + RKCAMERA_TR("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN)); + RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT)); + RKCAMERA_TR("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR)); + RKCAMERA_TR("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP)); + RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE)); + RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL)); + RKCAMERA_TR("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30)); + RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE)); + + RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX)); + RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH)); + RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR)); + RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y)); + RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV)); + RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS)); + } + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE))); + + control = to_soc_camera_control(pcdev->icd); + sd = dev_get_drvdata(control); + ret = v4l2_subdev_call(sd,core, init, 1); + + mf.width = pcdev->icd->user_width; + mf.height = pcdev->icd->user_height; + xlate = soc_camera_xlate_by_fourcc(pcdev->icd, pcdev->icd->current_fmt->host_fmt->fourcc); + mf.code = xlate->code; + + ret |= v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE)); + + RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor now! ret:0x%x\n",ret); +} +static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer) +{ + struct rk_camera_frmivalenum *fival_nxt=NULL,*fival_pre=NULL, *fival_rec=NULL; + struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer); + struct rk_camera_dev *pcdev = fps_timer->pcdev; + int rec_flag,i; + + RKCAMERA_DG("rk_camera_fps_func fps:0x%x\n",pcdev->fps); + if (pcdev->fps < 2) { + RKCAMERA_TR("Camera host haven't recevie data from sensor,Reinit sensor delay!\n"); + pcdev->camera_reinit_work.pcdev = pcdev; + INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work); + queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work)); + } else { + for (i=0; i<2; i++) { + if (pcdev->icd == pcdev->icd_frmival[i].icd) { + fival_nxt = pcdev->icd_frmival[i].fival_list; + } + } + + rec_flag = 0; + fival_pre = fival_nxt; + while (fival_nxt != NULL) { + + RKCAMERA_DG("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev), + fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF, + (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24), + fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator, + fival_nxt->fival.discrete.numerator); + + if (((fival_nxt->fival.pixel_format == pcdev->pixfmt) + && (fival_nxt->fival.height == pcdev->icd->user_height) + && (fival_nxt->fival.width == pcdev->icd->user_width)) + || (fival_nxt->fival.discrete.denominator == 0)) { + + if (fival_nxt->fival.discrete.denominator == 0) { + fival_nxt->fival.index = 0; + fival_nxt->fival.width = pcdev->icd->user_width; + fival_nxt->fival.height= pcdev->icd->user_height; + fival_nxt->fival.pixel_format = pcdev->pixfmt; + fival_nxt->fival.discrete.denominator = pcdev->fps+2; + fival_nxt->fival.discrete.numerator = 1; + fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE; + } else { + if (abs(pcdev->fps + 2 - fival_nxt->fival.discrete.numerator) > 2) { + fival_nxt->fival.discrete.denominator = pcdev->fps+2; + fival_nxt->fival.discrete.numerator = 1; + fival_nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE; + } + } + rec_flag = 1; + fival_rec = fival_nxt; + } + fival_pre = fival_nxt; + fival_nxt = fival_nxt->nxt; + } + + if ((rec_flag == 0) && fival_pre) { + fival_pre->nxt = kzalloc(sizeof(struct rk_camera_frmivalenum), GFP_ATOMIC); + if (fival_pre->nxt != NULL) { + fival_pre->nxt->fival.index = fival_pre->fival.index++; + fival_pre->nxt->fival.width = pcdev->icd->user_width; + fival_pre->nxt->fival.height= pcdev->icd->user_height; + fival_pre->nxt->fival.pixel_format = pcdev->pixfmt; + + fival_pre->nxt->fival.discrete.denominator = pcdev->fps+2; + fival_pre->nxt->fival.discrete.numerator = 1; + fival_pre->nxt->fival.type = V4L2_FRMIVAL_TYPE_DISCRETE; + rec_flag = 1; + fival_rec = fival_pre->nxt; + } + } + } + + return HRTIMER_NORESTART; +} +static int rk_camera_s_stream(struct soc_camera_device *icd, int enable) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + int cif_ctrl_val; + int ret; + + WARN_ON(pcdev->icd != icd); + + cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL); + if (enable) { + pcdev->fps = 0; + hrtimer_cancel(&(pcdev->fps_timer.timer)); + pcdev->fps_timer.pcdev = pcdev; + hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(5, 0),HRTIMER_MODE_REL); + cif_ctrl_val |= ENABLE_CAPTURE; + } else { + cif_ctrl_val &= ~ENABLE_CAPTURE; + ret = hrtimer_cancel(&pcdev->fps_timer.timer); + ret |= flush_work(&(pcdev->camera_reinit_work.work)); + RKCAMERA_DG("STREAM_OFF cancel timer and flush work:0x%x \n", ret); + } + write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val); + + RKCAMERA_DG("%s.. enable : 0x%x , CIF_CIF_CTRL = 0x%x\n", __FUNCTION__, enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL)); + return 0; +} +int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + struct rk_camera_frmivalenum *fival_list = NULL; + struct v4l2_frmivalenum *fival_head; + int i,ret = 0,index; + + index = fival->index & 0x00ffffff; + if ((fival->index & 0xff000000) == 0xff000000) { /* ddl@rock-chips.com: detect framerate */ + for (i=0; i<2; i++) { + if (pcdev->icd_frmival[i].icd == icd) { + fival_list = pcdev->icd_frmival[i].fival_list; + } + } + + if (fival_list != NULL) { + i = 0; + while (fival_list != NULL) { + if ((fival->pixel_format == fival_list->fival.pixel_format) + && (fival->height == fival_list->fival.height) + && (fival->width == fival_list->fival.width)) { + if (i == index) + break; + i++; + } + fival_list = fival_list->nxt; + } + + if ((i==index) && (fival_list != NULL)) { + memcpy(fival, &fival_list->fival, sizeof(struct v4l2_frmivalenum)); + } else { + ret = -EINVAL; + } + } else { + RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__); + ret = -EINVAL; + } + } else { + if (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[0].dev_name) == 0) { + fival_head = pcdev->pdata->info[0].fival; + } else { + fival_head = pcdev->pdata->info[1].fival; + } + i = 0; + while (fival_head->width && fival_head->height) { + if ((fival->pixel_format == fival_head->pixel_format) + && (fival->height == fival_head->height) + && (fival->width == fival_head->width)) { + if (i == index) { + break; + } + i++; + } + fival_head++; + } + + if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) { + memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum)); + RKCAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(&pcdev->icd->dev), + fival->width, fival->height, + fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF, + (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24), + fival->discrete.denominator,fival->discrete.numerator); + } else { + if (index == 0) + RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(&pcdev->icd->dev), + fival->width,fival->height, + fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF, + (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24), + index); + else + RKCAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(&pcdev->icd->dev), + fival->width,fival->height, + fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF, + (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24), + index); + ret = -EINVAL; + } + } + + return ret; +} + +#ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON +static int rk_camera_set_digit_zoom(struct soc_camera_device *icd, + const struct v4l2_queryctrl *qctrl, int zoom_rate) +{ + struct v4l2_crop a; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + unsigned int cif_fs = 0,cif_crop = 0; + #if 1 +/* ddl@rock-chips.com : The largest resolution is 2047x1088, so larger resolution must be operated some times + (Assume operate times is 4),but resolution which ipp can operate ,it is width and height must be even. */ + a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + a.c.width = icd->user_width*100/zoom_rate; + a.c.width &= ~0x03; + a.c.height = icd->user_height*100/zoom_rate; + a.c.height &= ~0x03; + + a.c.left = (((pcdev->host_width - a.c.width)>>1) +pcdev->host_left)&(~0x01); + a.c.top = (((pcdev->host_height - a.c.height)>>1) + pcdev->host_top)&(~0x01); + + down(&pcdev->zoominfo.sem); + pcdev->zoominfo.a.c.height = a.c.height; + pcdev->zoominfo.a.c.width = a.c.width; + pcdev->zoominfo.a.c.top = 0; + pcdev->zoominfo.a.c.left = 0; + up(&pcdev->zoominfo.sem); + + cif_crop = (a.c.left+ (a.c.top<<16)); + cif_fs = ((a.c.width ) + (a.c.height<<16)); +//cif do the crop , ipp do the scale + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE))); + write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop); + write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, cif_fs); + write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width); + write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|(ENABLE_CAPTURE))); + //MUST bypass scale + #else + //change the crop and scale parameters + #endif + RKCAMERA_DG("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, pcdev->host_width, pcdev->host_height ); + + return 0; +} +#endif +static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl( + struct soc_camera_host_ops *ops, int id) +{ + int i; + + for (i = 0; i < ops->num_controls; i++) + if (ops->controls[i].id == id) + return &ops->controls[i]; + + return NULL; +} + + +static int rk_camera_set_ctrl(struct soc_camera_device *icd, + struct v4l2_control *sctrl) +{ + + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + const struct v4l2_queryctrl *qctrl; + struct rk_camera_dev *pcdev = ici->priv; + int ret = 0; + + qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id); + if (!qctrl) { + ret = -ENOIOCTLCMD; + goto rk_camera_set_ctrl_end; + } + + switch (sctrl->id) + { + #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON + case V4L2_CID_ZOOM_ABSOLUTE: + { + if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){ + ret = -EINVAL; + goto rk_camera_set_ctrl_end; + } + ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value); + if (ret == 0) { + pcdev->zoominfo.zoom_rate = sctrl->value; + } else { + goto rk_camera_set_ctrl_end; + } + break; + } + #endif + default: + ret = -ENOIOCTLCMD; + break; + } +rk_camera_set_ctrl_end: + return ret; +} + +static struct soc_camera_host_ops rk_soc_camera_host_ops = +{ + .owner = THIS_MODULE, + .add = rk_camera_add_device, + .remove = rk_camera_remove_device, + .suspend = rk_camera_suspend, + .resume = rk_camera_resume, + .enum_frameinervals = rk_camera_enum_frameintervals, + .set_crop = rk_camera_set_crop, + .get_formats = rk_camera_get_formats, + .put_formats = rk_camera_put_formats, + .set_fmt = rk_camera_set_fmt, + .try_fmt = rk_camera_try_fmt, + .init_videobuf = rk_camera_init_videobuf, + .reqbufs = rk_camera_reqbufs, + .poll = rk_camera_poll, + .querycap = rk_camera_querycap, + .set_bus_param = rk_camera_set_bus_param, + .s_stream = rk_camera_s_stream, /* ddl@rock-chips.com : Add stream control for host */ + .set_ctrl = rk_camera_set_ctrl, + .controls = rk_camera_controls, + .num_controls = ARRAY_SIZE(rk_camera_controls) + +}; +static int rk_camera_probe(struct platform_device *pdev) +{ + struct rk_camera_dev *pcdev; + struct resource *res; + struct rk_camera_frmivalenum *fival_list,*fival_nxt; + int irq,i; + int err = 0; + + RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || irq < 0) { + err = -ENODEV; + goto exit; + } + pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); + if (!pcdev) { + dev_err(&pdev->dev, "Could not allocate pcdev\n"); + err = -ENOMEM; + goto exit_alloc; + } + + + /*config output clk*/ // must modify start + #if 0 + pcdev->aclk_ddr_lcdc = clk_get(&pdev->dev, "aclk_ddr_lcdc"); + pcdev->aclk_disp_matrix = clk_get(&pdev->dev, "aclk_disp_matrix"); + + pcdev->hclk_cpu_display = clk_get(&pdev->dev, "hclk_cpu_display"); + pcdev->vip_slave = clk_get(&pdev->dev, "vip_slave"); + pcdev->vip_out = clk_get(&pdev->dev,"vip_out"); + pcdev->vip_input = clk_get(&pdev->dev,"vip_input"); + pcdev->vip_bus = clk_get(&pdev->dev, "vip_bus"); + + pcdev->hclk_disp_matrix = clk_get(&pdev->dev,"hclk_disp_matrix"); + pcdev->vip_matrix = clk_get(&pdev->dev,"vip_matrix"); + + pcdev->pd_display = clk_get(&pdev->dev,"pd_display"); + + pcdev->zoominfo.zoom_rate = 100; + + if (!pcdev->aclk_ddr_lcdc || !pcdev->aclk_disp_matrix || !pcdev->hclk_cpu_display || + !pcdev->vip_slave || !pcdev->vip_out || !pcdev->vip_input || !pcdev->vip_bus || !pcdev->pd_display || + IS_ERR(pcdev->aclk_ddr_lcdc) || IS_ERR(pcdev->aclk_disp_matrix) || IS_ERR(pcdev->hclk_cpu_display) || IS_ERR(pcdev->pd_display) || + IS_ERR(pcdev->vip_slave) || IS_ERR(pcdev->vip_out) || IS_ERR(pcdev->vip_input) || IS_ERR(pcdev->vip_bus)) { +//must modify end + RKCAMERA_TR(KERN_ERR "failed to get vip_clk(axi) source\n"); + err = -ENOENT; + goto exit_reqmem_vip; + } + + if (!pcdev->hclk_disp_matrix || !pcdev->vip_matrix || + IS_ERR(pcdev->hclk_disp_matrix) || IS_ERR(pcdev->vip_matrix)) { + + RKCAMERA_TR(KERN_ERR "failed to get vip_clk(ahb) source\n"); + err = -ENOENT; + goto exit_reqmem_vip; + } +#endif + dev_set_drvdata(&pdev->dev, pcdev); + pcdev->res = res; + pcdev->pdata = pdev->dev.platform_data; /* ddl@rock-chips.com : Request IO in init function */ + pcdev->hostid = pdev->id; + + if (pcdev->pdata && pcdev->pdata->io_init) { + pcdev->pdata->io_init(); + } + #ifdef CONFIG_VIDEO_RK29_WORK_IPP + if (pcdev->pdata && (strcmp(pcdev->pdata->meminfo.name,"camera_ipp_mem")==0)) { + pcdev->vipmem_phybase = pcdev->pdata->meminfo.start; + pcdev->vipmem_size = pcdev->pdata->meminfo.size; + RKCAMERA_DG("\n%s Memory(start:0x%x size:0x%x) for IPP obtain \n",__FUNCTION__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size); + } else { + RKCAMERA_TR("\n%s Memory for IPP have not obtain! IPP Function is fail\n",__FUNCTION__); + pcdev->vipmem_phybase = 0; + pcdev->vipmem_size = 0; + } + #endif + INIT_LIST_HEAD(&pcdev->capture); + spin_lock_init(&pcdev->lock); + sema_init(&pcdev->zoominfo.sem,1); + + /* + * Request the regions. + */ + if(res){ + if (!request_mem_region(res->start, res->end - res->start + 1, + RK29_CAM_DRV_NAME)) { + err = -EBUSY; + goto exit_reqmem_vip; + } + pcdev->base = ioremap(res->start, res->end - res->start + 1); + if (pcdev->base == NULL) { + dev_err(pcdev->dev, "ioremap() of registers failed\n"); + err = -ENXIO; + goto exit_ioremap_vip; + } + } + + pcdev->irq = irq; + pcdev->dev = &pdev->dev; + + /* config buffer address */ + /* request irq */ + if(irq > 0){ + err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME, + pcdev); + if (err) { + dev_err(pcdev->dev, "Camera interrupt register failed \n"); + goto exit_reqirq; + } + } + pcdev->camera_wq = create_workqueue("rk_camera_workqueue"); + if (pcdev->camera_wq == NULL) + goto exit_free_irq; + pcdev->camera_reinit_work.pcdev = pcdev; + INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work); + + for (i=0; i<2; i++) { + pcdev->icd_frmival[i].icd = NULL; + pcdev->icd_frmival[i].fival_list = kzalloc(sizeof(struct rk_camera_frmivalenum),GFP_KERNEL); + + } + pcdev->soc_host.drv_name = RK29_CAM_DRV_NAME; + pcdev->soc_host.ops = &rk_soc_camera_host_ops; + pcdev->soc_host.priv = pcdev; + pcdev->soc_host.v4l2_dev.dev = &pdev->dev; + pcdev->soc_host.nr = pdev->id; + + err = soc_camera_host_register(&pcdev->soc_host); + if (err) + goto exit_free_irq; + pcdev->fps_timer.pcdev = pcdev; + hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pcdev->fps_timer.timer.function = rk_camera_fps_func; + pcdev->icd_cb.sensor_cb = NULL; +// rk29_camdev_info_ptr = pcdev; + RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__); + return 0; + +exit_free_irq: + + for (i=0; i<2; i++) { + fival_list = pcdev->icd_frmival[i].fival_list; + fival_nxt = fival_list; + while(fival_nxt != NULL) { + fival_nxt = fival_list->nxt; + kfree(fival_list); + fival_list = fival_nxt; + } + } + + free_irq(pcdev->irq, pcdev); + if (pcdev->camera_wq) { + destroy_workqueue(pcdev->camera_wq); + pcdev->camera_wq = NULL; + } +exit_reqirq: + iounmap(pcdev->base); +exit_ioremap_vip: + release_mem_region(res->start, res->end - res->start + 1); + +exit_reqmem_vip: + if (pcdev->aclk_ddr_lcdc) { + clk_put(pcdev->aclk_ddr_lcdc); + pcdev->aclk_ddr_lcdc = NULL; + } + if (pcdev->aclk_disp_matrix) { + clk_put(pcdev->aclk_disp_matrix); + pcdev->aclk_disp_matrix = NULL; + } + if (pcdev->hclk_cpu_display) { + clk_put(pcdev->hclk_cpu_display); + pcdev->hclk_cpu_display = NULL; + } + if (pcdev->vip_slave) { + clk_put(pcdev->vip_slave); + pcdev->vip_slave = NULL; + } + if (pcdev->vip_out) { + clk_put(pcdev->vip_out); + pcdev->vip_out = NULL; + } + if (pcdev->vip_input) { + clk_put(pcdev->vip_input); + pcdev->vip_input = NULL; + } + if (pcdev->vip_bus) { + clk_put(pcdev->vip_bus); + pcdev->vip_bus = NULL; + } + if (pcdev->hclk_disp_matrix) { + clk_put(pcdev->hclk_disp_matrix); + pcdev->hclk_disp_matrix = NULL; + } + if (pcdev->vip_matrix) { + clk_put(pcdev->vip_matrix); + pcdev->vip_matrix = NULL; + } + kfree(pcdev); +exit_alloc: +// rk_camdev_info_ptr = NULL; +exit: + return err; +} + +static int __devexit rk_camera_remove(struct platform_device *pdev) +{ + struct rk_camera_dev *pcdev = platform_get_drvdata(pdev); + struct resource *res; + struct rk_camera_frmivalenum *fival_list,*fival_nxt; + int i; + + free_irq(pcdev->irq, pcdev); + + if (pcdev->camera_wq) { + destroy_workqueue(pcdev->camera_wq); + pcdev->camera_wq = NULL; + } + + for (i=0; i<2; i++) { + fival_list = pcdev->icd_frmival[i].fival_list; + fival_nxt = fival_list; + while(fival_nxt != NULL) { + fival_nxt = fival_list->nxt; + kfree(fival_list); + fival_list = fival_nxt; + } + } + + soc_camera_host_unregister(&pcdev->soc_host); + + res = pcdev->res; + 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->hostid); + } + + kfree(pcdev); + // rk_camdev_info_ptr = NULL; + dev_info(&pdev->dev, "RK28 Camera driver unloaded\n"); + + return 0; +} + +static struct platform_driver rk_camera_driver = +{ + .driver = { + .name = RK29_CAM_DRV_NAME, + }, + .probe = rk_camera_probe, + .remove = __devexit_p(rk_camera_remove), +}; + + +static int __devinit rk_camera_init(void) +{ + RKCAMERA_DG("%s..%s..%d \n",__FUNCTION__,__FILE__,__LINE__); + return platform_driver_register(&rk_camera_driver); +} + +static void __exit rk_camera_exit(void) +{ + platform_driver_unregister(&rk_camera_driver); +} + +device_initcall_sync(rk_camera_init); +module_exit(rk_camera_exit); + +MODULE_DESCRIPTION("RKSoc Camera Host driver"); +MODULE_AUTHOR("ddl "); +MODULE_LICENSE("GPL"); +#endif diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c old mode 100644 new mode 100755 index cfe412a1733d..44dc74e60bcf --- a/drivers/media/video/s5k6aa.c +++ b/drivers/media/video/s5k6aa.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include #include "s5k6aa.h" static int debug; @@ -54,10 +55,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480 #define SENSOR_MAX_WIDTH 1280 #define SENSOR_MAX_HEIGHT 1024 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -79,11 +81,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 - -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -110,7 +107,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_AF_MODE_CLOSE 5 #endif -/* init 640X480 SVGA */ +/* init 800*600 SVGA */ static struct reginfo sensor_init_data[] = { {0x0010,0x0001}, // Reset @@ -3310,6 +3307,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { @@ -3318,9 +3322,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; - u16 pid = 0; - + char value; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); sensor_ioctrl(icd,Sensor_Reset, 1); @@ -3368,7 +3426,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -4605,20 +4663,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/sid130B.c b/drivers/media/video/sid130B.c old mode 100755 new mode 100644 index ef1f427615a2..e354db5d4635 --- a/drivers/media/video/sid130B.c +++ b/drivers/media/video/sid130B.c @@ -19,7 +19,9 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include +#include +#include + static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -50,10 +52,12 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 144 #define SENSOR_MAX_WIDTH 1600 #define SENSOR_MAX_HEIGHT 1200 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam + #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -73,9 +77,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW|\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 @@ -1674,6 +1675,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1681,7 +1689,62 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1742,7 +1805,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } #endif - ret = sensor_write_array(client, sensor_init_data); + ret = sensor_write_array(client, sensor_init_data_p); if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); @@ -2919,20 +2982,22 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash diff --git a/drivers/media/video/siv120b.c b/drivers/media/video/siv120b.c index a300398eaad4..13bd16538e47 100755 --- a/drivers/media/video/siv120b.c +++ b/drivers/media/video/siv120b.c @@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron #include #include #include -#include - +#include +#include static int debug; module_param(debug, int, S_IRUGO|S_IWUSR); @@ -51,10 +51,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_MIN_HEIGHT 480//144 #define SENSOR_MAX_WIDTH 640 #define SENSOR_MAX_HEIGHT 480 -#define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ -#define SENSOR_INIT_HEIGHT 480 -#define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 +#define SENSOR_INIT_WIDTH sensor_init_width /* Sensor pixel size for sensor_init_data array */ +#define SENSOR_INIT_HEIGHT sensor_init_height +#define SENSOR_INIT_WINSEQADR sensor_init_winseq_p +#define SENSOR_INIT_PIXFMT sensor_init_pixelcode +#define SENSOR_BUS_PARAM sensor_init_busparam #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -74,10 +75,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 -#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\ - SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\ - SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) - #define COLOR_TEMPERATURE_CLOUDY_DN 6500 #define COLOR_TEMPERATURE_CLOUDY_UP 8000 #define COLOR_TEMPERATURE_CLEARDAY_DN 5000 @@ -1457,7 +1454,13 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd sensor_power_end: return ret; } - +static s32 sensor_init_width = 640; +static s32 sensor_init_height = 480; +static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ); +static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8; +static struct reginfo* sensor_init_data_p = NULL; +static struct reginfo* sensor_init_winseq_p = NULL; +static struct reginfo* sensor_init_winseq_board = NULL; static int sensor_init(struct v4l2_subdev *sd, u32 val) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1465,8 +1468,63 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; const struct sensor_datafmt *fmt; - int ret, i; - + char value; + int ret,pid = 0,i = 0,j=0; + struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val; + sensor_init_data_p = sensor_init_data; + sensor_init_winseq_p = sensor_vga; + sensor_init_width = 640; + sensor_init_height = 480; + if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { + for(i = 0;i < RK_CAM_NUM;i++){ + if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name && + (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0)) + break; + } + } + if(tmp_plat_data && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){ + //user has defined the init data + //init reg + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){ + sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg; + sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val; + } + sensor_init_data_p = sensor_init_data; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){ + sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data); + } + //init winseq + if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){ + int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size; + if(sensor_init_winseq_board) + { + vfree(sensor_init_winseq_board); + sensor_init_winseq_board = NULL; + } + sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size); + if(!sensor_init_winseq_board) + SENSOR_TR("%s :vmalloc erro !",__FUNCTION__); + for(j = 0;j< tmp_winseq_size;j++){ + sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg; + sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val; + } + sensor_init_winseq_p = sensor_init_winseq_board; + } + else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){ + sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq); + } + //init width,height,bus,pixelcode + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE) + sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE) + sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE) + sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param; + if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE) + sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode; + } SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { @@ -1491,7 +1549,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) // ret = sensor_write(client, sensor_init_data + i*2, sensor_init_data + i*2 + 1); // printk("write to reg[0x%x] 0x%x\n",sensor_init_data[i].reg,sensor_init_data[i].val); - ret = sensor_write(client, sensor_init_data[i].reg, sensor_init_data[i].val); + ret = sensor_write(client, sensor_init_data_p[i].reg, sensor_init_data_p[i].val); //ret = sensor_write_array(client, sensor_init_data); if (ret != 0) { @@ -2607,20 +2665,23 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RK29_CAM_SUBDEV_IOREQUEST: { - sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; - if (sensor->sensor_io_request != NULL) { - if (sensor->sensor_io_request->gpio_res[0].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0]; - } else if (sensor->sensor_io_request->gpio_res[1].dev_name && - (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) { - sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1]; - } - } else { - SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); - ret = -EINVAL; - goto sensor_ioctl_end; - } + sensor->sensor_io_request = (struct rk29camera_platform_data*)arg; + if (sensor->sensor_io_request != NULL) { + int j = 0; + for(j = 0;j < RK_CAM_NUM;j++){ + if (sensor->sensor_io_request->gpio_res[j].dev_name && + (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) { + sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j]; + break; + } + } + if(j == RK_CAM_NUM){ + SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__); + ret = -EINVAL; + goto sensor_ioctl_end; + } + } + /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash -- 2.34.1