Задача казалась тривиальной: подключить модуль камеры Raspberry Pi с сенсором Sony IMX708 к камерному SoC Rockchip RV1106. Формально сценарий рабочий. Драйвер сенсора общается через стандартный V4L2 subdev API, а топология MIPI описывается в Device Tree. В мейнлайне ядра такой перенос обычное дело.
На практике пришлось стыковать два независимых вендорских форка от Rockchip и Raspberry Pi, где одинаковые имена функций в коде ни о чём не говорят.
Задача: носимая камера
Проект – носимая камера для постоянного ношения на теле. Требования жёсткие: максимальная компактность, Single Chip Solution с интегрированной памятью, готовый модуль камеры с автофокусом, низкое энергопотребление.
Выбрали Rockchip RV1106, специализированный камерный SoC со встроенным ISP, аппаратным кодером H.264/H.265 и NPU. Модуль камеры аналогичный Raspberry Pi Camera Module 3 с сенсором Sony IMX708. IMX708 выбирали не ради разрешения: нужен был готовый компактный модуль с моторизованным автофокусом, а альтернативы с меньшим разрешением его не имели. Что драйвера для него в дереве Rockchip нет, знали заранее. В этом и состоял вызов.
Максимальное разрешение на платформе 2304×1296. ISP версии 3.2 принимает не более 3072×1728, а подходящего режима такой геометрии у сенсора нет. Полные 12 Мп здесь не нужны и недостижимы.
Почему нельзя просто взять RPi-драйвер
Переносили не из мейнлайна в вендорское дерево, а из одного вендорского в другое. Rockchip требует от сенсора нестандартный набор ioctl RKMODULE_*. Без них rkaiq с сенсором не свяжется. В RPi-драйвере этого нет. Версии ядра не совпали: rpi-5.15.y против нашего 5.10, таблицы регистров брали из rpi-6.6.y. Итоговый файл – гибрид с начинкой от Raspberry Pi и каркасом от Rockchip.
Исправляю последнее тире:
Итоговый файл собрали как гибрид: начинка от Raspberry Pi, каркас от Rockchip.
PDAF: как rkcif узнаёт про embedded-поток
IMX708 передаёт фазовые данные для автофокуса по второму виртуальному каналу MIPI в виде embedded-строк. В драйвере зарегистрирован один pad. rkcif узнаёт геометрию embedded-потока не через граф падов, а через ответ на ioctl RKMODULE_GET_CHANNEL_INFO. Высота embedded-потока четыре строки: ISP ожидает высоту кратную четырём, фактических данных там меньше.
Четыре места где прописывается новый сенсор
Файл драйвера в drivers/media/i2c/, запись в Kconfig и Makefile, device tree с адресом I2C и описанием падов, IQ-профиль для rkaiq с именем собранным из свойств device tree. Про четвёртое не написано ни в одном руководстве Rockchip. Нашли экспериментально.
Калибровка цвета
Автобаланс белого не сработал: картинка уезжала в зелень. Профиль начинали с файла для другого сенсора, цветокоррекционные матрицы в нём посчитаны под чужие спектральные характеристики. Перешли в ручной режим, сняли эталонную поверхность при известном освещении, рассчитали коэффициенты по каналам. Множители для комнатного LED.
Автофокус
Привод объектива VCM DW9807 на шине I2C. Алгоритм комбинированный: PDAF как основной контур, контрастный как резервный. В норме система работает в замкнутом контуре по фазе. На однородной поверхности фазовые данные пропадают целиком, все 192 зоны сетки с нулевой достоверностью, тогда включается контрастный поиск.
Заключение
Сенсор стримит 2304×1296 на RV1106, автофокус работает по комбинированному алгоритму, цвета откалиброваны. Проекту быть.
Дальше своя плата: перенос device tree на кастомный дизайн, энергобюджет под
Главные задачи при внедрении – правильно зафиксировать критерии качества и отработать синхронизацию на реальной линии в ходе пилота. Остальное масштабируется.
Если у вас есть линия этикетирования и задача сократить возвраты от торговых сетей, расскажите о производстве и скорости линии. Оценим архитектуру решения и формат пилота.