移植一颗新 sensor 到 MTK 平台,改驱动只是开始。真正让你加班的是散落在 10 多个目录里的配置文件 —— 漏一个就是不同的故障现象,而且报错信息几乎不会告诉你漏了哪个。
> 本文以 Sony IMX335(5MP MIPI RAW,工业/安防常用)移植到 MTK ISP_50 平台为例,梳理完整流程、给出检查清单、重点讲 7 个最容易踩的坑。
## 适用范围
| 项目 | 版本 |
|------|------|
| 芯片 | MTK MT67xx / MT68xx (ISP_50) |
| Android | 9 ~ 14 |
| Kernel | 4.14 / 4.19 / 5.10 |
| Sensor | Sony IMX335 5MP (2592x1944, MIPI 4-lane) |
| Sensor 类型 | MIPI RAW(CSI 接入)|
不同内核版本的路径略有差异,但整体流程和坑是一样的。
## 移植全景图
先看全局,再逐步展开。**加粗的是最容易遗漏的步骤**:
```
┌───────────────── Kernel 层 ─────────────────┐
│ 1. kd_imgsensor.h 注册 SENSOR_ID + DRVNAME │
│ 2. imgsensor_sensor_list 注册(v1 + v1_1) │
│ 3. imgsensor_cfg_table.c 电源时序 │
│ 4. defconfig 添加 sensor 名 │
└──────────────────────────────────────────────┘
↓
┌───────────── Device 层(易漏)──────────────┐
│ 5. kernel-headers/kd_imgsensor.h 同步副本 │
└──────────────────────────────────────────────┘
↓
┌───────────────── HAL 层 ─────────────────────┐
│ 6. ProjectConfig.mk 四个 IMGSENSOR 变量 │
│ 7. imgsensor/ver1/{sensor}/ — 3A/ISP 参数 │
│ 8. imgsensor_metadata/{sensor}/ — 平台 meta │
│ 9. sendepfeature/{sensor}/ — feature table │
│ **10. common/hal/.../sensor/{sensor}/ (最致命)**│
│ 11. sensorlist.cpp 注册 │
│ 12. cfg_setting_imgsensor.cpp 配置 │
└──────────────────────────────────────────────┘
↓
┌───────────────── 参数调整 ────────────────────┐
│ 13. 分辨率、镜头、对焦模式匹配 │
└──────────────────────────────────────────────┘
```
## Step 1-4:Kernel 驱动注册
### 1.1 注册 SENSOR_ID
在 `kd_imgsensor.h` 中新增 sensor 的 ID 宏和驱动名字符串:
```c
// kd_imgsensor.h — 新增两行
#define IMX335_SENSOR_ID 0x0335
#define SENSOR_DRVNAME_IMX335_MIPI_RAW "imx335_mipi_raw"
```
### 1.2 注册驱动入口
两个文件需要同步修改:
| 文件 | 修改 |
|------|------|
| `imgsensor_sensor_list.h` | 声明 `IMX335_MIPI_RAW_SensorInit()` 函数原型 |
| `imgsensor_sensor_list.c` | 添加到 `kdSensorList[]` 数组 |
**注意:v1 和 v1_1 两个目录都要放驱动代码。** 原因见踩坑 #3。
### 1.3 电源时序
在 `imgsensor_cfg_table.c` 中添加你 sensor 的上电序列:
```c
// 关键:顺序和电压必须严格按 datasheet
{RST, Vol_Low, 0},
{DOVDD, Vol_1800, 0},
{AVDD, Vol_2900, 0}, // ← IMX335 需要 2.9V,不是标准 2.8V!
{DVDD, Vol_1200, 1},
{SensorMCLK,Vol_High, 1},
{RST, Vol_High, 2}
```
### 1.4 defconfig
```
CONFIG_CUSTOM_KERNEL_IMGSENSOR="imx335_mipi_raw ..."
```
## Step 5:Device 层 kernel-headers 同步
```
device/mediatek/common/kernel-headers/kd_imgsensor.h
```
这是一个**独立的副本**,不会自动和 kernel 的 `kd_imgsensor.h` 同步。HAL 编译时引用的是这个文件。**漏改 = HAL 编译找不到 SENSOR_ID 定义。**
## Step 6-12:HAL 层(核心,也是坑最多的地方)
### 6. ProjectConfig.mk
四个变量都要配:
```makefile
CUSTOM_HAL_IMGSENSOR = imx335_mipi_raw ...
CUSTOM_HAL_MAIN_IMGSENSOR = imx335_mipi_raw # 主摄
CUSTOM_KERNEL_IMGSENSOR = imx335_mipi_raw ...
CUSTOM_KERNEL_MAIN_IMGSENSOR = imx335_mipi_raw
```
少配一个,sensor 能检测到但 HAL 不认。
### 7-10. 四个 HAL 目录(最容易出错)
这是整个移植中最让人头疼的部分 —— **需要创建 4 个目录**,通常从已有 sensor(如 imx258)拷贝并重命名:
| # | 目录路径 | 文件数 | 说明 |
|---|---------|--------|------|
| 1 | `custom/{chip}/hal/imgsensor/ver1/{sensor}/` | ~50+ | 3A/ISP 调优参数 |
| 2 | `custom/{chip}/hal/imgsensor_metadata/{sensor}/` | ~6 | 平台级 metadata |
| 3 | `custom/{chip}/hal/sendepfeature/{sensor}/` | 1 | Feature table |
| **4** | **`custom/common/hal/imgsensor_metadata/sensor/{sensor}/`** | **1** | **Common metadata** |
**第 4 个目录只有 1 个头文件,却是最致命的坑。** 详见踩坑 #5。
### 11-12. 注册和配置
| 文件 | 修改 |
|------|------|
| `sensorlist.cpp` | 添加到 `SensorList[]` |
| `cfg_setting_imgsensor.cpp` | 配置 MCLK、CSI port、FOV 等 |
## Step 13:参数调整
从参考 sensor 拷贝的参数不能直接用,至少要改这些:
| 参数类别 | 必须调整的项 |
|---------|-------------|
| 分辨率 | `ACTIVE_ARRAY_SIZE`、`PHYSICAL_SIZE`、grabwindow |
| 镜头 | 光圈值、焦距 |
| 对焦 | 定焦 sensor 必须关闭 AF,Focus mode 改 `INFINITY + FIXED` |
| GIS | 分辨率和焦距要匹配 |
## 踩坑实录(7 个坑,个个要命)
### 坑 1:I2C 地址搞反(最常见)
模组图纸标的地址和实际地址可能不同,取决于 SLASEL 引脚电平。**先量 SLASEL 电平,再定 I2C 地址。**
MTK imgsensor 框架的 `i2c_addr_table` 填的是 **8-bit write 地址**,框架内部自动右移。如果你填了 7-bit 地址,会被二次右移,通信直接挂。
```c
.i2c_addr_table = {0x34, 0x6C, 0xff}, // ← 8-bit write 地址!
```
**定位方法**:I2C 通信失败一般是 `errno -6 (NACK)`。如果 sensor ID 读出全 0 或 0xFF,先查地址。
### 坑 2:电源时序漏配
`imgsensor_cfg_table.c` 里没有新 sensor 的条目 = sensor 根本没上电 = I2C 全部 ACK error。
**现象**:和坑 1 一样,sensor ID 读出 0/0xFF。区别在于示波器看 I2C 总线上根本没有信号(SDA/SCL 全低),说明是电源问题不是地址问题。
**额外注意**:有些 sensor 的 AVDD 不是标准 2.8V(比如 2.9V),务必查 datasheet 确认每路电源电压。
### 坑 3:v1 和 v1_1 都要放驱动
MTK 有一个 flicker 工具 `genimginfo.py`,它从 `common/v1_1/` 目录搜索驱动信息。只在 `common/v1/` 放驱动会导致编译报错,而且**错误信息完全看不出是因为 v1_1 缺文件**。
**建议**:v1 和 v1_1 放相同代码,改一处同步到另一处。
### 坑 4:device kernel-headers 不同步
上面 Step 5 已经说了。这个坑的恶心之处在于 —— **编译报错说的是 "undeclared identifier",你会下意识去查 kernel 的头文件,发现明明写了**。实际上 HAL 用的是 device 层的副本。
### 坑 5:第 4 个 HAL metadata 目录(最致命!)
```
custom/common/hal/imgsensor_metadata/sensor/{sensor_name}/
```
这个目录只有 **1 个头文件**:`config_static_metadata.sensor.{sensor}mipiraw.h`
但缺了它,**camerahalserver 会 SIGABRT 崩溃无限重启**。
原因链条:
1. 编译时该文件生成 `constructCustStaticMetadata_COMMON_SENSOR_*` 符号
2. 缺文件 = 缺符号 = `libcam.halsensor.so` 中没有对应函数
3. HAL 启动时 `checkSensorData()` 发现 `SENSITIVITY_RANGE` 为空
4. 直接 `abort()`
**定位方法**:
```bash
logcat | grep "camerahalserver\|SIGABRT\|checkSensorData"
```
看到反复出现 camerahalserver 崩溃 + SIGABRT,**第一件事就是检查这个目录**。
### 坑 6:Group Hold 时序导致 AE 暴动
某些 sensor 的曝光计算方式比较特殊。以 IMX335 为例,曝光 = VMAX - SHR0,和常见 sensor 的正向线性关系完全不同。如果 VMAX、SHR0、GAIN 不在同一个 group hold 事务中写入,中间帧的曝光值是错误的组合,导致 AE 反馈失调。
**现象**:画面忽亮忽暗,AE 在极端值间跳动。
**思路**:确保 `set_shutter` 和 `set_gain` 最终在一个 group hold 内统一写入所有相关寄存器。具体实现方式因 sensor 而异,需要看 datasheet 的 group hold 章节。
> IMX335 的 AE 暴动问题我们踩了很深的坑,涉及 MTK ISP_50 AE 算法的 9 层限制机制,后续会专门写一篇深度分析。
### 坑 7:AVDD 电压非标准
不是所有 sensor 都是 AVDD 2.8V。IMX335 就需要 **AVDD 2.9V**(Vol_2900)。填错电压可能出现两种情况:
- 偏低:sensor 不工作或 I2C 不稳定
- 偏高:sensor 短期能用但长期可能损坏
**原则**:每路电源电压必须查 datasheet 确认,不要想当然从参考 sensor 拷贝。
## 移植检查清单
**移植完成后逐项对照,避免遗漏:**
```
Kernel 层
[ ] kd_imgsensor.h 加 SENSOR_ID + DRVNAME
[ ] imgsensor_sensor_list.h/.c 注册(v1 + v1_1 两处)
[ ] imgsensor_cfg_table.c 电源时序(电压逐路确认)
[ ] defconfig 加 sensor 名
Device 层
[ ] kernel-headers/kd_imgsensor.h 同步
HAL 层
[ ] ProjectConfig.mk 四个 IMGSENSOR 变量
[ ] imgsensor/ver1/{sensor}/ — 3A 参数目录
[ ] imgsensor_metadata/{sensor}/ — platform metadata
[ ] sendepfeature/{sensor}/ — feature table
[ ] common/hal/imgsensor_metadata/sensor/{sensor}/ — 最易漏!
[ ] sensorlist.cpp 注册
[ ] cfg_setting_imgsensor.cpp 配置
参数
[ ] 分辨率 ACTIVE_ARRAY / PHYSICAL_SIZE 已改
[ ] 镜头光圈/焦距已改
[ ] 定焦 sensor 已关闭 AF
[ ] GIS 参数已匹配
```
## 总结
MTK Camera Sensor 移植的核心难点不在驱动本身,而在于 **10+ 个分散目录的文件需要逐一创建和配置**。报错信息往往指向别处,很难直接定位到"漏了哪个目录"。
两条实战建议:
1. **建自己的检查清单**(上面那个可以直接用)—— 每次移植照着过一遍,比什么经验都管用
2. **先跑通一颗参考 sensor**(如 imx258),确认全流程没问题后再改成目标 sensor —— 这样出了问题至少能二分定位
1259

被折叠的 条评论
为什么被折叠?



