From: zyc Date: Wed, 16 Oct 2013 08:06:11 +0000 (+0800) Subject: camera: add ov8825,ov2720 dirver for icatch7002. X-Git-Tag: firefly_0821_release~6556 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e2f94931cd58a6c2f1f9c3b7f29c09263b7dff7f;p=firefly-linux-kernel-4.4.55.git camera: add ov8825,ov2720 dirver for icatch7002. --- diff --git a/arch/arm/plat-rk/include/plat/rk_camera.h b/arch/arm/plat-rk/include/plat/rk_camera.h index cd349c8a759e..ed8167f8c9e6 100755 --- a/arch/arm/plat-rk/include/plat/rk_camera.h +++ b/arch/arm/plat-rk/include/plat/rk_camera.h @@ -259,6 +259,8 @@ #define RK29_CAM_SENSOR_NT99340 nt99340 //oyyf@rock-chips.com #define RK29_CAM_ISP_ICATCH7002_MI1040 icatchmi1040 #define RK29_CAM_ISP_ICATCH7002_OV5693 icatchov5693 +#define RK29_CAM_ISP_ICATCH7002_OV8825 icatchov8825 //zyt +#define RK29_CAM_ISP_ICATCH7002_OV2720 icatchov2720 //zyt #define RK29_CAM_SENSOR_NAME_OV7675 "ov7675" #define RK29_CAM_SENSOR_NAME_OV9650 "ov9650" @@ -298,6 +300,8 @@ #define RK29_CAM_SENSOR_NAME_HM5065 "hm5065" #define RK29_CAM_ISP_NAME_ICATCH7002_MI1040 "icatchmi1040" #define RK29_CAM_ISP_NAME_ICATCH7002_OV5693 "icatchov5693" +#define RK29_CAM_ISP_NAME_ICATCH7002_OV8825 "icatchov8825" //zyt +#define RK29_CAM_ISP_NAME_ICATCH7002_OV2720 "icatchov2720" //zyt //Sensor full resolution define #define ov7675_FULL_RESOLUTION 0x30000 // 0.3 megapixel @@ -362,6 +366,8 @@ #define nt99340_FULL_RESOLUTION 0x300000 // oyyf@rock-chips.com: 3 megapixel 2048*1536 #define icatchmi1040_FULL_RESOLUTION 0x200000 #define icatchov5693_FULL_RESOLUTION 0x500000 +#define icatchov8825_FULL_RESOLUTION 0x800000 //zyt +#define icatchov2720_FULL_RESOLUTION 0x210000 //zyt #define end_FULL_RESOLUTION 0x00 //Sensor i2c addr define @@ -416,6 +422,8 @@ #define hm5065_I2C_ADDR 0x3e #define icatchmi1040_I2C_ADDR 0x78 #define icatchov5693_I2C_ADDR 0x78 +#define icatchov8825_I2C_ADDR 0x78 //zyt +#define icatchov2720_I2C_ADDR 0x78 //zyt #define end_I2C_ADDR INVALID_VALUE @@ -547,6 +555,15 @@ #define icatchov5693_PWRSEQ (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\ SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\ SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1)) + +#define icatchov8825_PWRSEQ (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1)) //zyt + +#define icatchov2720_PWRSEQ (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\ + SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1)) //zyt + #define icatchmi1040_PWRSEQ (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\ SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\ SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1)) diff --git a/drivers/media/video/generic_sensor.h b/drivers/media/video/generic_sensor.h index 65a4cd55b611..879f18ddef36 100755 --- a/drivers/media/video/generic_sensor.h +++ b/drivers/media/video/generic_sensor.h @@ -336,6 +336,12 @@ static inline int sensor_get_full_width_height(int full_resolution, unsigned sho *h = 1200; break; } + case 0x210000: + { + *w = 1920; + *h = 1080; + break; + } case 0x300000: { diff --git a/drivers/media/video/icatch7002/Kconfig b/drivers/media/video/icatch7002/Kconfig index 4d0fa334a536..52306b014745 100755 --- a/drivers/media/video/icatch7002/Kconfig +++ b/drivers/media/video/icatch7002/Kconfig @@ -7,6 +7,21 @@ config ICATCH7002_OV5693 default n help Choose Y here if you have this this sensor and it is attach to icatch7002 + +config ICATCH7002_OV8825 + depends on SOC_CAMERA_ICATCH7002 + tristate "icatch7002 attached ov8825" + default n + help + Choose Y here if you have this this sensor and it is attach to icatch7002 + +config ICATCH7002_OV2720 + depends on SOC_CAMERA_ICATCH7002 + tristate "icatch7002 attached ov2720" + default n + help + Choose Y here if you have this this sensor and it is attach to icatch7002 + config ICATCH7002_MI1040 depends on SOC_CAMERA_ICATCH7002 tristate "icatch7002 attached mi1040" diff --git a/drivers/media/video/icatch7002/Makefile b/drivers/media/video/icatch7002/Makefile index 0377415935fb..916cf8e754d1 100755 --- a/drivers/media/video/icatch7002/Makefile +++ b/drivers/media/video/icatch7002/Makefile @@ -5,6 +5,8 @@ obj-$(CONFIG_SOC_CAMERA_ICATCH7002) += icatch7002_common.o #obj-$(CONFIG_SOC_CAMERA_ICATCH7002) += icatch_spi_host.o obj-$(CONFIG_ICATCH7002_MI1040) += icatch7002_mi1040.o obj-$(CONFIG_ICATCH7002_OV5693) += icatch7002_ov5693.o +obj-$(CONFIG_ICATCH7002_OV8825) += icatch7002_ov8825.o +obj-$(CONFIG_ICATCH7002_OV2720) += icatch7002_ov2720.o obj-$(CONFIG_SOC_CAMERA_ICATCH7002) += burn_spi_sample_code_0910.o obj-$(CONFIG_SOC_CAMERA_ICATCH7002) += app_i2c_lib_icatch.o diff --git a/drivers/media/video/icatch7002/icatch7002_common.c b/drivers/media/video/icatch7002/icatch7002_common.c index aa2cb494e252..217a309b2ca3 100755 --- a/drivers/media/video/icatch7002/icatch7002_common.c +++ b/drivers/media/video/icatch7002/icatch7002_common.c @@ -620,7 +620,7 @@ int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_z }else if(value == WqCmd_af_continues) set_val = 3; else{ - + DEBUG_TRACE("%s:focus value is invalidate!\n",__func__); } EXISP_I2C_FocusModeSet(set_val); @@ -649,8 +649,16 @@ int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_z } } + int staus_value = 0; + if(value == WqCmd_af_continues) + //staus_value = 0x10; + goto icatch_sensor_set_auto_focus_end; + else if(value == WqCmd_af_single) + staus_value = 0x0; + + while (cnt--) { - if (EXISP_I2C_AFStatusGet() == 0) { + if (EXISP_I2C_AFStatusGet() == staus_value) { break; } msleep(30); @@ -660,7 +668,9 @@ int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_z if (cnt <= 0) { DEBUG_TRACE("%s: focus timeout %d\n",__func__, value); - //__dump_i2c(0x7005, 0x7005); + __dump_i2c(0x7200, 0x727f); + + __dump_i2c(0x7005, 0x7006); return 1; } @@ -668,7 +678,7 @@ int icatch_sensor_set_auto_focus(struct i2c_client *client, int value,int *tmp_z DEBUG_TRACE("%s: focus fail %d\n",__func__, value); return 1; } - +icatch_sensor_set_auto_focus_end: DEBUG_TRACE("%s: focus success %d\n\n",__func__, value); return 0; } @@ -1691,7 +1701,7 @@ static int sensor_hdr_exposure(struct i2c_client *client, unsigned int code) - int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf) + int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf,bool is_capture) { const struct sensor_datafmt *fmt; struct generic_sensor*sgensor = to_generic_sensor(client); @@ -1789,6 +1799,12 @@ static int sensor_hdr_exposure(struct i2c_client *client, unsigned int code) set_h = 1944; res_set = OUTPUT_QSXGA; } + else if (((set_w <= 3264) && (set_h <= 2448)) && (supported_size & OUTPUT_QUXGA)) + { + set_w = 3264; + set_h = 2448; + res_set = OUTPUT_QUXGA; + } else { set_w = 1280; @@ -1800,6 +1816,11 @@ static int sensor_hdr_exposure(struct i2c_client *client, unsigned int code) // sensor_set_isp_output_res(client,res_set); //res will be setted sensor->isp_priv_info.curRes = res_set; + if(is_capture) + sensor->isp_priv_info.curPreviewCapMode = CAPTURE_MODE; + else + sensor->isp_priv_info.curPreviewCapMode = PREVIEW_MODE; + mf->width = set_w; mf->height = set_h; //enter capture or preview mode @@ -1915,6 +1936,13 @@ int icatch_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsiz fsize->discrete.width = 2592; fsize->discrete.height = 1944; fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + } + else if ((sensor->isp_priv_info.supportedSize[fsize->index] & OUTPUT_QUXGA)) + { + + fsize->discrete.width = 3264; + fsize->discrete.height = 2448; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; } else { err = -1; } @@ -1949,7 +1977,7 @@ end: static int icatch_set_isp_output_res(struct i2c_client *client,enum ISP_OUTPUT_RES outputSize){ struct generic_sensor*sgensor = to_generic_sensor(client); struct specific_sensor*sensor = to_specific_sensor(sgensor); -#if 0 +#if 1 u8 res_sel = 0; switch(outputSize) { case OUTPUT_QCIF: @@ -1966,9 +1994,13 @@ static int icatch_set_isp_output_res(struct i2c_client *client,enum ISP_OUTPUT_R case OUTPUT_SXGA: case OUTPUT_UXGA: case OUTPUT_1080P: + res_sel = 0x02; case OUTPUT_QXGA: case OUTPUT_QSXGA: - res_sel = IMAGE_CAP_NONZSL_SINGLE;// non-zsl single + res_sel = 0x0A;// non-zsl single + break; + case OUTPUT_QUXGA: + res_sel = 0x01;// non-zsl single break; default: DEBUG_TRACE("%s %s isp not support this resolution!\n",sgensor->dev_name,__FUNCTION__); @@ -1977,11 +2009,13 @@ static int icatch_set_isp_output_res(struct i2c_client *client,enum ISP_OUTPUT_R #endif int cnt = 16; //preview mode set - if(outputSize == OUTPUT_QSXGA){ + if((sensor->isp_priv_info.curPreviewCapMode == CAPTURE_MODE) + /*(outputSize == OUTPUT_QSXGA) || (outputSize == OUTPUT_QSXGA)*/){ + //in capture mode , isp output full size if size have not been set. if(sensor->isp_priv_info.hdr == FALSE){ if(IsZSL){ printk("IsZSL EXISP_PvSizeSet(0x0A)\n"); - EXISP_PvSizeSet(0x0A); + EXISP_PvSizeSet(res_sel); //polling until AE ready while (((EXISP_I2C_3AStatusGet() & 0x1) == 0) && (cnt -- > 0)) { DEBUG_TRACE("%s %s polling AE ready\n",sgensor->dev_name,__FUNCTION__); @@ -1999,17 +2033,17 @@ static int icatch_set_isp_output_res(struct i2c_client *client,enum ISP_OUTPUT_R EXISP_ImageCapSet(IMAGE_CAP_HDR); sensor_interrupt_wait_clear(); } - sensor->isp_priv_info.curPreviewCapMode = CAPTURE_NONE_ZSL_MODE; + //sensor->isp_priv_info.curPreviewCapMode = CAPTURE_NONE_ZSL_MODE; } else{ - EXISP_PvSizeSet(IMAGE_CAP_SINGLE); + EXISP_PvSizeSet(res_sel); //polling until AE ready while (((EXISP_I2C_3AStatusGet() & 0x1) == 0) && (cnt -- > 0)) { DEBUG_TRACE("%s %s polling AE ready\n",sgensor->dev_name,__FUNCTION__); mdelay(50); } sensor_interrupt_wait_clear(); - sensor->isp_priv_info.curPreviewCapMode = PREVIEW_MODE; + //sensor->isp_priv_info.curPreviewCapMode = PREVIEW_MODE; #if 1 DEBUG_TRACE("\n %s pid = 0x%x\n", sgensor->dev_name, EXISP_I2C_VendorIdGet); DEBUG_TRACE("fw version is 0x%x\n ",EXISP_I2C_FWVersionGet()); diff --git a/drivers/media/video/icatch7002/icatch7002_common.h b/drivers/media/video/icatch7002/icatch7002_common.h index cf90ccd00ed8..cc7148550078 100755 --- a/drivers/media/video/icatch7002/icatch7002_common.h +++ b/drivers/media/video/icatch7002/icatch7002_common.h @@ -76,7 +76,7 @@ extern int icatch_load_fw(struct soc_camera_device *icd,u8 sensorid); int icatch_get_rearid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *rear_id); int icatch_get_frontid_by_lowlevelmode(struct soc_camera_device *icd,UINT16 *front_id); extern int icatch_sensor_init(struct i2c_client *client); -extern int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf); +extern int icatch_s_fmt(struct i2c_client *client, struct v4l2_mbus_framefmt *mf,bool is_capture); extern int icatch_s_stream(struct v4l2_subdev *sd, int enable); extern int sensor_set_get_control_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, struct v4l2_ext_control *ext_ctrl,bool is_set); @@ -97,6 +97,7 @@ enum ISP_OUTPUT_RES{ OUTPUT_1080P =0x0800, //1920*1080 OUTPUT_QXGA =0x1000, // 2048*1536 OUTPUT_QSXGA =0x2000, // 2592*1944 + OUTPUT_QUXGA =0x4000, //3264*2448 }; diff --git a/drivers/media/video/icatch7002/icatch7002_mi1040.c b/drivers/media/video/icatch7002/icatch7002_mi1040.c index 7291b847c24a..30a50fbaeaa7 100755 --- a/drivers/media/video/icatch7002/icatch7002_mi1040.c +++ b/drivers/media/video/icatch7002/icatch7002_mi1040.c @@ -465,7 +465,7 @@ static int sensor_deactivate_cb(struct i2c_client *client) */ static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) { - return icatch_s_fmt(client, mf); + return icatch_s_fmt(client, mf,capture); } /* * the function is called after sensor register setting finished in VIDIOC_S_FMT diff --git a/drivers/media/video/icatch7002/icatch7002_ov2720.c b/drivers/media/video/icatch7002/icatch7002_ov2720.c new file mode 100755 index 000000000000..a2302abf03b3 --- /dev/null +++ b/drivers/media/video/icatch7002/icatch7002_ov2720.c @@ -0,0 +1,629 @@ + +#include "icatch7002_common.h" +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*v0.0.3: +* add sensor_focus_af_const_pause_usr_cb; +*/ +static int version = KERNEL_VERSION(0,0,3); +module_param(version, int, S_IRUGO); + + + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_ISP_ICATCH7002_OV2720 +#define SENSOR_V4L2_IDENT V4L2_IDENT_ICATCH7002_OV2720 +#define SENSOR_ID 0x2720 +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ + SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\ + SOCAM_DATA_ACTIVE_HIGH|SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 1280 +#define SENSOR_PREVIEW_H 960 +#define SENSOR_PREVIEW_FPS 30000 // 15fps +#define SENSOR_FULLRES_L_FPS 15000 // 7.5fps +#define SENSOR_FULLRES_H_FPS 15000 // 7.5fps +#define SENSOR_720P_FPS 30000 +#define SENSOR_1080P_FPS 0 + + +static unsigned int SensorConfiguration = 0; +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor Driver Configuration End */ + + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +//#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +//#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b) +//#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +//#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +//#define sensor_write_array generic_sensor_write_array + + + +/* +* The follow setting need been filled. +* +* Must Filled: +* sensor_init_data : Sensor initial setting; +* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; +* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; +* sensor_softreset_data : Sensor software reset register; +* sensor_check_id_data : Sensir chip id register; +* +* Optional filled: +* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; +* sensor_720p: Sensor 720p setting, it is for video; +* sensor_1080p: Sensor 1080p setting, it is for video; +* +* :::::WARNING::::: +* The SensorEnd which is the setting end flag must be filled int the last of each setting; +*/ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] ={ + SensorStreamChk, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + SensorEnd + +}; + +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + SensorStreamChk, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + SensorStreamChk, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorEnd +}; +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[]= +{ + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + SensorEnd +}; +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[]= +{ + // Brightness -2 + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + + SensorEnd +}; +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + SensorEnd +}; +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[]= +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +static struct rk_sensor_reg sensor_Contrast0[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; +static struct rk_sensor_reg sensor_SceneAuto[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +static struct rk_sensor_reg sensor_Zoom0[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = +{ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Zoom3[] = +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; + +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = +{ + //white balance + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"normal",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,4,"mono",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"aura",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,7,"vintage",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,8,"vintage2",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,9,"lomo",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,10,"red",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,11,"blue",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,12,"green",0), + + //scence + new_usr_v4l2menu(V4L2_CID_SCENE,0,"normal",0), + new_usr_v4l2menu(V4L2_CID_SCENE,1,"auto",0), + new_usr_v4l2menu(V4L2_CID_SCENE,2,"landscape",0), + new_usr_v4l2menu(V4L2_CID_SCENE,3,"night",0), + new_usr_v4l2menu(V4L2_CID_SCENE,4,"night_portrait",0), + new_usr_v4l2menu(V4L2_CID_SCENE,5,"snow",0), + new_usr_v4l2menu(V4L2_CID_SCENE,6,"sports",0), + new_usr_v4l2menu(V4L2_CID_SCENE,7,"candlelight",0), + + //antibanding + new_usr_v4l2menu(V4L2_CID_ANTIBANDING,0,"50hz",0), + new_usr_v4l2menu(V4L2_CID_ANTIBANDING,1,"60hz",0), + + //ISO + new_usr_v4l2menu(V4L2_CID_ISO,0,"auto",0), + new_usr_v4l2menu(V4L2_CID_ISO,1,"50",0), + new_usr_v4l2menu(V4L2_CID_ISO,2,"100",0), + new_usr_v4l2menu(V4L2_CID_ISO,3,"200",0), + new_usr_v4l2menu(V4L2_CID_ISO,4,"400",0), + new_usr_v4l2menu(V4L2_CID_ISO,5,"800",0), + new_usr_v4l2menu(V4L2_CID_ISO,6,"1600",0), +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ + new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 4, 1, 0,sensor_set_get_control_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER,"Brightness Control", -3, 2, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 12, 1, 5,sensor_set_get_control_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU,"Scene Control", 0, 7, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_ANTIBANDING,V4L2_CTRL_TYPE_MENU,"Antibanding Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_WHITEBALANCE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"WhiteBalanceLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"ExposureLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_METERING_AREAS,V4L2_CTRL_TYPE_INTEGER,"MeteringAreas Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_WDR,V4L2_CTRL_TYPE_BOOLEAN,"WDR Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EDGE,V4L2_CTRL_TYPE_BOOLEAN,"EDGE Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_JPEG_EXIF,V4L2_CTRL_TYPE_BOOLEAN,"Exif Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_ISO,V4L2_CTRL_TYPE_MENU,"Exif Control", 0, 6, 1, 0,sensor_set_get_control_cb, NULL), +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +/* +********************************************************** +* Following is callback +* If necessary, you could coding these callback +********************************************************** +*/ +/* +* the function is called in open sensor +*/ +static int sensor_activate_cb(struct i2c_client *client) +{ + return icatch_sensor_init(client); +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + + return 0; +} +/* +* the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + return icatch_s_fmt(client, mf,capture); +} +/* +* the function is called after sensor register setting finished in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 0; +} + +static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + return sensor->info_priv.chip_id[0]; +} +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("Suspend"); + + } else { + SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + + SENSOR_DG("Resume"); + + return 0; + +} +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + return 0; +} + +/* +* the function is v4l2 control V4L2_CID_VFLIP callback +*/ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + return 0; +} +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + return err; +} +static int sensor_mirror_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + return err; +} + +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client){ + + return 0; +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos) +{ + return 0; +} + +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){ + return 0; +} + +/* +* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some +* initialization in the function. +*/ +static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd) +{ + spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = icatch_s_stream; + spsensor->common_sensor.sensor_cb.sensor_enum_framesizes = icatch_enum_framesizes; + + spsensor->isp_priv_info.outputSize =OUTPUT_1080P|OUTPUT_QUADVGA; + spsensor->isp_priv_info.supportedSizeNum = 2; + spsensor->isp_priv_info.supportedSize[0] = OUTPUT_QUADVGA; + spsensor->isp_priv_info.supportedSize[1] = OUTPUT_1080P; + return; +} + +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); + + + + diff --git a/drivers/media/video/icatch7002/icatch7002_ov5693.c b/drivers/media/video/icatch7002/icatch7002_ov5693.c index 755d21b69283..d7094b9e2445 100755 --- a/drivers/media/video/icatch7002/icatch7002_ov5693.c +++ b/drivers/media/video/icatch7002/icatch7002_ov5693.c @@ -471,7 +471,7 @@ static int sensor_deactivate_cb(struct i2c_client *client) */ static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) { - return icatch_s_fmt(client, mf); + return icatch_s_fmt(client, mf,capture); } /* * the function is called after sensor register setting finished in VIDIOC_S_FMT diff --git a/drivers/media/video/icatch7002/icatch7002_ov8825.c b/drivers/media/video/icatch7002/icatch7002_ov8825.c new file mode 100755 index 000000000000..c31912fbc60c --- /dev/null +++ b/drivers/media/video/icatch7002/icatch7002_ov8825.c @@ -0,0 +1,639 @@ + +#include "icatch7002_common.h" +/* +* Driver Version Note +*v0.0.1: this driver is compatible with generic_sensor +*v0.0.3: +* add sensor_focus_af_const_pause_usr_cb; +*/ +static int version = KERNEL_VERSION(0,0,3); +module_param(version, int, S_IRUGO); + + + +static int debug; +module_param(debug, int, S_IRUGO|S_IWUSR); + +#define dprintk(level, fmt, arg...) do { \ + if (debug >= level) \ + printk(KERN_WARNING fmt , ## arg); } while (0) + +/* Sensor Driver Configuration Begin */ +#define SENSOR_NAME RK29_CAM_ISP_ICATCH7002_OV8825 +#define SENSOR_V4L2_IDENT V4L2_IDENT_ICATCH7002_OV8825 +#define SENSOR_ID 0x8825 +#define SENSOR_BUS_PARAM (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\ + SOCAM_HSYNC_ACTIVE_HIGH| SOCAM_VSYNC_ACTIVE_HIGH|\ + SOCAM_DATA_ACTIVE_HIGH|SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ) +#define SENSOR_PREVIEW_W 1280 +#define SENSOR_PREVIEW_H 960 +#define SENSOR_PREVIEW_FPS 30000 // 15fps +#define SENSOR_FULLRES_L_FPS 15000 // 7.5fps +#define SENSOR_FULLRES_H_FPS 15000 // 7.5fps +#define SENSOR_720P_FPS 30000 +#define SENSOR_1080P_FPS 0 + + +static unsigned int SensorConfiguration = CFG_Focus |CFG_FocusContinues|CFG_FocusZone; +static unsigned int SensorChipID[] = {SENSOR_ID}; +/* Sensor Driver Configuration End */ + + +#define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) +#define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) + +//#define SensorRegVal(a,b) CONS4(SensorReg,SENSOR_REGISTER_LEN,Val,SENSOR_VALUE_LEN)(a,b) +//#define sensor_write(client,reg,v) CONS4(sensor_write_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +//#define sensor_read(client,reg,v) CONS4(sensor_read_reg,SENSOR_REGISTER_LEN,val,SENSOR_VALUE_LEN)(client,(reg),(v)) +//#define sensor_write_array generic_sensor_write_array + + + +/* +* The follow setting need been filled. +* +* Must Filled: +* sensor_init_data : Sensor initial setting; +* sensor_fullres_lowfps_data : Sensor full resolution setting with best auality, recommand for video; +* sensor_preview_data : Sensor preview resolution setting, recommand it is vga or svga; +* sensor_softreset_data : Sensor software reset register; +* sensor_check_id_data : Sensir chip id register; +* +* Optional filled: +* sensor_fullres_highfps_data: Sensor full resolution setting with high framerate, recommand for video; +* sensor_720p: Sensor 720p setting, it is for video; +* sensor_1080p: Sensor 1080p setting, it is for video; +* +* :::::WARNING::::: +* The SensorEnd which is the setting end flag must be filled int the last of each setting; +*/ + +/* Sensor initial setting */ +static struct rk_sensor_reg sensor_init_data[] ={ + SensorStreamChk, + SensorEnd +}; +/* Senor full resolution setting: recommand for capture */ +static struct rk_sensor_reg sensor_fullres_lowfps_data[] ={ + SensorStreamChk, + SensorEnd + +}; + +/* Senor full resolution setting: recommand for video */ +static struct rk_sensor_reg sensor_fullres_highfps_data[] ={ + SensorEnd +}; +/* Preview resolution setting*/ +static struct rk_sensor_reg sensor_preview_data[] = +{ + SensorStreamChk, + SensorEnd +}; +/* 1280x720 */ +static struct rk_sensor_reg sensor_720p[]={ + SensorStreamChk, + SensorEnd +}; + +/* 1920x1080 */ +static struct rk_sensor_reg sensor_1080p[]={ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_softreset_data[]={ + SensorEnd +}; + +static struct rk_sensor_reg sensor_check_id_data[]={ + SensorEnd +}; +/* +* The following setting must been filled, if the function is turn on by CONFIG_SENSOR_xxxx +*/ +static struct rk_sensor_reg sensor_WhiteB_Auto[]= +{ + SensorEnd +}; +/* Cloudy Colour Temperature : 6500K - 8000K */ +static struct rk_sensor_reg sensor_WhiteB_Cloudy[]= +{ + SensorEnd +}; +/* ClearDay Colour Temperature : 5000K - 6500K */ +static struct rk_sensor_reg sensor_WhiteB_ClearDay[]= +{ + //Sunny + SensorEnd +}; +/* Office Colour Temperature : 3500K - 5000K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp1[]= +{ + //Office + SensorEnd + +}; +/* Home Colour Temperature : 2500K - 3500K */ +static struct rk_sensor_reg sensor_WhiteB_TungstenLamp2[]= +{ + //Home + SensorEnd +}; +static struct rk_sensor_reg *sensor_WhiteBalanceSeqe[] = {sensor_WhiteB_Auto, sensor_WhiteB_TungstenLamp1,sensor_WhiteB_TungstenLamp2, + sensor_WhiteB_ClearDay, sensor_WhiteB_Cloudy,NULL, +}; + +static struct rk_sensor_reg sensor_Brightness0[]= +{ + // Brightness -2 + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness1[]= +{ + // Brightness -1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness2[]= +{ + // Brightness 0 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness3[]= +{ + // Brightness +1 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness4[]= +{ + // Brightness +2 + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Brightness5[]= +{ + // Brightness +3 + + SensorEnd +}; +static struct rk_sensor_reg *sensor_BrightnessSeqe[] = {sensor_Brightness0, sensor_Brightness1, sensor_Brightness2, sensor_Brightness3, + sensor_Brightness4, sensor_Brightness5,NULL, +}; + +static struct rk_sensor_reg sensor_Effect_Normal[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_WandB[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Sepia[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Negative[] = +{ + //Negative + SensorEnd +}; +static struct rk_sensor_reg sensor_Effect_Bluish[] = +{ + // Bluish + SensorEnd +}; + +static struct rk_sensor_reg sensor_Effect_Green[] = +{ + // Greenish + SensorEnd +}; +static struct rk_sensor_reg *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effect_WandB, sensor_Effect_Negative,sensor_Effect_Sepia, + sensor_Effect_Bluish, sensor_Effect_Green,NULL, +}; + +static struct rk_sensor_reg sensor_Exposure0[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure1[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure2[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure3[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure4[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure5[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Exposure6[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3, + sensor_Exposure4, sensor_Exposure5,sensor_Exposure6,NULL, +}; + +static struct rk_sensor_reg sensor_Saturation0[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation1[]= +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Saturation2[]= +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_SaturationSeqe[] = {sensor_Saturation0, sensor_Saturation1, sensor_Saturation2, NULL,}; + +static struct rk_sensor_reg sensor_Contrast0[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast1[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast2[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast3[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast4[]= +{ + + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Contrast5[]= +{ + + SensorEnd +}; + +static struct rk_sensor_reg sensor_Contrast6[]= +{ + + SensorEnd +}; +static struct rk_sensor_reg *sensor_ContrastSeqe[] = {sensor_Contrast0, sensor_Contrast1, sensor_Contrast2, sensor_Contrast3, + sensor_Contrast4, sensor_Contrast5, sensor_Contrast6, NULL, +}; +static struct rk_sensor_reg sensor_SceneAuto[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_SceneNight[] = +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_SceneSeqe[] = {sensor_SceneAuto, sensor_SceneNight,NULL,}; + +static struct rk_sensor_reg sensor_Zoom0[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom1[] = +{ + SensorEnd +}; + +static struct rk_sensor_reg sensor_Zoom2[] = +{ + SensorEnd +}; + + +static struct rk_sensor_reg sensor_Zoom3[] = +{ + SensorEnd +}; +static struct rk_sensor_reg *sensor_ZoomSeqe[] = {sensor_Zoom0, sensor_Zoom1, sensor_Zoom2, sensor_Zoom3, NULL,}; + +/* +* User could be add v4l2_querymenu in sensor_controls by new_usr_v4l2menu +*/ +static struct v4l2_querymenu sensor_menus[] = +{ + //white balance + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,0,"auto",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,1,"incandescent",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,2,"fluorescent",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,3,"daylight",0), + new_usr_v4l2menu(V4L2_CID_DO_WHITE_BALANCE,4,"cloudy-daylight",0), + + //speical effect + new_usr_v4l2menu(V4L2_CID_EFFECT,0,"normal",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,1,"aqua",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,2,"negative",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,3,"sepia",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,4,"mono",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,5,"none",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,6,"aura",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,7,"vintage",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,8,"vintage2",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,9,"lomo",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,10,"red",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,11,"blue",0), + new_usr_v4l2menu(V4L2_CID_EFFECT,12,"green",0), + + //scence + new_usr_v4l2menu(V4L2_CID_SCENE,0,"normal",0), + new_usr_v4l2menu(V4L2_CID_SCENE,1,"auto",0), + new_usr_v4l2menu(V4L2_CID_SCENE,2,"landscape",0), + new_usr_v4l2menu(V4L2_CID_SCENE,3,"night",0), + new_usr_v4l2menu(V4L2_CID_SCENE,4,"night_portrait",0), + new_usr_v4l2menu(V4L2_CID_SCENE,5,"snow",0), + new_usr_v4l2menu(V4L2_CID_SCENE,6,"sports",0), + new_usr_v4l2menu(V4L2_CID_SCENE,7,"candlelight",0), + + //antibanding + new_usr_v4l2menu(V4L2_CID_ANTIBANDING,0,"50hz",0), + new_usr_v4l2menu(V4L2_CID_ANTIBANDING,1,"60hz",0), + + //ISO + new_usr_v4l2menu(V4L2_CID_ISO,0,"auto",0), + new_usr_v4l2menu(V4L2_CID_ISO,1,"50",0), + new_usr_v4l2menu(V4L2_CID_ISO,2,"100",0), + new_usr_v4l2menu(V4L2_CID_ISO,3,"200",0), + new_usr_v4l2menu(V4L2_CID_ISO,4,"400",0), + new_usr_v4l2menu(V4L2_CID_ISO,5,"800",0), + new_usr_v4l2menu(V4L2_CID_ISO,6,"1600",0), +}; +/* +* User could be add v4l2_queryctrl in sensor_controls by new_user_v4l2ctrl +*/ +static struct sensor_v4l2ctrl_usr_s sensor_controls[] = +{ + new_user_v4l2ctrl(V4L2_CID_DO_WHITE_BALANCE,V4L2_CTRL_TYPE_MENU,"White Balance Control", 0, 4, 1, 0,sensor_set_get_control_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_BRIGHTNESS,V4L2_CTRL_TYPE_INTEGER,"Brightness Control", -3, 2, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE,V4L2_CTRL_TYPE_INTEGER,"Exposure Control", -3, 3, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EFFECT,V4L2_CTRL_TYPE_MENU,"Effect Control", 0, 12, 1, 5,sensor_set_get_control_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_CONTRAST,V4L2_CTRL_TYPE_INTEGER,"Contrast Control", -4, 4, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_SCENE,V4L2_CTRL_TYPE_MENU,"Scene Control", 0, 7, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_ANTIBANDING,V4L2_CTRL_TYPE_MENU,"Antibanding Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_WHITEBALANCE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"WhiteBalanceLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EXPOSURE_LOCK,V4L2_CTRL_TYPE_BOOLEAN,"ExposureLock Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_METERING_AREAS,V4L2_CTRL_TYPE_INTEGER,"MeteringAreas Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_WDR,V4L2_CTRL_TYPE_BOOLEAN,"WDR Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_EDGE,V4L2_CTRL_TYPE_BOOLEAN,"EDGE Control", 0, 1, 1, 1,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_JPEG_EXIF,V4L2_CTRL_TYPE_BOOLEAN,"Exif Control", 0, 1, 1, 0,sensor_set_get_control_cb, NULL), + new_user_v4l2ctrl(V4L2_CID_ISO,V4L2_CTRL_TYPE_MENU,"Exif Control", 0, 6, 1, 0,sensor_set_get_control_cb, NULL), + +// new_user_v4l2ctrl(V4L2_CID_FOCUSZONE,V4L2_CTRL_TYPE_BOOLEAN,"FocusZone Control", 0, 1, 1, 1,sensor_focus_default_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_FOCUS_ABSOLUTE,V4L2_CTRL_TYPE_INTEGER,"Focus Control", 0, 0xff, 1, 0,sensor_focus_default_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_FOCUS_AUTO,V4L2_CTRL_TYPE_BOOLEAN,"Focus Control", 0, 1, 1, 0,sensor_focus_default_cb, NULL), +// new_user_v4l2ctrl(V4L2_CID_FOCUS_CONTINUOUS,V4L2_CTRL_TYPE_BOOLEAN,"Focus Control", 0, 1, 1, 0,sensor_focus_default_cb, NULL), +}; + +//MUST define the current used format as the first item +static struct rk_sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} +}; + + +/* +********************************************************** +* Following is local code: +* +* Please codeing your program here +********************************************************** +*/ +/* +********************************************************** +* Following is callback +* If necessary, you could coding these callback +********************************************************** +*/ +/* +* the function is called in open sensor +*/ +static int sensor_activate_cb(struct i2c_client *client) +{ + return icatch_sensor_init(client); +} +/* +* the function is called in close sensor +*/ +static int sensor_deactivate_cb(struct i2c_client *client) +{ + + return 0; +} +/* +* the function is called before sensor register setting in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + return icatch_s_fmt(client, mf,capture); +} +/* +* the function is called after sensor register setting finished in VIDIOC_S_FMT +*/ +static int sensor_s_fmt_cb_bh (struct i2c_client *client,struct v4l2_mbus_framefmt *mf, bool capture) +{ + return 0; +} +static int sensor_try_fmt_cb_th(struct i2c_client *client,struct v4l2_mbus_framefmt *mf) +{ + return 0; +} + +static int sensor_softrest_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + + return 0; +} +static int sensor_check_id_usr_cb(struct i2c_client *client,struct rk_sensor_reg *series) +{ + struct generic_sensor *sensor = to_generic_sensor(client); + return sensor->info_priv.chip_id[0]; +} +static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg) +{ + //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + + if (pm_msg.event == PM_EVENT_SUSPEND) { + SENSOR_DG("Suspend"); + + } else { + SENSOR_TR("pm_msg.event(0x%x) != PM_EVENT_SUSPEND\n",pm_msg.event); + return -EINVAL; + } + return 0; +} + +static int sensor_resume(struct soc_camera_device *icd) +{ + + SENSOR_DG("Resume"); + + return 0; + +} +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ +static int sensor_v4l2ctrl_mirror_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + return 0; +} + +/* +* the function is v4l2 control V4L2_CID_VFLIP callback +*/ +static int sensor_v4l2ctrl_flip_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + return 0; +} +/* +* the function is v4l2 control V4L2_CID_HFLIP callback +*/ + +static int sensor_flip_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + return err; +} +static int sensor_mirror_cb(struct i2c_client *client, int flip) +{ + int err = 0; + + return err; +} + +/* +* the functions are focus callbacks +*/ +static int sensor_focus_init_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_single_usr_cb(struct i2c_client *client){ + return icatch_sensor_set_auto_focus(client, WqCmd_af_single,NULL); +} + +static int sensor_focus_af_near_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_far_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_specialpos_usr_cb(struct i2c_client *client,int pos){ + return 0; +} + +static int sensor_focus_af_const_usr_cb(struct i2c_client *client){ + + return icatch_sensor_set_auto_focus(client, WqCmd_af_continues,NULL); +} +static int sensor_focus_af_const_pause_usr_cb(struct i2c_client *client) +{ + return 0; +} +static int sensor_focus_af_close_usr_cb(struct i2c_client *client){ + return 0; +} + +static int sensor_focus_af_zoneupdate_usr_cb(struct i2c_client *client, int *zone_tm_pos) +{ + return icatch_sensor_set_auto_focus(client, WqCmd_af_update_zone,zone_tm_pos); +} + +/* +face defect call back +*/ +static int sensor_face_detect_usr_cb(struct i2c_client *client,int on){ + return 0; +} + +/* +* The function can been run in sensor_init_parametres which run in sensor_probe, so user can do some +* initialization in the function. +*/ +static void sensor_init_parameters_user(struct specific_sensor* spsensor,struct soc_camera_device *icd) +{ + spsensor->common_sensor.sensor_cb.sensor_s_stream_cb = icatch_s_stream; + spsensor->isp_priv_info.focus_zone.lx = 256; + spsensor->isp_priv_info.focus_zone.rx = 768; + spsensor->isp_priv_info.focus_zone.ty = 256; + spsensor->isp_priv_info.focus_zone.dy = 768; + spsensor->common_sensor.sensor_cb.sensor_enum_framesizes = icatch_enum_framesizes; + + spsensor->isp_priv_info.outputSize = OUTPUT_QUXGA|OUTPUT_QUADVGA; + spsensor->isp_priv_info.supportedSizeNum = 2; + spsensor->isp_priv_info.supportedSize[0] = OUTPUT_QUADVGA; + spsensor->isp_priv_info.supportedSize[1] = OUTPUT_QUXGA; + return; +} + +/* +* :::::WARNING::::: +* It is not allowed to modify the following code +*/ + +sensor_init_parameters_default_code(); + +sensor_v4l2_struct_initialization(); + +sensor_probe_default_code(); + +sensor_remove_default_code(); + +sensor_driver_default_module_code(); + + + + diff --git a/drivers/media/video/rk30_camera.c b/drivers/media/video/rk30_camera.c index 9fbf07b9a4e0..f65ea0baf039 100755 --- a/drivers/media/video/rk30_camera.c +++ b/drivers/media/video/rk30_camera.c @@ -958,7 +958,7 @@ static void rk30_camera_request_reserve_mem(void) case 0x800000: default: { - cam_ipp_mem = 0x800000; + cam_ipp_mem = 0xC00000; cam_pmem = 0x1900000; break; } @@ -983,7 +983,12 @@ static void rk30_camera_request_reserve_mem(void) cam_pmem = 0xc00000; break; } - + case 0x210000: + { + cam_ipp_mem = 0xc00000; + cam_pmem = 0xc00000; + break; + } case 0x100000: { cam_ipp_mem = 0x600000; diff --git a/drivers/media/video/rk30_camera_pingpong.c b/drivers/media/video/rk30_camera_pingpong.c index a5669ef193da..d24a0b7b0fa7 100755 --- a/drivers/media/video/rk30_camera_pingpong.c +++ b/drivers/media/video/rk30_camera_pingpong.c @@ -426,6 +426,13 @@ struct rk_hdr_info_s bool en; struct hdr_exposure frame[3]; }; +struct rk_cif_crop +{ + spinlock_t lock; + struct v4l2_rect c; + struct v4l2_rect bounds; +}; + #define CONFIG_CIF_STOP_SYNC 1 struct rk_camera_dev @@ -468,6 +475,7 @@ struct rk_camera_dev int hostid; int icd_width; int icd_height; + struct rk_cif_crop cropinfo; struct rk29camera_platform_data *pdata; struct resource *res; @@ -536,7 +544,7 @@ static const char *rk_cam_driver_description = "RK_Camera"; static int rk_camera_s_stream(struct soc_camera_device *icd, int enable); static void rk_camera_capture_process(struct work_struct *work); -#define OPTIMIZE_MEMORY_USE +// #define OPTIMIZE_MEMORY_USE /* * Videobuf operations @@ -1792,6 +1800,9 @@ static int rk_camera_add_device(struct soc_camera_device *icd) struct v4l2_subdev *sd; int ret,i,icd_catch; struct rk_camera_frmivalenum *fival_list,*fival_nxt; + struct v4l2_cropcap cropcap; + struct v4l2_mbus_framefmt mf; + const struct soc_camera_format_xlate *xlate = NULL; mutex_lock(&camera_lock); @@ -1828,6 +1839,23 @@ static int rk_camera_add_device(struct soc_camera_device *icd) goto ebusy; #endif v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb)); + + if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) { + memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect)); + } else { + xlate = soc_camera_xlate_by_fourcc(icd, V4L2_PIX_FMT_NV12); + mf.width = 10000; + mf.height = 10000; + mf.field = V4L2_FIELD_NONE; + mf.code = xlate->code; + mf.reserved[6] = 0xfefe5a5a; + v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + + pcdev->cropinfo.bounds.left = 0; + pcdev->cropinfo.bounds.top = 0; + pcdev->cropinfo.bounds.width = mf.width; + pcdev->cropinfo.bounds.height = mf.height; + } } pcdev->icd = icd; pcdev->icd_init = 0; @@ -2309,7 +2337,17 @@ static void rk_camera_put_formats(struct soc_camera_device *icd) { return; } +static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop) +{ + struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent); + struct rk_camera_dev *pcdev = ici->priv; + spin_lock(&pcdev->cropinfo.lock); + memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect)); + spin_unlock(&pcdev->cropinfo.lock); + + return 0; +} static int rk_camera_set_crop(struct soc_camera_device *icd, struct v4l2_crop *a) { @@ -2355,12 +2393,14 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_mbus_framefmt mf; struct v4l2_rect rect; - int ret,usr_w,usr_h; + int ret,usr_w,usr_h,sensor_w,sensor_h; int stream_on = 0; - + int ratio, bounds_aspect; + usr_w = pix->width; usr_h = pix->height; - RK30_CAM_DEBUG_TRACE("%s enter width:%d height:%d\n",__FUNCTION__,usr_w,usr_h); + + RK30_CAM_DEBUG_TRACE("enter width:%d height:%d\n",usr_w,usr_h); xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { dev_err(dev, "Format %x not found\n", pix->pixelformat); @@ -2377,125 +2417,183 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd, 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 + + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + mf.reserved[0] = pix->priv; /* ddl@rock-chips.com : v0.3.3 */ + mf.reserved[1] = 0; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + if (mf.code != xlate->code) + return -EINVAL; + + if ((pcdev->cropinfo.c.width == pcdev->cropinfo.bounds.width) && + (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) { + bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height); + if ((mf.width*10/mf.height) != bounds_aspect) { + RK30_CAM_DEBUG_TRACE("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n", + usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height); + + mf.width = pcdev->cropinfo.bounds.width/4; + mf.height = pcdev->cropinfo.bounds.height/4; + + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + mf.reserved[0] = pix->priv; + mf.reserved[1] = 0; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + if (mf.code != xlate->code) + return -EINVAL; + } + } + + sensor_w = mf.width; + sensor_h = mf.height; + + ratio = ((mf.width*mf.reserved[1])/100)&(~0x03); // 4 align + mf.width -= ratio; + + ratio = ((ratio*mf.height/mf.width)+1)&(~0x01); // 2 align + mf.height -= ratio; + 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))) { - RK30_CAM_DEBUG_TRACE("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))) { - RK30_CAM_DEBUG_TRACE("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((mf.width*10/mf.height) != (usr_w*10/usr_h)) { - ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w); - pcdev->host_width = ratio*usr_w/10; - pcdev->host_height = ratio*usr_h/10; - //for ipp ,need 4 bit alligned. - pcdev->host_width &= ~CROP_ALIGN_BYTES; - pcdev->host_height &= ~CROP_ALIGN_BYTES; - RK30_CAM_DEBUG_TRACE("ratio = %d ,host:%d*%d\n",ratio,pcdev->host_width,pcdev->host_height); - } - else { // needn't crop ,just scaled by ipp - pcdev->host_width = mf.width; - pcdev->host_height = mf.height; - } - } - else { - pcdev->host_width = usr_w; - pcdev->host_height = usr_h; - } - #else - //according to crop and scale capability to change , here just cropt to user needed + if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) { - RK30_CAM_DEBUG_TRACE("Senor invalid source resolution(%dx%d)\n",mf.width,mf.height); + 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))) { - RK30_CAM_DEBUG_TRACE("Senor invalid destination resolution(%dx%d)\n",usr_w,usr_h); + RKCAMERA_TR("Senor and IPP both invalid destination resolution(%dx%d)\n",usr_w,usr_h); ret = -EINVAL; goto RK_CAMERA_SET_FMT_END; - } - pcdev->host_width = usr_w; - pcdev->host_height = usr_h; - #endif + } + + spin_lock(&pcdev->cropinfo.lock); + if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) { + if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) { + //Scale + Crop center is for keep aspect ratio unchange + ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w); + pcdev->host_width = ratio*usr_w/10; + pcdev->host_height = ratio*usr_h/10; + pcdev->host_width &= ~CROP_ALIGN_BYTES; + pcdev->host_height &= ~CROP_ALIGN_BYTES; + + pcdev->host_left = ((sensor_w-pcdev->host_width )>>1); + pcdev->host_top = ((sensor_h-pcdev->host_height)>>1); + } else { + //Scale + crop(user define) + pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width; + pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height; + pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width); + pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height); + } + + pcdev->host_left &= (~0x01); + pcdev->host_top &= (~0x01); + } else { + if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) { + //Crop Center for cif can work , then scale + pcdev->host_width = mf.width; + pcdev->host_height = mf.height; + pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01); + pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01); + } else { + //Crop center for cif can work + crop(user define), then scale + pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width; + pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height; + pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1); + pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height)+((sensor_h - mf.height)>>1); + } + + pcdev->host_left &= (~0x01); + pcdev->host_top &= (~0x01); + } + spin_unlock(&pcdev->cropinfo.lock); + } else { + spin_lock(&pcdev->cropinfo.lock); + if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) { + pcdev->host_width = mf.width; + pcdev->host_height = mf.height; + pcdev->host_left = 0; + pcdev->host_top = 0; + } else { + pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width; + pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height; + pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width); + pcdev->host_top = (pcdev->cropinfo.c.top*mf.height/pcdev->cropinfo.bounds.height); + } + spin_unlock(&pcdev->cropinfo.lock); + } + icd->sense = NULL; if (!ret) { - RK30_CAM_DEBUG_TRACE("%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); rect.width = pcdev->host_width; rect.height = pcdev->host_height; - 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 = pcdev->host_left; + rect.top = pcdev->host_top; down(&pcdev->zoominfo.sem); - #if CIF_DO_CROP - pcdev->zoominfo.a.c.left = 0; - pcdev->zoominfo.a.c.top = 0; - pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate; - pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; - pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate; - pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES; - pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width; - pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height; - //recalculate the CIF width & height - rect.width = pcdev->zoominfo.a.c.width ; - rect.height = pcdev->zoominfo.a.c.height; - rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01); - rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01); - #else - pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate; - pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; - pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate; - pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES; - //now digital zoom use ipp to do crop and scale - if(pcdev->zoominfo.zoom_rate != 100) { - pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01); - pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01); - } - else { - pcdev->zoominfo.a.c.left = 0; - pcdev->zoominfo.a.c.top = 0; - } - pcdev->zoominfo.vir_width = pcdev->host_width; - pcdev->zoominfo.vir_height = pcdev->host_height; - #endif +#if CIF_DO_CROP // this crop is only for digital zoom + pcdev->zoominfo.a.c.left = 0; + pcdev->zoominfo.a.c.top = 0; + pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; + pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES; + pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width; + pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height; + //recalculate the CIF width & height + rect.width = pcdev->zoominfo.a.c.width ; + rect.height = pcdev->zoominfo.a.c.height; + rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01); + rect.top = ((((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1))+pcdev->host_top)&(~0x01); +#else + pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES; + pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate; + pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES; + //now digital zoom use ipp to do crop and scale + if(pcdev->zoominfo.zoom_rate != 100){ + pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01); + pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01); + } else { + pcdev->zoominfo.a.c.left = 0; + pcdev->zoominfo.a.c.top = 0; + } + pcdev->zoominfo.vir_width = pcdev->host_width; + pcdev->zoominfo.vir_height = pcdev->host_height; +#endif 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)) { - RK30_CAM_DEBUG_TRACE("IPP Destination resolution(%dx%d, ((%d div 1) mod 64)=%d is <= 8)",usr_w,usr_h, usr_w, (int)((usr_w>>1)&0x3f)); + 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)) { - RK30_CAM_DEBUG_TRACE("IPP Destination resolution(%dx%d, %d mod 64=%d is <= 8)",usr_w,usr_h, usr_w, (int)(usr_w&0x3f)); + 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; } } } - RK30_CAM_DEBUG_TRACE("%s..%s icd width:%d user 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, + + RK30_CAM_DEBUG_TRACE("%s CIF Host:%dx%d@(%d,%d) Sensor:%dx%d->%dx%d User crop:(%d,%d,%d,%d)in(%d,%d) (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name, + pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top, + sensor_w,sensor_h,mf.width,mf.height, + pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height, + pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height, + 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); @@ -2515,7 +2613,7 @@ 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) - RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); + RKCAMERA_TR("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret); return ret; } static bool rk_camera_fmt_capturechk(struct v4l2_format *f) @@ -2716,7 +2814,7 @@ static int rk_camera_querycap(struct soc_camera_host *ici, char fov[9]; int i; - strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18); + strlcpy(cap->card, dev_name(pcdev->icd->pdev), 20); memset(orientation,0x00,sizeof(orientation)); for (i=0; ipdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) { @@ -3470,7 +3568,9 @@ static int rk_camera_probe(struct platform_device *pdev) INIT_LIST_HEAD(&pcdev->camera_work_queue); spin_lock_init(&pcdev->lock); spin_lock_init(&pcdev->camera_work_lock); - // spin_lock_init(&pcdev->irq_lock); + + memset(&pcdev->cropinfo.c,0x00,sizeof(struct v4l2_rect)); + spin_lock_init(&pcdev->cropinfo.lock); sema_init(&pcdev->zoominfo.sem,1); /* diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 5badba86d035..5ea6fdbb56d8 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -369,6 +369,7 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, b->timestamp = vb->ts; b->bytesused = vb->size; b->sequence = vb->field_count >> 1; + b->reserved = vb->rk_code; /* ddl@rock-chips.com */ } int videobuf_mmap_free(struct videobuf_queue *q) diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 96d18ce42224..46766b61a804 100755 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -95,6 +95,8 @@ enum { V4L2_IDENT_MTK9335ISP = 320, /* ddl@rock-chips.com : MTK9335ISP support */ V4L2_IDENT_ICATCH7002_MI1040 = 321, V4L2_IDENT_ICATCH7002_OV5693 =322, + V4L2_IDENT_ICATCH7002_OV8825 = 323, //zyt + V4L2_IDENT_ICATCH7002_OV2720 = 324, //zyt /* Conexant MPEG encoder/decoders: reserved range 400-420 */ V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */ V4L2_IDENT_CX23415 = 415, diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 455ba9384e42..b02caa9088c2 100755 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -111,6 +111,7 @@ struct videobuf_buffer { struct rk29_vaddr vaddr; #endif void *priv; + unsigned int rk_code; /* ddl@rock-chips.com: this filed must copy to struct v4l2_buffer.reserved */ }; struct videobuf_queue_ops {