camera: add ov8825,ov2720 dirver for icatch7002.

This commit is contained in:
zyc
2013-10-16 16:06:11 +08:00
parent 7cc20c8709
commit e2f94931cd
15 changed files with 1566 additions and 114 deletions

View File

@@ -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))

View File

@@ -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:
{

View File

@@ -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"

View File

@@ -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

View File

@@ -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());

View File

@@ -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
};

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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();

View File

@@ -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;

View File

@@ -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);
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 and IPP both 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;
}
//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);
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);
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; i<RK_CAM_NUM;i++) {
if ((pcdev->pdata->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);
/*

View File

@@ -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)

View File

@@ -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,

View File

@@ -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 {