摄相头驱动源码路径: - kernel/drivers/media/video/ov2655_2m.c
- kernel/drivers/media/video/ ov2655_2m.h
- kernel/arch/arm/mach-exynos/mach-x4412.c
复制代码 在mach-x4412.c中,定义了OV2655的名称和地址: - static struct i2c_board_info ov2655_i2c_info = {
- I2C_BOARD_INFO("ov2655", 0x30),
- .platform_data = &ov2655_plat,
- };
复制代码 OV2655属于fimc接口设备,通过注册fimc设备实现注册ov2655的i2c设备。在ov2655_2m.c中,通过i2c_add_driver函数添加ov2655的i2c驱动。在结构体ov2655_i2c_driver的id_table对应的驱动名称为宏ov2655_DRIVER_NAME,它在驱动最前面被定义为ov2655,和mach-x4412.c中的正好吻合,探测函数ov2655_probe得以执行。 在探测函数中通过v4l2_i2c_subdev_init函数注册一个基于v4l2的i2c子设备,就可以正常使用I2C的读写函数了。 __OV2655_init_2bytes函数用于一次性初始化一组寄存器,在ov2655_2m.h中定义了OV2655的一系列需要上电初始化的寄存器,存放在二维数组ov2655_init_reg中。每一组数组由一个16位的寄存器地址和一个8位的寄存器预初始化的值组成,__OV2655_init_2bytes函数会自动计算分析,将它们完整的写入OV2655芯片中。其函数原型如下: - static int __OV2655_init_2bytes(struct v4l2_subdev *sd, unsigned short *reg[],int total)
- {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = -EINVAL, i;
- unsigned short *item;
- unsigned char bytes;
-
- for (i = 0; i < total; i++)
- {
- item = (unsigned short *) ®[i];
-
- if (item[0] == REG_DELAY)
- {
- mdelay(item[1]);
- ret = 0;
- }
- else
- {
- ret = OV2655_write(sd, item[0], item[1]);
- }
- if (ret < 0)
- ;//v4l_info(client, "%s: register set failed\n", __func__);
- }
-
- return ret;
- }
复制代码 从程序清单可以看出,item[0]表示初始化数组中的第一个16位的寄存器地址,item[1]表示初始化数组中的第二个8位的预写入寄存器的值,通过OV2655_write函数传出。 - static inline int OV2655_write(struct v4l2_subdev *sd, unsigned short addr,
- u8 val)
- {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct i2c_msg msg[1];
- unsigned char reg[3];
-
- if (!client->adapter)
- return -ENODEV;
-
- msg->addr = client->addr;
- msg->flags = 0;
- msg->len = 3;
- msg->buf = reg;
-
- reg[0] = addr >> 8;
- reg[1] = addr & 0xFF;
- reg[2] = val & 0xFF;
-
- if (i2c_transfer(client->adapter, msg, 1) != 1)
- {
- printk("ov2655 i2c_transfer failed\n");
- return -EIO;
- }
-
- return 0;
- }
复制代码 在OV2655_write函数中,msg->addr表示写入寄存器的起始地址,msg->flags为0表示I2C执行写命令,msg->len为3表示一次性写入3个字节,前两个字节组成16位,表示寄存器的地址,第三个字节表示要写入的寄存器的值。msg->buf表示要写入的字节的值,紧接着程序就给reg数组赋了值。最后调用i2c_transfer函数完成i2c的写操作。在__OV2655_init_2bytes函数中通过一个for循环,多次调用OV2655_write函数,实现一系列寄存器的初始化,换句话说,我们只需要把OV2655需要初始化的寄存器地址和值填入初始化寄存器数组ov2655_init_reg中,然后通过__OV2655_init_2bytes函数调用即可。
|