4. Sensor上电时序与初始化
本章是 Camera Sensor 驱动开发的核心基础。Sensor 作为模拟与数字混合器件,其启动过程必须严格遵循电源、时钟与复位信号的时序要求。任何时序违规都可能导致 Sensor 初始化失败、ID 读取错误或输出异常图像。本节将深入解析 DVDD/AVDD/IOVDD 电源管理、XSHUTDOWN/RESET 时序、PLL 配置与帧率计算,并结合骁龙平台的实际驱动实现进行讲解。
4.1 电源域:DVDD / AVDD / IOVDD
现代 Sensor 通常需要三路独立电源,分别供给数字核心、模拟电路和 IO 接口。各路电源的上电顺序、电压精度和纹波要求直接影响 Sensor 的启动成功率与噪声性能。
| 电源域 | 典型电压 | 供电对象 | 关键要求 |
|---|---|---|---|
| DVDD (Digital Core) | 1.05V – 1.2V | 数字逻辑、PLL 数字部分、MIPI 数字 PHY | 上电顺序通常最先;纹波 < 20mVpp |
| AVDD (Analog) | 2.8V – 3.3V | 像素阵列、模拟读出、ADC、PLL 模拟部分 | 噪声敏感,需低噪声 LDO;通常最后上电 |
| IOVDD (IO / MIPI) | 1.8V 或 2.8V | I2C/SPI 接口、MIPI CSI 差分 IO、GPIO | 需与主控 SoC 的 IO 电压匹配;上电顺序在 DVDD 之后 |
实战提示: 在骁龙平台上,PMIC(如 PM8150L)的 LDO 输出通常通过
cam_sensor_subdev 驱动中的 regulator_set_voltage 和 regulator_enable 进行控制。务必在 dtsi 中配置 vin-supply 属性,确保驱动框架能正确管理电源域。
4.1.1 上电时序要求
Sensor 数据手册会给出严格的电源建立时序图。以下是一个典型的三路电源上电时序示例:
- DVDD 先上电:从 0V 上升到 90% 目标电压的时间(t1)通常 < 100µs。
- IOVDD 随后:在 DVDD 稳定后(t2)开始上升,延迟通常为 0 – 1ms。
- AVDD 最后:在 IOVDD 稳定后(t3)开始上升,延迟通常为 0 – 5ms。
- XSHUTDOWN 释放:在所有电源稳定后(t4),将 XSHUTDOWN 拉高,延迟通常为 1 – 10ms。
常见错误: 若 AVDD 先于 DVDD 上电,可能导致 Sensor 内部 ESD 保护二极管正向导通,造成 latch-up 或永久损坏。驱动开发时务必在 probe 函数中按顺序使能 regulator。
4.2 XSHUTDOWN / RESET 时序
XSHUTDOWN 引脚是 Sensor 的硬件使能/复位控制。在电源稳定后,驱动必须通过 GPIO 控制该引脚从低电平切换到高电平,并等待 Sensor 内部初始化完成。
4.2.1 时序参数
| 参数 | 最小值 | 典型值 | 最大值 | 说明 |
|---|---|---|---|---|
| t_XSHUT_LOW | 1 ms | 5 ms | 10 ms | XSHUTDOWN 拉低后保持低电平时间 |
| t_XSHUT_HIGH | 1 ms | 5 ms | 20 ms | XSHUTDOWN 拉高后等待 Sensor 就绪 |
| t_RESET_PULSE | 100 µs | 1 ms | 5 ms | RESET 引脚低脉冲宽度(若独立) |
驱动实现要点: 在 Linux 内核驱动中,使用
gpiod_set_value_cansleep 控制 XSHUTDOWN GPIO,然后调用 msleep 或 usleep_range 实现延迟。避免使用 mdelay 在原子上下文中阻塞。
4.3 PLL 配置与帧率计算
Sensor 内部的 PLL(锁相环)负责将外部主时钟(MCLK)倍频到像素时钟(PCLK),进而驱动像素阵列的读出速率。PLL 配置直接决定帧率、行时间和数据输出带宽。
4.3.1 PLL 架构
典型的 Sensor PLL 包含以下可编程分频器:
- MCLK:外部输入时钟,通常为 6 – 27 MHz。
- PLL_MULT(M):倍频因子,决定 VCO(压控振荡器)频率。
- PLL_DIV(N):VCO 后分频,得到 PCLK。
- VT_SYS_CLK_DIV:像素读出时钟分频。
- OP_SYS_CLK_DIV:MIPI 接口时钟分频。
4.3.2 帧率计算公式
帧率(FPS)由以下参数决定:
FPS = PCLK / (HTS × VTS)
其中:
PCLK = MCLK × M / N / VT_SYS_CLK_DIV
HTS = 水平总像素数(包括 blanking)
VTS = 垂直总行数(包括 blanking)
计算示例: 假设 MCLK = 24 MHz,M = 32,N = 2,VT_DIV = 1,则 PCLK = 24 × 32 / 2 / 1 = 384 MHz。若 HTS = 2000,VTS = 1125,则 FPS = 384,000,000 / (2000 × 1125) ≈ 170.7 FPS。
4.3.3 骁龙平台 PLL 配置实战
在骁龙 Camera 驱动中,PLL 参数通常通过 sensor_lib 结构体中的 pll_params 数组传递给 Sensor 的寄存器写入函数。以下是一个典型的 PLL 配置代码片段:
static struct camera_sensor_pll_params pll_config_1920x1080_30fps = {
.mclk = 24000000, // 24 MHz
.pll_mult = 32, // M
.pll_div = 2, // N
.vt_sys_clk_div = 1, // VT_DIV
.op_sys_clk_div = 4, // OP_DIV
.frame_length_lines = 1125,// VTS
.line_length_pck = 2000, // HTS
.output_width = 1920,
.output_height = 1080,
};
static int sensor_set_pll(struct camera_sensor_device *sdev,
struct camera_sensor_pll_params *pll)
{
uint32_t pclk, fps;
// 计算 PCLK
pclk = pll->mclk * pll->pll_mult / pll->pll_div / pll->vt_sys_clk_div;
// 计算帧率
fps = pclk / (pll->frame_length_lines * pll->line_length_pck);
dev_info(sdev->dev, "Target FPS: %d, PCLK: %d Hz\n", fps, pclk);
// 写入 Sensor 寄存器(I2C 通信)
sensor_write_reg(sdev, 0x0301, pll->pll_mult & 0xFF);
sensor_write_reg(sdev, 0x0303, pll->pll_div & 0xFF);
sensor_write_reg(sdev, 0x0305, pll->vt_sys_clk_div & 0xFF);
sensor_write_reg(sdev, 0x0307, pll->op_sys_clk_div & 0xFF);
sensor_write_reg(sdev, 0x0340, (pll->frame_length_lines >> 8) & 0xFF);
sensor_write_reg(sdev, 0x0341, pll->frame_length_lines & 0xFF);
sensor_write_reg(sdev, 0x0342, (pll->line_length_pck >> 8) & 0xFF);
sensor_write_reg(sdev, 0x0343, pll->line_length_pck & 0xFF);
return 0;
}
带宽约束检查: 配置 PLL 后,务必验证 MIPI 数据速率是否超过骁龙 CSI 接收器的最大支持速率(例如 2.5 Gbps/lane)。若超出,需降低 OP_DIV 或减少 MIPI lane 数。
4.4 初始化流程总结
完整的 Sensor 初始化流程可归纳为以下步骤:
- 电源使能:按 DVDD → IOVDD → AVDD 顺序使能 regulator。
- 时钟提供:通过 SoC 的 GPIO 或时钟控制器输出 MCLK。
- 硬件复位:拉低 XSHUTDOWN,等待 t_XSHUT_LOW 后拉高。
- I2C 通信建立:读取 Sensor 的 Chip ID 寄存器,验证通信正常。
- PLL 配置:写入 M/N/VT_DIV/OP_DIV 等寄存器,设置目标帧率。
- Streaming 开启:写入 0x0100 = 0x01,Sensor 开始输出图像数据。
| 步骤 | 驱动函数 | 关键检查点 |
|---|---|---|
| 1. 电源使能 | sensor_power_up() | regulator 是否返回成功?电压是否稳定? |
| 2. 时钟提供 | clk_prepare_enable() | MCLK 频率是否与 dtsi 配置一致? |
| 3. 硬件复位 | gpiod_set_value() | XSHUTDOWN 时序是否满足数据手册? |
| 4. I2C 通信 | sensor_read_chip_id() | 读取的 ID 是否与预期匹配? |
| 5. PLL 配置 | sensor_set_pll() | 计算帧率是否在目标范围内? |
| 6. Streaming | sensor_start_streaming() | MIPI CSI 是否检测到同步头? |
调试技巧: 在骁龙平台上,使用
cam_sensor_debug 内核参数可以打印详细的电源和时序日志。例如:echo 0x1F > /sys/module/cam_sensor_core/parameters/debug_mask。
掌握本节内容后,你将能够独立完成 Sensor 驱动的电源管理、时序控制与 PLL 配置,为后续的 ISP 调优和图像质量优化打下坚实基础。