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

📄 ov5640.c

📁 linux下ov5640驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {0x518d, 0x42},     {0x518e, 0x3a},     {0x518f, 0x56},     {0x5190, 0x46},     {0x5191, 0xf0},     {0x5192, 0xf},     {0x5193, 0x70},     {0x5194, 0xf0},     {0x5195, 0xf0},     {0x5196, 0x3},     {0x5197, 0x1},     {0x5198, 0x6},     {0x5199, 0x62},     {0x519a, 0x4},     {0x519b, 0x0},     {0x519c, 0x4},     {0x519d, 0xe7},     {0x519e, 0x38}, };static const struct regval ov5640_qsxga_regs[] = {    {0x3820, 0x40},  /* diff. init */    {0x3821, 0x06},    {0x3814, 0x11}, /* image windowing */    {0x3815, 0x11},    {0x3803, 0x00},    {0x3807, 0x9f},    {0x3808, 0x0a}, /* 0x0a20==2592 */    {0x3809, 0x20},    {0x380a, 0x07}, /* 0x798==1944 */    {0x380b, 0x98},    {0x380c, 0x0b},    {0x380d, 0x1c},    {0x380e, 0x07},    {0x380f, 0xb0},    {0x3813, 0x04},        {0x3618, 0x04},    {0x3612, 0x4b},    {0x3708, 0x21},    {0x3709, 0x12},    {0x370c, 0x00},    {0x3a02, 0x07}, /* night mode */    {0x3a03, 0xb0},    {0x3a0e, 0x06},    {0x3a0d, 0x08},    {0x3a14, 0x07},    {0x3a15, 0xb0},        {0x4004, 0x06}, /* BLC line number */    {0x5000, 0x07}, /* black/white pixel cancell, color interp. enable */    {0x5181, 0x52}, /* AWB */    {0x5182, 0x00},    {0x5197, 0x01},    {0x519e, 0x38},        {0x3035, 0x21}, /* SC PLL */    {0x5000, 0x27},     {0x5001, 0x83}, /* special effect, color matrix, AWB enable */    {0x3035, 0x71},    {0x4713, 0x02}, /* jpeg mode 2 */    {0x3036, 0x69},    {0x4407, 0x0c}, /* jpeg ctrl */    {0x460b, 0x37},    {0x460c, 0x20},    {0x3824, 0x01},    {0x4005, 0x1A},};/*static const struct regval ov5640_qsxga_to_qvga_regs[] = {};*/static const struct regval ov5640_qsxga_to_vga_regs[] = {    {0x3800, 0x00}, /* image windowing */    {0x3801, 0x00},    {0x3802, 0x00},    {0x3803, 0x00},    {0x3804, 0xA },    {0x3805, 0x3f},    {0x3806, 0x7 },    {0x3807, 0x9f},    {0x3808, 0x2 }, /* 0x280== 640*/    {0x3809, 0x80},    {0x380a, 0x1 }, /* 0x1e0== 480*/    {0x380b, 0xe0},    {0x380c, 0xc },    {0x380d, 0x80},    {0x380e, 0x7 },    {0x380f, 0xd0},        {0x5001, 0xa3}, /* SDE, scaling, color matrix, AWB enable */    {0x5680, 0x0 }, /* AVG ctrl */    {0x5681, 0x0 },    {0x5682, 0xA },    {0x5683, 0x20},    {0x5684, 0x0 },    {0x5685, 0x0 },    {0x5686, 0x7 },    {0x5687, 0x98},};static const struct regval ov5640_qsxga_to_xga_regs[] = {    {0x3800, 0x00},    {0x3801, 0x00},    {0x3802, 0x00},    {0x3803, 0x00},    {0x3804, 0xA },    {0x3805, 0x3f},    {0x3806, 0x7 },    {0x3807, 0x9f},    {0x3808, 0x4 }, /* 0x400==1024 */    {0x3809, 0x0 },    {0x380a, 0x3 }, /* 0x300== 768*/    {0x380b, 0x0 },    {0x380c, 0xc },    {0x380d, 0x80},    {0x380e, 0x7 },    {0x380f, 0xd0},    {0x5001, 0xa3},    {0x5680, 0x0 },    {0x5681, 0x0 },    {0x5682, 0xA },    {0x5683, 0x20},    {0x5684, 0x0 },    {0x5685, 0x0 },    {0x5686, 0x7 },    {0x5687, 0x98},};static const struct regval ov5640_qsxga_to_sxga_regs[] = {    {0x3800, 0x00},    {0x3801, 0x00},    {0x3802, 0x00},    {0x3803, 0x00},    {0x3804, 0xA },    {0x3805, 0x3f},    {0x3806, 0x7 },    {0x3807, 0x9f},    {0x3808, 0x5 }, /* 0x500==1280 */    {0x3809, 0x0 },    {0x380a, 0x3 }, /* 0x3c0==960 */    {0x380b, 0xc0},    {0x380c, 0xc },    {0x380d, 0x80},    {0x380e, 0x7 },    {0x380f, 0xd0},    {0x5001, 0xa3},    {0x5680, 0x0 },    {0x5681, 0x0 },    {0x5682, 0xA },    {0x5683, 0x20},    {0x5684, 0x0 },    {0x5685, 0x0 },    {0x5686, 0x7 },    {0x5687, 0x98},};static const struct regval ov5640_qsxga_to_uxga_regs[] = {    {0x3800, 0x00},    {0x3801, 0x00},    {0x3802, 0x00},    {0x3803, 0x00},    {0x3804, 0xA },    {0x3805, 0x3f},    {0x3806, 0x7 },    {0x3807, 0x9f},    {0x3808, 0x6 }, /* 0x640== 1600*/    {0x3809, 0x40},    {0x380a, 0x4 }, /* 0x4b0==1200 */    {0x380b, 0xb0},    {0x380c, 0xc },    {0x380d, 0x80},    {0x380e, 0x7 },    {0x380f, 0xd0},    {0x5001, 0xa3},    {0x5680, 0x0 },    {0x5681, 0x0 },    {0x5682, 0xA },    {0x5683, 0x20},    {0x5684, 0x0 },    {0x5685, 0x0 },    {0x5686, 0x7 },    {0x5687, 0x98},};static const struct regval ov5640_qsxga_to_qxga_regs[] = {    {0x3800, 0x00},    {0x3801, 0x00},    {0x3802, 0x00},    {0x3803, 0x00},    {0x3804, 0xA },    {0x3805, 0x3f},    {0x3806, 0x7 },    {0x3807, 0x9f},    {0x3808, 0x8 }, /* 0x800==2048 */    {0x3809, 0x0 },    {0x380a, 0x6 }, /* 0x600==1536 */    {0x380b, 0x0 },    {0x380c, 0xc },    {0x380d, 0x80},    {0x380e, 0x7 },    {0x380f, 0xd0},    {0x5001, 0xa3},    {0x5680, 0x0 },    {0x5681, 0x0 },    {0x5682, 0xA },    {0x5683, 0x20},    {0x5684, 0x0 },    {0x5685, 0x0 },    {0x5686, 0x7 },    {0x5687, 0x98},};#if 0static const struct v4l2_queryctrl ov5640_controls[] = {	{		.id		= V4L2_CID_VFLIP,		.type		= V4L2_CTRL_TYPE_BOOLEAN,		.name		= "Flip Vertically",		.minimum	= 0,		.maximum	= 1,		.step		= 1,		.default_value	= 0,	},	{		.id		= V4L2_CID_HFLIP,		.type		= V4L2_CTRL_TYPE_BOOLEAN,		.name		= "Flip Horizontally",		.minimum	= 0,		.maximum	= 1,		.step		= 1,		.default_value	= 0,	},};#endif/* QVGA: 320*240 */ /*static const struct ov5640_win_size ov5640_win_qvga = {	.name     = "QVGA",	.width    = QVGA_WIDTH,	.height   = QVGA_HEIGHT,	.regs     = ov5640_qsxga_to_qvga_regs,};*/static const struct ov5640_win_size ov5640_wins[] = {    {        .name    = "VGA",    /* VGA: 640*480 */        .resv    = RESV_VGA,        .width   = VGA_WIDTH,         .height  = VGA_HEIGHT,        .regs    = ov5640_qsxga_to_vga_regs,    },    {        .name    = "XGA",    /* XGA: 1024*768 */        .resv    = RESV_XGA,        .width   = XGA_WIDTH,        .height  = XGA_HEIGHT,        .regs    = ov5640_qsxga_to_xga_regs,    },    {        .name    = "SXGA",    /* SXGA: 1280*960  */        .resv    = RESV_SXGA,        .width   = SXGA_WIDTH,        .height  = SXGA_HEIGHT,        .regs    = ov5640_qsxga_to_sxga_regs,    },    {        .name    = "UXGA",    /* UXGA: 1600*1200 */        .resv    = RESV_UXGA,        .width   = UXGA_WIDTH,        .height  = UXGA_HEIGHT,        .regs    = ov5640_qsxga_to_uxga_regs,    },    {        .name    = "QXGA",    /* QXGA: 2048*1536 */        .resv    = RESV_QXGA,        .width   = QXGA_WIDTH,        .height  = QXGA_HEIGHT,        .regs    = ov5640_qsxga_to_qxga_regs,    },    {        .name    = "QSXGA",    /* QSXGA: 2560*1920*/        .resv    = RESV_QSXGA,        .width   = QSXGA_WIDTH,        .height  = QSXGA_HEIGHT,        .regs    = ov5640_qsxga_regs,    },};/* * supported color format list */static const struct ov5640_color_format ov5640_cfmts[] = {	{		.code		= V4L2_MBUS_FMT_YUYV8_2X8_BE,		.colorspace	= V4L2_COLORSPACE_JPEG,	},	{		.code		= V4L2_MBUS_FMT_YUYV8_2X8_LE,		.colorspace	= V4L2_COLORSPACE_JPEG,	},};static int i2cc_get_reg(struct i2c_client *client,     unsigned short reg, unsigned char *value){    unsigned char buffer[2];    int ret = 0;    int err = 0;    buffer[0] = (reg >> 8) & 0xFF;    buffer[1] = reg & 0xFF;    if (2 != (ret = i2c_master_send(client, buffer, 2))) {        err = -2;        OV_ERR("i2cc out error: ret == %d (should be 2)\n", ret);    }    if (1 != (ret = i2c_master_recv(client, buffer, 1))) {        err = -1;        OV_ERR("i2cc in error: ret == %d (should be 1)\n", ret);    }    //OV_INFO("ov5640 client: read 0x%x = 0x%x\n", reg, buffer[0]);    *value = buffer[0];    return (err);}static int i2cc_set_reg(struct i2c_client *client,    unsigned short reg, unsigned char value){    unsigned char buffer[3];    int ret = 0;    int err = 0;    buffer[0] = (reg >> 8) & 0xFF;    buffer[1] = reg & 0xFF;    buffer[2] = value;    //OV_INFO("ov5640 client: writing 0x%x = 0x%x\n", reg, value);    if (3 != (ret = i2c_master_send(client, buffer, 3))) {        OV_ERR("i2cc out error: ret = %d (should be 3)\n", ret);        err = -3;    }    return (err);}static inline struct ov5640_priv *to_ov5640(const struct i2c_client *client){	return container_of(i2c_get_clientdata(client), struct ov5640_priv, subdev);}static int write_regs(struct i2c_client *client,     const struct regval *regs, int array_len){    int i;    int ret = 0;    for (i = 0; i < array_len; i++) {        if ((ret = i2cc_set_reg(client, regs->reg, regs->val))) {            OV_ERR("error to set reg:0x%d -> value:%d(index:%d)\n", regs->reg,                 regs->val, i);            break;        }        regs++;    }    INFO_BLUE("------*------- write array regs over -------*------ \n");    return (ret);}static int ov5640_set_bus_param(struct soc_camera_device *icd,     unsigned long flags){    INFO_PURLPLE("\n");	return 0;}static unsigned long ov5640_query_bus_param(struct soc_camera_device *icd){	struct soc_camera_link *icl = to_soc_camera_link(icd);        /* camera can do 10 bit transfers,  but omit it now */	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;	return soc_camera_apply_sensor_flags(icl, flags);}static int ov5640_g_chip_ident(struct v4l2_subdev *sd,			       struct v4l2_dbg_chip_ident *id){	struct i2c_client *client = v4l2_get_subdevdata(sd);	struct ov5640_priv *priv = to_ov5640(client);	id->ident = priv->model;	id->revision = 0;	return (0);}static const struct ov5640_win_size *select_win(    unsigned int width, unsigned int height){    const struct ov5640_win_size *ret = NULL;    int size = ARRAY_SIZE(ov5640_wins);    unsigned int diff = -1;    unsigned int tmp;    int i;    for (i = 0; i < size; i++) {        tmp = abs(width - ov5640_wins[i].width) +             abs(height - ov5640_wins[i].height);        if (tmp < diff) {            diff = tmp;            ret = ov5640_wins + i;        }    }    return (ret); }static int ov5640_try_fmt(struct v4l2_subdev *sd,    struct v4l2_mbus_framefmt *vmf){    struct i2c_client *client = v4l2_get_subdevdata(sd);    struct ov5640_priv *priv = to_ov5640(client);    const struct ov5640_win_size *win;    int found = 0;    int i;        win = select_win(vmf->width, vmf->height);    vmf->width = win->width;    vmf->height = win->height;    vmf->field = V4L2_FIELD_NONE;    for (i = 0; i < ARRAY_SIZE(ov5640_cfmts); i++) {        if (ov5640_cfmts[i].code == vmf->code) {            found = 1;            break;        }    }    if (found) {        vmf->colorspace = ov5640_cfmts[i].colorspace;    } else {        /* Unsupported format requested. Propose either */		if (priv->cfmt) {			/* the current one or */			vmf->colorspace = priv->cfmt->colorspace;			vmf->code = priv->cfmt->code;		} else {			/* the default one */			vmf->colorspace = ov5640_cfmts[0].colorspace;			vmf->code = ov5640_cfmts[0].code;		}    }    INFO_GREEN("code:%d-%s %dX%d\n",         vmf->code, win->name, vmf->width, vmf->height);    return (0);}/* start or stop streaming from the device */static int ov5640_s_stream(struct v4l2_subdev *sd, int enable){    struct i2c_client *client = v4l2_get_subdevdata(sd);    struct ov5640_priv *priv = to_ov5640(client);    if (!enable) {        INFO_PURLPLE("stream down\n");        // set regs to enter sleep mode, already in DVP mode        i2cc_set_reg(client, 0x3008, 0x42);        return (0);    }    if (NULL == priv->win || NULL == priv->cfmt) {        OV_ERR("win or cfmt select error!\n");        return (-EPERM);    }    INFO_PURLPLE("stream on\n");    //set regs to leave sleep mode, in DVP mode , needn't to set 0x300e to 0xc    i2cc_set_reg(client, 0x3008, 0x02);        INFO_GREEN("format: %d, win:%s\n", priv->cfmt->code, priv->win->name);    // wait for 2 Vsync, and capture the 3rd frame, (1 / 7.5) * 2 =. 267ms    mdelay(270);        return (0);}

⌨️ 快捷键说明

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