⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ov5640.c

📁 linux下ov5640驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            reg3a11 = 0x30;            break;        case -3:  /* -1.0EV */            reg3a11 = 0x41;            break;        case -2:  /* -0.7EV */            reg3a11 = 0x51;            break;        case -1:  /* -0.3EV */            reg3a11 = 0x61;            break;        case 0:  /* 0EV, default */            reg3a11 = 0x61;            break;        case 1:  /* 0.3EV */            reg3a11 = 0x71;            break;        case 2:  /* 0.7EV */            reg3a11 = 0x80;            reg3a1f = 0x20;            break;        case 3:  /* 1.0EV */            reg3a11 = 0x90;            reg3a1f = 0x20;            break;        case 4:  /* 1.3EV */            reg3a11 = 0x91;            reg3a1f = 0x20;            break;        case 5:  /* 1.7EV */            reg3a11 = 0xa0;            reg3a1f = 0x20;            break;        default:            OV_ERR("exposure - %d is out of range[-5, 5]\n", level);            return (-ERANGE);    }    OV_INFO("exposure: %d, 0x3a0f:0x%x, 0x3a10:0x%x\n", level, reg3a0f, reg3a10);    //OV_INFO("0x3a1b:0x%x, 0x3a1e:0x%x\n", reg3a1b, reg3a1e);    OV_INFO("0x3a11:0x%x, 0x3a1f:0x%x\n\n", reg3a11, reg3a1f);    i2cc_set_reg(client, 0x3a0f, reg3a0f);  /* stable range high limit(enter) */    i2cc_set_reg(client, 0x3a10, reg3a10);  /* stable range low limit(enter) */    i2cc_set_reg(client, 0x3a11, reg3a11);  /* fast zone high limit */    i2cc_set_reg(client, 0x3a1b, reg3a1b);  /* stable range high limit(go out) */    i2cc_set_reg(client, 0x3a1e, reg3a1e);  /* stable range low limit(go out) */    i2cc_set_reg(client, 0x3a1f, reg3a1f);  /* fast zone low limit */    priv->exposure = level;        return (0);}#define OV5640_FLIP_VAL  ((unsigned char)0x06)#define OV5640_FLIP_MASK (~(OV5640_FLIP_VAL))static int ov5640_set_flip(struct i2c_client *client, struct v4l2_control *ctrl){    struct ov5640_priv *priv = to_ov5640(client);    unsigned char reg3820, reg3821;    OV_INFO("old flag: %d\n", priv->flip_flag);        switch (ctrl->id) {        case V4L2_CID_HFLIP:            if (ctrl->value) {                priv->flip_flag |= OV5640_HFLIP;            } else {                priv->flip_flag &= ~OV5640_HFLIP;            }            break;	    case V4L2_CID_VFLIP:            if (ctrl->value) {                priv->flip_flag |= OV5640_VFLIP;            } else {                priv->flip_flag &= ~OV5640_VFLIP;            }            break;        default:            OV_ERR("set flip out of range\n");            return (-ERANGE);    }    OV_INFO("new flag: %d\n", priv->flip_flag);    i2cc_get_reg(client, 0x3820, &reg3820);    i2cc_get_reg(client, 0x3821, &reg3821);        if (priv->flip_flag & OV5640_VFLIP) {        reg3820 |= OV5640_FLIP_VAL;    } else {        reg3820 &= OV5640_FLIP_MASK;    }        if (priv->flip_flag & OV5640_HFLIP) {        reg3821 |= OV5640_FLIP_VAL;    } else {        reg3821 &= OV5640_FLIP_MASK;    }    /* have a bug which flip a half picture only. */    //i2cc_set_reg(client, 0x3212, 0x00);   /* enable group0, when add no flip */    i2cc_set_reg(client, 0x3820, reg3820);     i2cc_set_reg(client, 0x3821, reg3821);    //i2cc_set_reg(client, 0x3212, 0x10);   /* end group0 */    //i2cc_set_reg(client, 0x3212, 0xa1);   /* launch group1 */    OV_INFO("0x3820:0x%x, 0x3821:0x%x\n", reg3820, reg3821);        return (0);}static int ov5640_set_sharpness(struct i2c_client *client, int sharp){    struct ov5640_priv *priv = to_ov5640(client);    unsigned char reg5302;    switch (sharp) {        case -1:  /*auto sharpness*/            break;        case 0:   /* sharpness off */            reg5302 = 0x00;            break;        case 1:            reg5302 = 0x02;            break;        case 2:            reg5302 = 0x04;            break;        case 3:            reg5302 = 0x08;            break;        case 4:            reg5302 = 0x0c;            break;        case 5:            reg5302 = 0x10;            break;        case 6:            reg5302 = 0x14;            break;        case 7:            reg5302 = 0x18;            break;        case 8:            reg5302 = 0x20;            break;        default:            OV_ERR("set sharpness is out of range - %d[-1,8]\n", sharp);            return (-ERANGE);    }    if (0 <= sharp) {        i2cc_set_reg(client, 0x5308, 0x65);        i2cc_set_reg(client, 0x5302, reg5302);        OV_INFO("sharp:%d, 5302:0x%x\n", sharp, reg5302);    } else {        const struct regval ov5640_auto_sharpness[] = {            {0x5308, 0x25},            {0x5300, 0x08},            {0x5301, 0x30},            {0x5302, 0x10},            {0x5303, 0x00},            {0x5309, 0x08},            {0x530a, 0x30},            {0x530b, 0x04},            {0x530c, 0x06},        };        int len = ARRAY_SIZE(ov5640_auto_sharpness);        write_regs(client, ov5640_auto_sharpness, len);        OV_INFO("sharp:%d, len:%d\n", sharp, len);    }    priv->sharpness = sharp;        return (0);}static int ov5640_set_colorfx(struct i2c_client *client, int effect){    struct ov5640_priv *priv = to_ov5640(client);    unsigned char reg5583, reg5584, reg5001, reg5580;    reg5001 = 0xff;    reg5580 = 0x18;    switch (effect) {        case 0: /* normal */            reg5001 = 0x7f;            reg5580 = 0x00;            break;        case 1: /* black and white */            reg5583 = 0x80;            reg5584 = 0x80;            break;        case 2: /* sepia , antique */            reg5583 = 0x40;            reg5584 = 0xa0;            break;        case 3: /* negative */            reg5001 = 0xff;            reg5580 = 0x40;            break;        case 4: /* bluish */            reg5583 = 0xa0;            reg5584 = 0x40;            break;        case 5: /* greenish */            reg5583 = 0x60;            reg5584 = 0x60;            break;        case 6: /* reddish */            reg5583 = 0x80;            reg5584 = 0xc0;            break;        default:            OV_ERR("set color effects out of range - %d[0,6]\n", effect);            return (-ERANGE);    }    i2cc_set_reg(client, 0x5001, reg5001);    i2cc_set_reg(client, 0x5580, reg5580);    OV_INFO("effect:%d, 0x5001:0x%x, 0x5580:0x%x\n", effect, reg5001, reg5580);    if (0 != effect && 3 != effect) {        i2cc_set_reg(client, 0x5583, reg5583);        i2cc_set_reg(client, 0x5584, reg5584);         OV_INFO("0x5583:0x%x, 0x5584:0x%x\n", reg5583, reg5584);    }    priv->colorfx = effect;    return (0);}/* Must be sorted from low to high control ID! */static const u32 ov5640_user_ctrls[] = {	V4L2_CID_USER_CLASS,	V4L2_CID_BRIGHTNESS,	V4L2_CID_CONTRAST,	V4L2_CID_SATURATION,	V4L2_CID_HUE,//	V4L2_CID_BLACK_LEVEL,	V4L2_CID_AUTO_WHITE_BALANCE,//	V4L2_CID_DO_WHITE_BALANCE,//	V4L2_CID_RED_BALANCE,//	V4L2_CID_BLUE_BALANCE,//	V4L2_CID_GAMMA,	V4L2_CID_EXPOSURE,	V4L2_CID_AUTOGAIN,	V4L2_CID_GAIN,	V4L2_CID_HFLIP,	V4L2_CID_VFLIP,	V4L2_CID_POWER_LINE_FREQUENCY,//	V4L2_CID_HUE_AUTO,	V4L2_CID_WHITE_BALANCE_TEMPERATURE,	V4L2_CID_SHARPNESS,//	V4L2_CID_BACKLIGHT_COMPENSATION,//	V4L2_CID_CHROMA_AGC,//	V4L2_CID_CHROMA_GAIN,//	V4L2_CID_COLOR_KILLER,	V4L2_CID_COLORFX,//	V4L2_CID_AUTOBRIGHTNESS,	V4L2_CID_BAND_STOP_FILTER,//	V4L2_CID_ROTATE,//	V4L2_CID_BG_COLOR,	0,};static const u32 ov5640_camera_ctrls[] = {	V4L2_CID_CAMERA_CLASS,	V4L2_CID_EXPOSURE_AUTO,//	V4L2_CID_EXPOSURE_ABSOLUTE,//	V4L2_CID_EXPOSURE_AUTO_PRIORITY,//	V4L2_CID_PAN_RELATIVE,//	V4L2_CID_TILT_RELATIVE,//	V4L2_CID_PAN_RESET,//	V4L2_CID_TILT_RESET,//	V4L2_CID_PAN_ABSOLUTE,//	V4L2_CID_TILT_ABSOLUTE,//	V4L2_CID_FOCUS_ABSOLUTE,//	V4L2_CID_FOCUS_RELATIVE,//	V4L2_CID_FOCUS_AUTO,//	V4L2_CID_ZOOM_ABSOLUTE,//	V4L2_CID_ZOOM_RELATIVE,//	V4L2_CID_ZOOM_CONTINUOUS,//	V4L2_CID_IRIS_ABSOLUTE,//	V4L2_CID_IRIS_RELATIVE,//	V4L2_CID_PRIVACY,	V4L2_CID_SCENE_EXPOSURE,	0,};static const u32 *ov5640_ctrl_classes[] = {	ov5640_user_ctrls,	ov5640_camera_ctrls,	NULL,};static int ov5640_queryctrl(struct v4l2_subdev *sd,		struct v4l2_queryctrl *qc){	//struct i2c_client *client = v4l2_get_subdevdata(sd);	qc->id = v4l2_ctrl_next(ov5640_ctrl_classes, qc->id);	if (qc->id == 0) {		return (-EINVAL);	}    OV_INFO("%s: id-%s\n", __func__, v4l2_ctrl_get_name(qc->id));	/* Fill in min, max, step and default value for these controls. */	switch (qc->id) {	/* Standard V4L2 controls */	case V4L2_CID_USER_CLASS:		return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);	case V4L2_CID_BRIGHTNESS:		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 0);	case V4L2_CID_CONTRAST:		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 0);	case V4L2_CID_SATURATION:		return v4l2_ctrl_query_fill(qc, -4, 4, 1, 0);	case V4L2_CID_HUE:		return v4l2_ctrl_query_fill(qc, -180, 150, 30, 0);#if 0//	case V4L2_CID_BLACK_LEVEL:	case V4L2_CID_AUTO_WHITE_BALANCE:		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);//	case V4L2_CID_DO_WHITE_BALANCE://	case V4L2_CID_RED_BALANCE://	case V4L2_CID_BLUE_BALANCE://	case V4L2_CID_GAMMA:#endif	case V4L2_CID_EXPOSURE:		return v4l2_ctrl_query_fill(qc, -5, 5, 1, 0);#if 0	case V4L2_CID_AUTOGAIN:		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);	case V4L2_CID_GAIN:		return v4l2_ctrl_query_fill(qc, 0, 0xFFU, 1, 128);#endif	case V4L2_CID_HFLIP:	case V4L2_CID_VFLIP:		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);#if 0	case V4L2_CID_POWER_LINE_FREQUENCY:		return v4l2_ctrl_query_fill(qc, 0, 2, 1, 1);//	case V4L2_CID_HUE_AUTO:	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:		return v4l2_ctrl_query_fill(qc, 0, 3, 1, 0);#endif	case V4L2_CID_SHARPNESS:		return v4l2_ctrl_query_fill(qc, -1, 8, 1, -1);//	case V4L2_CID_BACKLIGHT_COMPENSATION://	case V4L2_CID_CHROMA_AGC://	case V4L2_CID_CHROMA_GAIN://	case V4L2_CID_COLOR_KILLER:	case V4L2_CID_COLORFX:		return v4l2_ctrl_query_fill(qc, 0, 6, 1, 0);//	case V4L2_CID_AUTOBRIGHTNESS:#if 0	case V4L2_CID_BAND_STOP_FILTER:		return v4l2_ctrl_query_fill(qc, 0, 63, 1, 2);//	case V4L2_CID_ROTATE://	case V4L2_CID_BG_COLOR:#endif	case V4L2_CID_CAMERA_CLASS:		return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);#if 0	case V4L2_CID_EXPOSURE_AUTO:		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);//	case V4L2_CID_EXPOSURE_ABSOLUTE://	case V4L2_CID_EXPOSURE_AUTO_PRIORITY://	case V4L2_CID_PAN_RELATIVE://	case V4L2_CID_TILT_RELATIVE://	case V4L2_CID_PAN_RESET://	case V4L2_CID_TILT_RESET://	case V4L2_CID_PAN_ABSOLUTE://	case V4L2_CID_TILT_ABSOLUTE://	case V4L2_CID_FOCUS_ABSOLUTE://	case V4L2_CID_FOCUS_RELATIVE://	case V4L2_CID_FOCUS_AUTO://	case V4L2_CID_ZOOM_ABSOLUTE://	case V4L2_CID_ZOOM_RELATIVE://	case V4L2_CID_ZOOM_CONTINUOUS://	case V4L2_CID_IRIS_ABSOLUTE://	case V4L2_CID_IRIS_RELATIVE://	case V4L2_CID_PRIVACY:	case V4L2_CID_SCENE_EXPOSURE:		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);#endif	default:		OV_ERR("invalid control ctrl: %s\n", v4l2_ctrl_get_name(qc->id));		qc->flags |= V4L2_CTRL_FLAG_DISABLED;		return (-EINVAL);	}	return (0);}static int ov5640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl){	struct i2c_client *client = v4l2_get_subdevdata(sd);	//struct ov5640_priv *priv = to_ov5640(client);	int ret = 0;	//int val = 0;    OV_INFO("%s: control ctrl- %s\n", __func__, v4l2_ctrl_get_name(ctrl->id));	switch (ctrl->id) {	case V4L2_CID_BRIGHTNESS:		ov5640_set_brightness(client, ctrl->value);		break;	case V4L2_CID_CONTRAST:		ov5640_set_contrast(client, ctrl->value);		break;	case V4L2_CID_SATURATION:		ov5640_set_saturation(client, ctrl->value);		break;	case V4L2_CID_HUE:		ov5640_set_hue(client, ctrl->value);		break;#if 0//	case V4L2_CID_BLACK_LEVEL://		ov5640_set_black_level(sd, ctrl->value);//		break;	case V4L2_CID_AUTO_WHITE_BALANCE:		ov5640_set_awb(client, ctrl->value);		break;//	case V4L2_CID_DO_WHITE_BALANCE://		ov5640_set_do_white_balance(sd, ctrl->value);//		break;//	case V4L2_CID_RED_BALANCE://		ov5640_set_red_balance(sd, ctrl->value);//		break;//	case V4L2_CID_BLUE_BALANCE://		ov5640_set_blue_balance(sd, ctrl->value);//		break;//	case V4L2_CID_GAMMA://		ov5640_set_gamma(sd, ctrl->value);//		break;#endif	case V4L2_CID_EXPOSURE:		ov5640_set_exposure_level(client, ctrl->value);		break;#if 0	case V4L2_CID_AUTOGAIN:		ov5640_set_autogain(sd, ctrl->value);		break;	case V4L2_CID_GAIN:		ov5640_set_gain(sd, ctrl->value);		break;#endif	case V4L2_CID_HFLIP:	case V4L2_CID_VFLIP:        ov5640_set_flip(client, ctrl);        break;#if 0	case V4L2_CID_POWER_LINE_FREQUENCY:		ov5640_set_power_line_frequency(sd, ctrl->value);		break;//	case V4L2_CID_HUE_AUTO://		ov5640_set_hue_auto(sd, ctrl->value);//		break;	case V4L2_CID_WHITE_BALANCE_TEMPERATURE:		set_white_balance_temperature(client, ctrl->value);		break;#endif	case V4L2_CID_SHARPNESS:		ov5640_set_sharpness(client, ctrl->value);		break;//	case V4L2_CID_BACKLIGHT_COMPENSATION://		ov5640_set_backlight_compensation(sd, ctrl->value);//		break;//	case V4L2_CID_CHROMA_AGC://		ov5640_set_chroma_agc(sd, ctrl->value);//		break;//	case V4L2_CID_CHROMA_GAIN://		ov5640_set_chroma_gain(sd, ctrl->value);//		break;//	case V4L2_CID_COLOR_KILLER://		ov5640_set_color_killer(sd, ctrl->value);//		break;	case V4L2_CID_COLORFX:		ov5640_set_colorfx(client, ctrl->value);		break;#if 0//	case V4L2_CID_AUTOBRIGHTNESS://		ov5640_set_autobrightness(sd, ctrl->value);//		break;	case V4L2_CID_BAND_STOP_FILTER:		ov5640_set_band_stop_filter(sd, ctrl->value);		break;//	case V4L2_CID_ROTATE://		ov5640_set_rotate(sd, ctrl->value);//		break;//	case V4L2_CID_BG_COLOR://		ov5640_set_bg_color(sd, ctrl->value);//		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -