前段时间在rk平台移植了ov5647在这期间顺便了解了下驱动结构和代码匹配流程。首先是初始化部分。抛去init和compatible匹配直接分析probe:
struct device_node *np = client->dev.of_node;
struct device *dev = &client->dev;
struct ov5647 *sensor;
struct v4l2_subdev *sd;
char facing[2];
u32 xclk_freq;
int ret;
sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
return -ENOMEM;
if (IS_ENABLED(CONFIG_OF) && np) {
ret = ov5647_parse_dt(sensor, np);
if (ret) {
dev_err(dev, "DT parsing error: %d\n", ret);
return ret;
}
}
sensor->xclk = devm_clk_get(dev, NULL);
if (IS_ERR(sensor->xclk)) {
dev_err(dev, "could not get xclk");
return PTR_ERR(sensor->xclk);
}
xclk_freq = clk_get_rate(sensor->xclk);
if (xclk_freq != 25000000) {
dev_err(dev, "Unsupported clock frequency: %u\n", xclk_freq);
return -EINVAL;
}
/* Request the power down GPIO asserted. */
sensor->pwdn = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_HIGH);
if (IS_ERR(sensor->pwdn)) {
dev_err(dev, "Failed to get 'pwdn' gpio\n");
return -EINVAL;
}
ret = ov5647_configure_regulators(dev, sensor);
if (ret) {
dev_err(dev, "Failed to get power regulators\n");
return ret;
}
mutex_init(&sensor->lock);
sensor->mode = OV5647_DEFAULT_MODE;
ret = of_property_read_u32(np, RKMODULE_CAMERA_MODULE_INDEX,
&sensor->module_index);
ret |= of_property_read_string(np, RKMODULE_CAMERA_MODULE_FACING,
&sensor->module_facing);
ret |= of_property_read_string(np, RKMODULE_CAMERA_MODULE_NAME,
&sensor->module_name);
ret |= of_property_read_string(np, RKMODULE_CAMERA_LENS_NAME,
&sensor->len_name);
ret = ov5647_init_controls(sensor, dev);
if (ret)
goto mutex_destroy;
sd = &sensor->sd;
v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
sd->internal_ops = &ov5647_subdev_inte