v4l2-common.h
对一个I2C驱动添加v4l2_subdev支持的建议方式是将v4l2_subdev嵌入到每一个I2C设备实例的state struct。如果设备非常简单,可以直接创建v4l2_subdev。
典型的state struct类似如下:
struct chipname_state { struct v4l2_subdev sd; ... /* additional state fields */ };
v4l2_subdev结构体的初始化:
v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
该函数可以填充v4l2_subdev的所有成员,并且确保v4l2_subdev和i2c_client互指。
所以应该有一个内联函数可以从v4l2_subdev指向chipname_state struct:
static inline struct chipname_state *to_state(struct v4l2_subdev *sd) { return container_of(sd, struct chipname_state, sd); }
从v4l2_subdev获取i2c_client:
struct i2c_client *client = v4l2_get_subdevdata(sd);
从i2c_client获取v4l2_subdev:
struct v4l2_subdev *sd = i2c_get_clientdata(client);
确保当remove()回调时,调用v4l2_device_unregister_subdev(sd)。这是从bridge driver中注销sub-device。即使sub-devices从没有被注册过,该方法被调用也是安全的。
struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, "module_foo", "chipid", 0x36, NULL);
加载给定module(如果没有module需要加载,可以为NULL)并且根据给定i2c_adapter调用i2c_new_device()并且chip/address arguments。如果一切顺利,它将会完成subdev和v4l2_device的同时注册。
你也可以使用v4l2_i2c_new_subdev()的最后一个参数来传递一个可能应该被probe的I2C地址数组。这些probe addresses只有当之前的参数为0才会被使用。一个非零的说法意味着你知道确切的I2C地址,在这种情况下没有探测将发生。
你传递给v4l2_i2c_new_subdev()的参数chipid通常和module name一致。允许指定一个chip变量:saa7114或saa7115。通常会通过i2c驱动自动探测。
v4l2_i2c_new_subdev_cfg:添加新irq和platform_data参数并且同时有"addr"和“probed_addrs”参数:如果add不为0将被使用,否则probed_addrs将被probed。
例如:this will probe for address 0x10:
struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10));
v4l2_i2c_new_subdev_board使用一个传递到i2c drvieri2c_board_info结构体并且替代irq,platform_data和addr参数。
如果subdev支持s_config在core ops中,在subdev被安装后,这个op会被调用,并且传递irq和platform_data参数。同时v4l2_i2c_new_(probed_)subdev将会调用s_config,但是irq为0并且platform_data设置为NULL。