2026 年 Fairphone 6 广角相机实现 Linux 实验性支持,多步骤攻克技术难题
背景Fairphone 6 成为主线 Linux 和 postmarketOS 的有趣目标原因有五其一与多数受支持的 postmarketOS 设备相比它的硬件较新其二Fairphone 投资支持主线 LinuxLuca Weiss 推动了大部分开发工作其三这些努力为硬件提供了有前景的初步支持其四Fairphone 有意允许安装替代操作系统其五Fairphone 旨在长期支持其设备这款手机能为未来工作提供稳定基础。不过要使该设备普遍可用仍有板载音频和相机支持两大障碍。因进行一个需要 QR 扫描的项目作者借此机会尝试让至少一个相机正常工作并声明很大程度依赖大语言模型LLM完成这项工作。Fairphone 6 的相机Fairphone 6 有三个相机后置为索尼 IMX896前置是三星 S5KKD1广角是豪威科技 OV13B10。索尼和三星的传感器无主线 Linux 驱动程序豪威科技的 OV13B10 有主线驱动程序超广角相机足以用于 QR 扫描。手机相机并非单一设备在高通系统级芯片SoC上图像捕捉路径是一个链条图像传感器 → CSI - 2 D - PHY → CSIPHY → CSID → ISPVFE/TFE→ 内存 I2C MIPI 通道 解码 解复用 写入引擎 DMA 。此外还有相机时钟控制器camcc、CCI高通专用的相机 I2C 控制器、电源轨道以及用于自动对焦的音圈马达VCM等辅助组件。下游供应商的安卓内核用高通大量的专有 CAMX/cam - kernel 堆栈驱动这一切主线 Linux 中等效的是更小的 qcom - camss 驱动程序由 libcamera 提供用户空间集成和图像处理功能。为让豪威科技的相机正常工作作者需让 qcom - camss 了解 SoC 的特定模块在设备树中描述硬件启用传感器驱动程序并配置 libcamera 将原始拜耳帧转换为应用程序可用的图像。初步探索实施前作者想了解有多少工作是全新的有多少可从主线已支持的硬件中移植过来这能表明在无制造商支持的情况下项目是否可行。初步研究结果令人鼓舞FP6 的 SoC 是高通 milosSM7635下游主板代号是 volcanopostmarketOS 已能用基于主线的内核分支启动它相机硬件模块包括 TFE665一种前端精简型 ISP、CSID665 和 CSIPHY v2.2.1camcc 时钟控制器和 CCI 已存在于内核分支中三个相机分别是主摄像头索尼 IMX896无主线驱动程序、超广角摄像头豪威科技 OV13B10有仅支持 ACPI/x86 的主线驱动程序、前置摄像头三星 S5KKD1无主线驱动程序。因此目标明确为 OV13B10 超广角摄像头它是 1300 万像素的传感器有现有主线驱动程序宽广视野适合 QR 扫描。将下游的寄存器头文件cam_tfe665.h、cam_csiphy_2_2_1_hwreg.h 和 cam_tfe_bus.c与主线的 qcom - camss 比较发现 TFE665 本质与主线已支持的 TFE530 是相同的 IP寄存器布局相同只是内部模块基偏移量不同因写入总线位于不同地址。同样CSID665 的 RDI 寄存器与受支持的 CSID 相匹配CSIPHY v2.2.1 属于同一三相 PHY 家族。这意味着作者可移植现有驱动程序而非从头编写所有内容。步骤 1将捕获子系统移植到内核中qcom - camss 在 milos 上不可用作者必须连接现有部分。TFE665 ISP 驱动程序方面作者仿照主线的 TFE530 驱动程序camss - vfe - 340.c添加新的 camss - vfe - 665.c。因寄存器内容相同驱动程序逻辑也相同主要区别是 milos 将 ISP 控制块和写入总线块放在不同偏移量处总线寄存器基地址从 0xa00 移到 0x1800处理偏移量变化占了大部分工作。CSID665 和 CSIPHY v2.2.1 方面CSID665 因 RDI 寄存器偏移量相同重用现有第二代 CSID 操作CSIPHY v2.2.1 需要新的通道配置表和 D - PHY 调优值作者从下游的 cam_csiphy_2_2_1_hwreg.h 中转录通道寄存器序列、约 1.1 Gbps/通道“500 Msps”的数据速率和 AFE 设置PHY 的寄存器窗口位于偏移量 0x1000 处。资源、兼容性和设备树方面在 camss.c 中作者描述了 milos 的捕获复合体包括四个 CSIPHY、三个 CSID、三个 TFE 及其时钟、互连和电源域还注册了新的 qcom,milos - camss 兼容性。在设备树中作者添加了 camssac13000 节点包括其寄存器、中断请求IRQs、时钟、互连、IOMMUs、GDSC 和 CSI 输入端口以及 MCLK 和复位引脚控制状态。缺失的寄存器总线时钟方面这时遇到问题驱动程序绑定成功但读取 TFE 硬件版本寄存器返回 0x0复位超时好像模块没通电。解决办法是启用 CAM_CC_SOC_AHB_CLK 时钟它控制整个相机复合体包括 CCI使用的 AHB 寄存器总线无它寄存器访问会无声返回零。作者添加这个时钟和 CAMNOC AXI 时钟设置 CAMNOC 数据路径时钟速率此时ISP 恢复正常hw_version 0x30000000。这表明在高通硬件上若模块读取值为零可能是其访问路径上缺少时钟或电源域。步骤 2启动 OV13B10 传感器主线的 ov13b10 驱动程序为 x86/ACPI 笔记本电脑编写只能通过 ACPI 匹配作者在两处修改。使驱动程序可在 ARM 和设备树中使用方面作者添加 OpenFirmware 匹配表ovti,ov13b10让驱动程序可从设备树中探测在 milos - fairphone - fp6.dts 中描述该传感器它位于 CCI I2C 总线上地址为 0x36需要 19.2 MHz 的 MCLK1、一个复位 GPIO 和电源轨道实验性启动时作者简单强制开启稳压器未进行完整时序控制。两个小细节方面一是通道编号下游设备树使用 data - lanes 1 2 3 4主线惯例是从零开始编号 0 1 2 3编号错误CSIPHY 会对通道掩码编程导致通道 0 缺失PHY 无法锁定二是使用哪个 CSIPHYFP6 的线路将超广角相机连接到 CSIPHY1从下游设备树获取此信息避免大量试错。此时传感器探测成功通过 I2C 正确读取芯片 IDCSIPHY 报告通道有活动ISP 也产生了帧但这些帧完全是黑色的。步骤 3全零帧之谜这是主要问题帧以正确速率和大小到达buf_done 信号触发但每个像素值都是零启用传感器内部彩条测试图案时也如此该图案在传感器内部生成应无论场景都显示。数据路径传递了帧时序但未传递像素数据。内核日志提供线索VFE0: Bad config violation。ISP 的写入引擎每帧都会报告消费者/配置违规因写入主设备的配置与传入的数据不匹配。深入研究下游的 cam_tfe_bus.c差异清晰RDI 写入主设备的打包器格式取决于 ISP 总线宽度TFE530qcm2290主线驱动程序目标有 64 位的 RDI 总线用打包器 0xaTFE665milos有 128 位的 RDI 总线需打包器 0x0。主线驱动程序硬编码 64 位的值在 milos 上错误写入引擎拒绝写入像素。将寄存器值从 PLAIN64 (0xa) 改为 0x0 后全零帧变成真实图像最大像素值为 255完整彩条图案出现违规报告停止。此时相机从物理上开始工作OV13B10 → CSIPHY → CSID → TFE665 → DDR传输真正的拜耳帧。步骤 4从原始拜耳帧到 libcamera原始帧足以用于 QR 脚本但可用相机需要 libcamera它是现代 Linux 相机应用程序使用的用户空间框架。libcamera 0.7.2 已通过其通用的简单管道处理程序识别 milos 的 qcom - camss 图形其软件 ISP 将原始帧解拜耳为 RGB在 Adreno GPU 上通过 EGL 加速开箱约 30 fps。cam 和 GStreamer 的 libcamerasrc 立即生成清晰图像。自动曝光是不起作用的部分图像要么太暗要么太亮日志报告 Failed to create camera sensor helper for ov13b10。libcamera 的软件自动曝光和增益循环需要针对每个传感器的小辅助程序将传感器的增益寄存器值映射到实际的增益乘数libcamera 包含几个传感器的辅助程序但无此传感器的。修复方法简单OV13B10 的模拟增益是线性的0x80 1×即 gain code / 128与其他几个豪威科技传感器行为相同。作者在 libcamera 的传感器辅助数据库中添加类class CameraSensorHelperOv13b10 : public CameraSensorHelper {public: CameraSensorHelperOv13b10() { gain_ AnalogueGainLinear{ 1, 0, 0, 128 }; }};REGISTER_CAMERA_SENSOR_HELPER(ov13b10, CameraSensorHelperOv13b10)自动曝光循环立即开始收敛。作者还在 libcamera 的传感器属性数据库中添加条目反向移植传感器驱动程序的 V4L2 裁剪和 get_selection 支持libcamera 用这些支持处理像素阵列的几何信息。之后GStreamer 和 PipeWire 接收到正确曝光的视频流。安装 PipeWire libcamera 插件后相机在桌面应用程序中作为普通视频源出现。某些情况下图像仍有些过曝辅助程序可能还需进一步改进。步骤 5对焦、方向和分辨率问题作者还有些问题需微调。自动对焦方面超广角相机有用于对焦的音圈马达VCM下游设备树表明它是 Awinic AW86017。为自动对焦轨道供电由一个 GPIO 驱动的稳压器控制并探测 CCI I2C 总线后作者在地址 0x0c 处发现遵循事实上的标准 DW9714 10 位 DAC 协议的设备主线的 dw9714 驱动程序可直接驱动它。一次对焦扫描证实镜头可物理移动中间设置时清晰度明显达峰值。libcamera 通过设备树中的 lens - focus 链接将镜头与传感器关联。不幸的是libcamera 的软件 ISP 无自动对焦算法为避免镜头固定在无穷远处导致特写模糊作者用小的 udev 规则设置适合手臂距离 QR 扫描和文档拍摄的合理固定对焦此设置可按需调整或通过软件控制对焦。方向方面传感器相对于手机竖屏方向有一定角度安装预览画面最初是横向的。设置设备树的旋转和方向属性后支持 libcamera 的应用程序可正确显示视频流。合并模式方面OV13B10 驱动程序宣传几种分辨率包括 2×2 合并的半分辨率模式。在这个 CAMSS 路径上合并模式产生混乱、扭曲的输出其读取几何形状与声明的帧大小不匹配全分辨率和其他几种模式正常。为避免提供有问题的预览作者禁用这两种有问题的模式让 libcamera 只选择正常模式。代价是因软件 ISP 是裁剪而非缩放1080p 预览是从较大模式中裁剪出来的中心部分会稍微放大而非显示完整的超广角视野。最终在 GNOME 相机/Snapshot 中可看到实时、直立、自动曝光、对焦清晰的预览画面且 QR 扫描功能正常。资源重现这些结果所需的补丁和相关文件可在这个仓库找到[github.com/nondescriptpointer/fairphone6 - wide - camera - linux](https://github.com/nondescriptpointer/fairphone6-wide-camera-linux)局限性这只是实验性开端并非正式的相机支持只有超广角OV13B10相机可用主摄像头IMX896和前置摄像头S5KKD1传感器无主线驱动程序没有自动对焦功能libcamera 的软件 ISP 无对比度自动对焦循环对焦是固定折衷位置要实现真正自动对焦需在软件 ISP 中添加自动对焦算法或在应用程序端添加循环驱动 VCM常见分辨率下预览视野被裁剪因 2×2 合并的传感器模式有问题且软件 ISP 是裁剪而非缩放修复合并模式的寄存器序列或添加缩放器可恢复完整超广角视野电源时序管理简化稳压器是强制开启的而非按顺序开启VCM 在固定对焦位置会消耗空闲电流实验没问题但日常使用需适当电源管理ISP 仅为软件实现所有解拜耳、自动曝光和自动白平衡处理都在软件中进行借助 GPU 辅助对 QR 扫描和日常使用效果不错但无法提供调优的硬件 ISP 管道的图像质量作者没花时间优化图像质量可能需进一步优化从传感器获得更好照片。下一步计划- 修复合并模式恢复完整视野。- 编写适当的电源时序管理。- 准备好可以上游化的部分。

相关新闻