1. 开篇为什么需要从零开始集成Camera驱动第一次接触Camera驱动开发的朋友可能会有疑问为什么不能直接用芯片厂商提供的参考代码其实这个问题我也遇到过。记得三年前接手第一个MTK平台项目时拿着原厂的BSP包信心满满结果插上我们自己定制的摄像头模组后系统直接卡在开机动画。后来花了整整两周时间才搞明白原来参考设计里的上电时序和我们的硬件设计完全不匹配。Camera驱动集成之所以需要从零开始核心原因有三点硬件差异每个摄像头模组的供电需求、I2C地址、寄存器配置都可能不同平台特性不同SoC的ISP处理管线、时钟架构存在差异系统适配Android HAL层的接口规范每年都在演进以最常见的OV5647传感器为例虽然数据手册标注的标准供电电压是2.8V但实际项目中我们发现某些批次模组在2.6V时画质更稳定。这种细节只有通过完整走一遍驱动集成流程才能发现。2. 环境准备搭建开发环境2.1 获取必要的代码仓库MTK平台开发需要同步多个代码仓库这里分享一个高效的方法# 先初始化repo mkdir mtk-camera-dev cd mtk-camera-dev repo init -u https://source.codeaurora.org/quic/le/platform/manifest -b alps-mp-m0.mp1 # 修改manifest.xml添加摄像头相关仓库 cat EOF .repo/local_manifests/camera.xml manifest project pathvendor/mediatek/proprietary/hardware/mtkcam nameplatform/vendor/mediatek/proprietary/hardware/mtkcam / project pathkernel-4.19/drivers/misc/mediatek/imgsensor nameplatform/kernel-4.19/drivers/misc/mediatek/imgsensor / /manifest EOF # 同步代码建议晚上跑需要下载约30GB数据 repo sync -j8同步完成后重点关注以下目录kernel-4.19/drivers/misc/mediatek/imgsensor/传感器驱动核心代码vendor/mediatek/proprietary/hardware/mtkcam/HAL层实现device/mediatek/mt6765/设备树配置文件2.2 工具链配置MTK平台推荐使用预编译的工具链wget https://cdn.mediatek.com/tools/arm-eabi-4.8.tgz tar xzf arm-eabi-4.8.tgz -C ~/toolchains/ export PATH$PATH:~/toolchains/arm-eabi-4.8/bin验证工具链是否生效arm-eabi-gcc --version # 应该输出类似 gcc version 4.8.x 的信息3. 驱动集成实战3.1 创建传感器驱动目录假设我们要集成的传感器是Sony IMX586操作步骤如下在kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6765/下新建目录mkdir imx586_mipi_raw复制基础文件模板cp ov5647_mipi_raw/Makefile imx586_mipi_raw/ cp ov5647_mipi_raw/kd_sensorlist.c imx586_mipi_raw/修改Makefile关键参数obj-y imx586mipiraw_Sensor.o obj-y imx586mipiraw_otp.o注意MTK平台强制要求驱动文件名格式为传感器名mipirawSensor.o3.2 配置上电时序这是最容易出错的环节分享一个真实案例的配置// 在imx586mipiraw_Sensor.c中添加 static struct regval_list imx586_init_setting[] { {0x0100, 0x00}, // 先确保传感器处于休眠状态 // AVDD 2.8V {REGULATOR_TYPE_AVDD, 2800000, 1, 0, 0}, // DVDD 1.2V (注意IMX586需要先于IOVDD上电) {REGULATOR_TYPE_DVDD, 1200000, 1, 1000, 0}, // 延迟1ms // IOVDD 1.8V {REGULATOR_TYPE_IOVDD, 1800000, 1, 500, 0}, // 延迟0.5ms // MCLK 24MHz {CLK_TYPE_MCLK, 24000000, 1, 10, 0}, // 复位信号 {RST_TYPE_PDN, 1, 5, 0, 0}, // 拉高复位5ms {0x0100, 0x01}, // 唤醒传感器 {0x0000, 0x00} // 结束标记 };常见坑点电压值单位是微伏(μV)延迟时间单位是微秒(μs)必须严格按数据手册要求的顺序上电3.3 配置HAL层在vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6765/中修改添加传感器枚举// mtk_sensorlist.cpp static MUINT32 g_SupportedSensors[] { SENSOR_DRVNAME_IMX586_MIPI_RAW, // ...其他传感器 };配置3A参数!-- imx586_mipi_raw_param.xml -- aaaParams aeParams expModeFRAME_RATE_LIMITATION/expMode minGain1.0/minGain maxGain16.0/maxGain /aeParams /aaaParams4. 系统级配置4.1 修改ProjectConfig.mk在device/mediatek/mt6765/ProjectConfig.mk中添加# 摄像头数量 CUSTOM_HAL_IMGSENSOR imx586_mipi_raw # 主摄像头配置 CAMERA_HAL_VERSION 3 MTK_CAM_MAX_NUMBER_OF_CAMERA 24.2 更新内核defconfigcd kernel-4.19 make menuconfig勾选以下选项Device Drivers --- Multimedia support --- [*] MediaTek Camera Support [*] IMX586 MIPI RAW Sensor保存后会自动生成.config文件但还需要手动更新平台配置echo CONFIG_CUSTOM_KERNEL_IMGSENSOR\imx586_mipi_raw\ arch/arm64/configs/mt6765_defconfig5. 调试技巧与常见问题5.1 日志分析技巧MTK平台提供了专用调试命令# 查看传感器注册情况 adb shell cat /proc/mtkcam/seninf/seninf1 # 实时查看I2C通信 adb shell echo 1 /sys/kernel/debug/camera_i2c/enable adb logcat | grep CAM_I2C典型错误日志分析[seninf] ERR: cam_mclk_set error时钟配置错误[imgsensor] ERR: write_cmos_sensor 0x1234 failI2C通信失败5.2 硬件排查清单当摄像头无法正常工作时建议按以下顺序排查用万用表测量各供电引脚电压用示波器检查MCLK时钟信号确认I2C线路上拉电阻是否正常检查PCB走线是否满足MIPI差分对要求6. 验证与优化6.1 基础功能测试编写简单的测试脚本# camera_test.py import cv2 for i in range(10): cap cv2.VideoCapture(i) if cap.isOpened(): print(fCamera index {i} found!) ret, frame cap.read() cv2.imwrite(f/sdcard/test_{i}.jpg, frame) cap.release()6.2 性能优化参数在imx586mipiraw_Sensor.c中调整static struct SET_PD_BLOCK_INFO_T imx586Mipiraw_pd_table { .i4OffsetX 0, .i4OffsetY 0, .i4PitchX 16, // 根据实际PD分布调整 .i4PitchY 16, .i4PairNum 8, // 相位对数量 };实际项目中我们发现将i4PitchY从默认值32改为16后对焦速度提升了约15%。