九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 4399|回复: 1
打印 上一主题 下一主题

x4412&ibox项目实战56-Linux摄相头驱动之I2C驱动实验

[复制链接]
跳转到指定楼层
楼主
发表于 2014-11-29 11:04:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
摄相头驱动源码路径:
  1. kernel/drivers/media/video/ov2655_2m.c
  2. kernel/drivers/media/video/ ov2655_2m.h
  3. kernel/arch/arm/mach-exynos/mach-x4412.c
复制代码
       mach-x4412.c中,定义了OV2655的名称和地址:
  1. static struct i2c_board_info  ov2655_i2c_info = {
  2.          I2C_BOARD_INFO("ov2655", 0x30),
  3.          .platform_data = &ov2655_plat,
  4. };
复制代码
       OV2655属于fimc接口设备,通过注册fimc设备实现注册ov2655i2c设备。在ov2655_2m.c中,通过i2c_add_driver函数添加ov2655i2c驱动。在结构体ov2655_i2c_driverid_table对应的驱动名称为宏ov2655_DRIVER_NAME,它在驱动最前面被定义为ov2655,和mach-x4412.c中的正好吻合,探测函数ov2655_probe得以执行。
       在探测函数中通过v4l2_i2c_subdev_init函数注册一个基于v4l2i2c子设备,就可以正常使用I2C的读写函数了。
       __OV2655_init_2bytes函数用于一次性初始化一组寄存器,在ov2655_2m.h中定义了OV2655的一系列需要上电初始化的寄存器,存放在二维数组ov2655_init_reg中。每一组数组由一个16位的寄存器地址和一个8位的寄存器预初始化的值组成,__OV2655_init_2bytes函数会自动计算分析,将它们完整的写入OV2655芯片中。其函数原型如下:
  1. static int __OV2655_init_2bytes(struct v4l2_subdev *sd, unsigned short *reg[],int total)
  2. {
  3.          struct i2c_client *client = v4l2_get_subdevdata(sd);
  4.          int ret = -EINVAL, i;
  5.          unsigned short *item;
  6.          unsigned char bytes;

  7.          for (i = 0; i < total; i++)
  8.          {
  9.                    item = (unsigned short *) ®[i];

  10.                    if (item[0] == REG_DELAY)
  11.                    {
  12.                             mdelay(item[1]);
  13.                             ret = 0;
  14.                    }
  15.                    else
  16.                    {
  17.                             ret = OV2655_write(sd, item[0], item[1]);
  18.                    }
  19.                    if (ret < 0)
  20.                             ;//v4l_info(client, "%s: register set failed\n", __func__);
  21.          }

  22.          return ret;
  23. }
复制代码
       从程序清单可以看出,item[0]表示初始化数组中的第一个16位的寄存器地址,item[1]表示初始化数组中的第二个8位的预写入寄存器的值,通过OV2655_write函数传出。
  1. static inline int OV2655_write(struct v4l2_subdev *sd, unsigned short addr,
  2.                    u8 val)
  3. {
  4.          struct i2c_client *client = v4l2_get_subdevdata(sd);
  5.          struct i2c_msg msg[1];
  6.          unsigned char reg[3];

  7.          if (!client->adapter)
  8.                    return -ENODEV;

  9.          msg->addr = client->addr;
  10.          msg->flags = 0;
  11.          msg->len = 3;
  12.          msg->buf = reg;

  13.          reg[0] = addr >> 8;
  14.          reg[1] = addr & 0xFF;
  15.          reg[2] = val & 0xFF;

  16.          if (i2c_transfer(client->adapter, msg, 1) != 1)
  17.          {
  18.                    printk("ov2655 i2c_transfer failed\n");
  19.                    return -EIO;
  20.          }

  21.          return 0;
  22. }
复制代码
       OV2655_write函数中,msg->addr表示写入寄存器的起始地址,msg->flags0表示I2C执行写命令,msg->len3表示一次性写入3个字节,前两个字节组成16位,表示寄存器的地址,第三个字节表示要写入的寄存器的值。msg->buf表示要写入的字节的值,紧接着程序就给reg数组赋了值。最后调用i2c_transfer函数完成i2c的写操作。在__OV2655_init_2bytes函数中通过一个for循环,多次调用OV2655_write函数,实现一系列寄存器的初始化,换句话说,我们只需要把OV2655需要初始化的寄存器地址和值填入初始化寄存器数组ov2655_init_reg中,然后通过__OV2655_init_2bytes函数调用即可。
回复

使用道具 举报

沙发
发表于 2015-7-30 17:24:20 | 只看该作者
我现在也准备在4412上面安装ov2655。请问,ov2655的通过mipi接口与4412链接,kernel提供的驱动可以支持吗?谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-11-23 14:35 , Processed in 0.018341 second(s), 16 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表