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) |