Разработчик запустил на Fairphone 6 ультраширокую камеру под управлением основного Linux — пока экспериментально, но кадры уже видны в GNOME Snapshot. Fairphone 6 интересен тем, что Fairphone сам продвигает поддержку основного ядра, а устройство относительно современное. Главные проблемы для повседневного использования — звук и камера. Этот проект сфокусировался на QR-сканировании, поэтому выбрали камеру, которую проще всего завести: широкоугольную на сенсоре OmniVision OV13B10.
Камера в Qualcomm-смартфонах — это целая цепочка: сенсор → CSI-2 → CSIPHY → CSID → ISP (TFE) → память. В стоке всё это крутится на проприетарном стеке Qualcomm. В основном ядре за это отвечает драйвер qcom-camss и userspace-фреймворк libcamera.
Разработчик выяснил, что чипсет в FP6 — Qualcomm milos (SM7635), а его ISP-блок TFE665 почти один в один совпадает с TFE530, который уже поддерживается. Основное отличие — сдвиг базовых адресов регистров. Это позволило портировать драйвер, не пиша всё с нуля. В итоге добавили camss-vfe-665.c, подтянули CSID665 и CSIPHY v2.2.1 с новыми настройками полосы пропускания, описали весь комплекс в device tree и наткнулись на первую засаду — регистры ISP читались как ноль. Оказалось, не хватало тактовой шины CAM_CC_SOC_AHB_CLK. После её добавления ISP ожил.
Сенсор OV13B10 в основном ядре есть, но он заточен под x86/ACPI. Понадобилось добавить OpenFirmware-совместимость (ovti,ov13b10) для ARM и device tree. Две мелкие, но критичные ошибки: перепутанная нумерация lane (в mainline они нумеруются с нуля, а в downstream с единицы) и неверный номер CSIPHY (нужен был CSIPHY1, а не угаданный с ходу). После этого сенсор начал выдавать поток — но кадры были полностью чёрными.
Главный баг крылся в packer format'е: TFE530 использует 64-битную шину RDI и пакер 0xa, а TFE665 — 128-битную, ему нужен 0x0. Драйвер жёстко прописывал 64-битное значение. Как только поменяли регистр на 0x0, чёрные кадры превратились в картинку — даже тестовый colour-bar сенсора заработал.
Дальше — настройка libcamera. Современная версия 0.7.2 уже знала milos-qcom-camss через generic pipeline. Софтверный ISP на CPU/GPU debayer'ил кадры в RGB примерно с 30 fps. Единственное, что не работало — автоэкспозиция: не было сенсорного helper'а для OV13B10. Аналоговый gain у него линейный: код / 128, как у многих OmniVision. Разработчик добавил класс CameraSensorHelperOv13b10 — автоэкспозиция заработала.
Автофокуса в софтверном ISP libcamera нет. Ультраширокоугольная камера использует voice-coil motor Awinic AW86017, который говорит по протоколу DW9714. Драйвер dw9714 подошёл, фокус двигается. Но без алгоритма автофокуса пришлось зафиксировать его на дистанции, удобной для QR-кодов и документов — через udev-правило.
Ориентацию сенсора поправили через device tree. Проблема с 2×2-binned режимами (половинное разрешение) — они дают мусорные кадры, поэтому их отключили. Из-за этого на 1080p показывается центр кадра с кропом, а не всё поле зрения.
В итоге в GNOME Camera / Snapshot есть живой, правильный предпросмотр с автоэкспозицией и фиксированным фокусом. QR-скан работает. Но это только начало: основная и фронтальная камеры не заведены, нет нормального автофокуса, кропнутое поле зрения, упрощённое управление питанием и чисто софтверный ISP. Все патчи и файлы лежат в репозитории github.com/nondescriptpointer/fairphone6-wide-camera-linux.