正式步入v4l2_i2c_subdev_init
这个是什么呢,看代码:
这个是在v4l2-common里面:
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
{
v4l2_subdev_init(sd, ops); //这个地方属于初始化,也就是申请相关空间
sd->flags |= V4L2_SUBDEV_FL_IS_I2C; //说明这个是个i2c的
/* the owner is the same as the i2c_client's driver owner */
sd->owner = client->driver->driver.owner;
/* i2c_client and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, client); //相互保存数据
i2c_set_clientdata(client, sd);
//相互保存数据
/* initialize name */
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", //在这个地方这个name改变了,这里也就是注册mipi的时候用到的名字,每个mipi的每个线都要和这个名字对应,分别是name-所在的i2c总线-i2c的地址
client->driver->driver.name, i2c_adapter_id(client->adapter),
client->addr);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
这个函数主要起到保存参数的总用,后续调用更加的方便。
在这个函数后,真正对v4l2配置的在下面这个函数:
/* register a msm sensor into the msm device, which will probe the
* sensor HW. if the HW exist then create a video device (/dev/videoX/)
* to represent this sensor */
一个v4l2的接口在
/dev/videoX/每一个
videoX对应一个v4l2的设备节点,从这个开始才是v4l2的重点:
int msm_sensor_register(struct v4l2_subdev *sensor_sd)
{
int rc = -EINVAL;
struct msm_camera_sensor_info *sdata;
struct msm_cam_v4l2_device *pcam;
struct msm_sensor_ctrl_t *s_ctrl;
D("%s for %s\n", __func__, sensor_sd->name);
/* allocate the memory for the camera device first */
pcam = kzalloc(sizeof(*pcam), GFP_KERNEL);
if (!pcam) {
pr_err("%s: could not allocate mem for msm_cam_v4l2_device\n",
__func__);
return -ENOMEM;
}
pcam->sensor_sdev = sensor_sd; //这个
sensor_sd,就是一个v4l2的name而已,里面的成员只做了赋值为0的初始化动作,后面会看到它的羽翼逐渐丰满。
s_ctrl = get_sctrl(sensor_sd);
sdata = (struct msm_camera_sensor_info *) s_ctrl->sensordata;//这个很眼熟,不就是那个board中的
msm_camera_sensor_info嘛!它包含了对sensor的很多信息,power啊reset啊 是否是有yuv的还是raw的,有没有对焦啊,什么都有!
pcam->act_sdev = msm_actuator_probe(sdata->actuator_info);//这个地方看了对马达的probe了没,马达的i2c的probe就是从这个地方开始的
pcam->eeprom_sdev = msm_eeprom_probe(sdata->eeprom_info); //这个地方对应board中的
eeprom_info
D("%s: pcam =0x%p\n", __func__, pcam);
pcam->sdata = sdata; //
msm_camera_sensor_info进去了
/* init the user count and lock*/
pcam->use_count = 0;
mutex_init(&pcam->vid_lock);
mutex_init(&pcam->mctl_node.dev_lock);
/* Initialize the formats supported */
rc = msm_mctl_init_user_formats(pcam);