參考資料:
極客筆記https://deepinout.com/camera-sensor-driver/camera-sensor-driver-sensor-subdev-register-flow.html
Camera驅動模型:
使用者空間透過CSL協議層,才能訪問到Camera subdev,/dev/v4l-subdevx都不是固定的
可以透過cat /sys/class/video4linux/v4l-subdevx/name查詢到當前裝置各個子裝置都具體是啥裝置
cam_sensor_dev:註冊裝置,暴露介面
cam_sensor_soc:解析dts,比如clk,regulator等
cam_sensor_core:實際工作流程,開啟關閉開流等
static const struct camera_submodule_component camera_sensor[] = { #ifdef CONFIG_SPECTRA_SENSOR {&cam_res_mgr_init, &cam_res_mgr_exit}, // 入口函式所有子裝置都在這裡 {&cam_cci_init_module, &cam_cci_exit_module}, {&cam_csiphy_init_module, &cam_csiphy_exit_module}, {&cam_tpg_init_module, &cam_tpg_exit_module}, {&cam_actuator_driver_init, &cam_actuator_driver_exit}, {&cam_sensor_driver_init, &cam_sensor_driver_exit}, {&cam_eeprom_driver_init, &cam_eeprom_driver_exit}, {&cam_ois_driver_init, &cam_ois_driver_exit}, {&cam_flash_init_module, &cam_flash_exit_module}, #endif };
platform_driver_register註冊平臺裝置,針對高通的cci匯流排的
i2c_add_driver註冊i2c裝置
高通支援掛載到i2c匯流排,也支援掛載到cci匯流排
CRM就是video裝置,引入component框架
struct cam_sensor_ctrl_t整個sensor資源都是存在這個結構體裡面
static int cam_sensor_init_subdev_params(struct cam_sensor_ctrl_t *s_ctrl) { int rc = 0; s_ctrl->v4l2_dev_str.internal_ops = &cam_sensor_internal_ops; s_ctrl->v4l2_dev_str.ops = &cam_sensor_subdev_ops; // subdev操作控制介面 strscpy(s_ctrl->device_name, CAMX_SENSOR_DEV_NAME, CAM_CTX_DEV_NAME_MAX_LENGTH); s_ctrl->v4l2_dev_str.name = s_ctrl->device_name; s_ctrl->v4l2_dev_str.sd_flags = (V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS); // 前面確定是否暴露裝置節點給上層,後者表示有沒event通知機制 s_ctrl->v4l2_dev_str.ent_function = CAM_SENSOR_DEVICE_TYPE; // 查詢這個type型別,CSL匹配這個型別確定開啟的是哪一個的 s_ctrl->v4l2_dev_str.token = s_ctrl; s_ctrl->v4l2_dev_str.close_seq_prior = CAM_SD_CLOSE_MEDIUM_LOW_PRIORITY; rc = cam_register_subdev(&(s_ctrl->v4l2_dev_str)); // 註冊子裝置 if (rc) CAM_ERR(CAM_SENSOR, "Fail with cam_register_subdev rc: %d", rc); return rc; }
回撥介面:
s_ctrl->bridge_intf.device_hdl = -1; s_ctrl->bridge_intf.link_hdl = -1; s_ctrl->bridge_intf.ops.get_dev_info = cam_sensor_publish_dev_info; // CRM bridge介面 s_ctrl->bridge_intf.ops.link_setup = cam_sensor_establish_link; s_ctrl->bridge_intf.ops.apply_req = cam_sensor_apply_request; s_ctrl->bridge_intf.ops.notify_frame_skip = cam_sensor_notify_frame_skip; s_ctrl->bridge_intf.ops.flush_req = cam_sensor_flush_request; // flush s_ctrl->bridge_intf.ops.process_evt = cam_sensor_process_evt; // 訊息處理事件介面
流程如下: