MTK平台Camera移植避坑指南从驱动添加到DWS配置的完整流程基于Kernel 4.19在嵌入式设备开发中Camera模块的移植往往是系统集成中最具挑战性的环节之一。特别是基于MTK平台的Android设备Camera驱动的移植涉及从内核到框架的多层修改任何一个环节的疏漏都可能导致模组无法正常工作。本文将基于Kernel 4.19版本系统性地梳理MTK平台Camera移植的全流程重点解析各环节的关键配置与常见陷阱帮助开发者高效完成Camera模组的集成与调试。1. 环境准备与基础配置移植前的准备工作往往决定了后续调试的顺利程度。首先需要确认开发环境已完整包含MTK平台的标准代码库特别是kernel-4.19目录下的驱动相关代码。建议在开始前收集以下关键文档Camera模组规格书(Datasheet)包含传感器ID、I2C地址、寄存器配置等核心信息硬件原理图明确供电方式PMIC/GPIO及各引脚定义GPIO映射表用于DTS配置中的引脚号确认在ProjectConfig.mk中添加模组编译选项是第一步# device/mediateksample/{$PLATFORM}/ProjectConfig.mk CUSTOM_HAL_IMGSENSOR imx586_mipi_raw ov12a10_mipi_raw CUSTOM_HAL_LENS dw9714af dummy_lens注意多个sensor之间用空格分隔确保新增模组已加入编译列表。2. 内核驱动集成2.1 驱动文件放置与版本确认MTK平台的Camera驱动通常存放在kernel-4.19/drivers/misc/mediatek/imgsensor/src目录下关键是要确定使用common/v1还是common/v1_1路径# 查看平台Makefile确定COMMON_VERSION cat kernel-4.19/drivers/misc/mediatek/imgsensor/src/{$PLATFORM}/Makefile常见问题驱动文件放错路径导致未编译未在defconfig中添加对应宏定义驱动与模组硬件版本不匹配验证驱动是否成功编译ls -l out/target/product/{$Project}/obj/KERNEL_OBJ/drivers/misc/mediatek/imgsensor/src/common/2.2 传感器注册与供电配置在kd_imgsensor.h中添加传感器ID与名称宏定义// kernel-4.19/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h #define IMX586_SENSOR_ID 0x0586供电配置是Camera移植中最易出错的环节之一。在imgsensor_cfg_table.c中需要准确区分PMIC和GPIO供电类型// kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6853/camera_hw_mt6833/imgsensor_cfg_table.c static struct IMGSENSOR_HW_CFG imgsensor_custom_config[] { { .pwr_ctrl { [IMGSENSOR_HW_PIN_DOVDD] { .pin IMGSENSOR_HW_PIN_DOVDD, .type IMGSENSOR_HW_ID_REGULATOR // PMIC供电 }, [IMGSENSOR_HW_PIN_AVDD] { .pin IMGSENSOR_HW_PIN_AVDD, .type IMGSENSOR_HW_ID_GPIO // GPIO供电 } } } };关键点VCAMD(DVDD)、VCAMA(AVDD)、VCAMIO(VDDIO)三路供电必须与原理图严格对应。3. 设备树与DWS配置3.1 DTSI引脚配置设备树配置需要准确定义各控制引脚以主摄RST和CLK为例// kernel-4.19/arch/arm64/boot/dts/mediatek/cust_mt6739_camera.dtsi pio { camera_pins_cam0_rst_0: cam00 { pins_cmd_dat { pinmux PINMUX_GPIO56__FUNC_GPIO56; slew-rate 1; output-low; }; }; camera_pins_cam0_rst_1: cam01 { pins_cmd_dat { pinmux PINMUX_GPIO56__FUNC_GPIO56; slew-rate 1; output-high; }; }; camera_pins_cam0_clk_0: cam02 { pins_cmd_dat { pinmux PINMUX_GPIO50__FUNC_CMMCLK0; }; }; };3.2 DWS调试技巧DWS(Digital Waveform Settings)工具可用于强制控制GPIO状态是排查供电问题的利器定位dws文件kernel-4.19/drivers/misc/mediatek/dws/使用dtc工具转换dws为dtsdtc -I dws -O dts -o output.dts input.dws在GUI工具中强制拉高GPIO电平测试供电对于PMIC控制的供电可在对应regulator添加常开属性mt_pmic_vcamio_ldo_reg: ldo_vcamio { regulator-name vcamio; regulator-min-microvolt 1800000; regulator-max-microvolt 1800000; regulator-always-on; // 关键配置 };4. Vendor层适配4.1 SensorList同步配置Vendor层的sensorlist.cpp必须与内核层的sensor_list.c保持严格一致// vendor/mediatek/proprietary/custom/common/hal/imgsensor_src/sensorlist.cpp ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] { {IMX586_SENSOR_ID, SENSOR_DRVNAME_IMX586_MIPI_RAW, IMX586_MIPI_RAW_SensorInit}, {OV12A10_SENSOR_ID, SENSOR_DRVNAME_OV12A10_MIPI_RAW, OV12A10_MIPI_RAW_SensorInit} };4.2 MIPI与时钟配置根据原理图配置正确的CSI通道和MCLK频率// vendor/mediatek/proprietary/custom/{$Platform}/hal/imgsensor_src/cfg_setting_imgsensor.cpp static struct IMGSENSOR_SENSOR_LIST gImgSensorList[MAX_NUM_OF_SUPPORT_SENSOR] { { imx586_mipi_raw, { {IMGSENSOR_HW_ID_MCLK, IMGSENSOR_HW_PIN_MCLK}, // MCLK引脚 {IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_AVDD}, // 模拟供电 {IMGSENSOR_HW_ID_REGULATOR, IMGSENSOR_HW_PIN_DOVDD}, // 数字供电 {IMGSENSOR_HW_ID_NONE, IMGSENSOR_HW_PIN_NONE}, }, .mipi_sensor_idx 0, // CSI通道号 .mclk 24, // MHz } };5. 常见问题排查指南5.1 I2C通信失败典型表现内核日志中出现i2c transfer failed错误排查步骤确认I2C地址与规格书一致检查供电是否正常AVDD/DVDD/VDDIO使用示波器检查SCL/SDA信号质量在驱动中启用调试日志// 在sensor驱动中添加 #define DEBUG_I2C static int i2c_read_reg(struct i2c_client *client, u16 reg, u8 *val) { int ret; struct i2c_msg msg[2] { { .addr client-addr, .flags 0, .len 2, .buf (u8 *)reg, }, { .addr client-addr, .flags I2C_M_RD, .len 1, .buf val, } }; ret i2c_transfer(client-adapter, msg, 2); #ifdef DEBUG_I2C pr_info(i2c read: reg0x%04x, val0x%02x\n, reg, *val); #endif return ret; }5.2 图像异常处理颜色异常修改输出数据格式尝试不同Bayer模式.sensor_output_dataformat SENSOR_OUTPUT_FORMAT_RAW_R, // 尝试R/Gr/Gb/B图像倒置通过寄存器配置镜像模式static void set_mirror_flip(kal_uint8 image_mirror) { write_cmos_sensor(0x3820, ((read_cmos_sensor(0x3820) 0xFB) | 0x04)); write_cmos_sensor(0x3821, ((read_cmos_sensor(0x3821) 0xFB) | 0x00)); }分辨率问题检查imgsensor_winsize_info结构体配置static struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info[5] { .pre { .pclk 60000000, .linelength 1736, .framelength 1148, .grabwindow_width 1280, .grabwindow_height 960, .mipi_data_lp2hs_settle_dc 85, } };5.3 调试工具与技巧寄存器调试adb shell echo 0x1234 0x56 /proc/camera_reg供电测量使用万用表测量AVDD/DVDD/VDDIO电压检查上电时序是否符合规格书要求日志分析adb logcat -b kernel | grep imgsensor adb shell cat /proc/kmsg kmsg.log固件版本确认adb shell getprop | grep camera在实际项目中遇到过一个典型案例Camera模组能正常上电但无法输出图像最终发现是DTS中的MIPI时钟极性配置错误。通过对比正常项目的设备树配置将camera_mipi_clk_sel从0改为1后问题解决。这提醒我们即使是相同的硬件平台不同项目间的微小配置差异也可能导致功能异常。