8. 编写相机传感器驱动程序¶
本文档仅涵盖内核中的 API。有关相机传感器驱动程序中用户空间 API 实现的最佳实践,请参阅使用相机传感器驱动程序。
8.1. CSI-2、并行和 BT.656 总线¶
请参阅像素数据发送器和接收器驱动程序。
8.2. 处理时钟¶
相机传感器具有内部时钟树,包括 PLL 和多个分频器。时钟树通常由驱动程序根据一些特定于硬件的输入参数进行配置:外部时钟频率和链路频率。这两个参数通常从系统固件获得。**在任何情况下都不应使用其他频率。**
时钟频率如此重要的原因是时钟信号来自 SoC,并且在许多情况下,特定的频率被设计为在系统中使用。使用其他频率可能会在其他地方造成有害影响。因此,只有预定的频率可由用户配置。
8.2.1. ACPI¶
读取 clock-frequency
_DSD 属性以表示频率。驱动程序可以依赖于使用此频率。
8.2.2. 设备树¶
实现此目的的首选方法是使用 assigned-clocks
、assigned-clock-parents
和 assigned-clock-rates
属性。有关更多信息,请参阅 时钟设备树绑定。然后,驱动程序使用 clk_get_rate()
获取频率。
这种方法的缺点是无法保证该频率没有被另一个驱动程序直接或间接修改,或者最初是否受到板的时钟树的支持。需要更改通用时钟框架 API 以确保可靠性。
8.3. 电源管理¶
相机传感器与其他设备结合使用以形成相机流水线。它们必须遵守此处列出的规则,以确保流水线上的一致电源管理。
相机传感器驱动程序负责控制它们以其他方式控制的设备的电源状态。它们应使用运行时 PM 来管理电源状态。运行时 PM 应在探测时启用,并在移除时禁用。驱动程序应启用运行时 PM 自动挂起。另请参阅异步子设备注册。
运行时 PM 处理程序应处理时钟、调节器、GPIO 和其他启动和关闭传感器所需的系统资源。对于不使用任何这些资源的驱动程序(例如仅支持 ACPI 系统的驱动程序),运行时 PM 处理程序可以不实现。
通常,设备应至少在其寄存器被访问时以及流式传输时通电。驱动程序应在启动流式传输时使用 pm_runtime_resume_and_get()
,在停止流式传输时使用 pm_runtime_put()
或 pm_runtime_put_autosuspend()
。它们可以在探测时为设备供电(例如读取识别寄存器),但不应在探测后无条件地保持供电。
在系统挂起时,整个相机流水线必须停止流式传输,并在系统恢复时重新启动。这需要相机传感器和相机流水线的其余部分之间的协调。桥驱动程序负责此协调,并指示相机传感器通过调用适当的子设备操作(.enable_streams()
或 .disable_streams()
)来停止和重新启动流式传输。因此,相机传感器驱动程序**不应**跟踪流式传输状态,以便在 PM 挂起处理程序中停止流式传输并在恢复处理程序中重新启动它。驱动程序通常不应实现系统 PM 处理程序。
相机传感器驱动程序**不应**实现子设备 .s_power()
操作,因为它已被弃用。虽然此操作在某些现有驱动程序中实现,因为它们早于弃用,但新驱动程序应改用运行时 PM。如果您认为需要开始从 ISP 或桥驱动程序调用 .s_power()
,请改为将运行时 PM 支持添加到您正在使用的传感器驱动程序中,并删除其 .s_power()
处理程序。
另请参阅示例。
8.3.1. 控制框架¶
v4l2_ctrl_handler_setup()
函数可能不会在设备的运行时 PM runtime_resume
回调中使用,因为它无法确定设备的电源状态。这是因为设备的电源状态仅在电源状态转换发生后才会更改。s_ctrl
回调可用于在电源状态转换后获取设备的电源状态
如果成功获取电源计数或运行时 PM 已禁用,则该函数返回一个非零值,在这种情况下,驱动程序可以继续访问设备。
8.4. 旋转、方向和翻转¶
使用 v4l2_fwnode_device_parse()
从系统固件获取旋转和方向信息,并使用 v4l2_ctrl_new_fwnode_properties()
注册适当的控件。
8.5. 示例驱动程序¶
传感器驱动程序实现的功能各不相同,并且根据支持的功能集和其他质量,特定的传感器驱动程序更好地服务于示例的目的。以下驱动程序是已知的好例子
驱动程序名称 |
文件 |
驱动程序类型 |
示例主题 |
CCS |
|
自由配置 |
电源管理(ACPI 和 DT)、UAPI |
imx219 |
|
基于寄存器列表 |
电源管理 (DT)、UAPI、模式选择 |
imx319 |
|
基于寄存器列表 |
电源管理(ACPI 和 DT) |