Front Sensor Bringup
1、Camera 框架介绍:
Camera
的框架分为 Kernel
部分和 hal
部分,其中kernel
部分主要有两块:
image sensor driver
,负责具体型号的sensor
的id
检测,上电,以及在preview
、capture
、初始化
、3A
等等功能设定时的寄存器配置;isp driver
,通过DMA
将sensor
数据流上传;
HAL
层部分主要有三部分组成:
imageio
,主要负责数据buffer
上传的pipe
;drv
,包含imgsensor
和isp
的hal
层控制;feature io
,包含各种3A
等性能配置;
2、Camera Bringup 需要配置的文件(本文以hi1634q型号的前摄为例,平台是mt6789,kernel版本为5.10)
2.1、Device Config Files
修改时删除多余的 sensor driver name,只保留自己的即可;
/device/mediateksample/k6789v1_64
ProjectConfig.mk
/device/mediatek/mt6789
CameraConfig.mk
device-camera.mk
注意:CUSTOM_HAL_IMGSENSOR 、CUSTOM_HAL_SUB_IMGSENSOR 、CUSTOM_KERNEL_IMGSENSOR 、CUSTOM_KERNEL_SUB_IMGSENSOR 这四个必须都要指定 sensor name;不能遗漏!
/device/mediatek/common/kernel-headers
kd_imgsensor.h
指定 sensor name 和 sensor model id !这里一定要check不能出错!
2.2、Kernel Config Files
/kernel-5.10/arch/arm64/configs
mgk_64_k510_defconfig
修改时删除多余的 sensor driver name,只保留自己的即可;
/kernel-5.10/drivers/misc/mediatek/imgsensor/inc
kd_imgsensor.h
指定 sensor name 和 sensor model id 和 device config files 那边修改一样!这里一定要check不能出错!
/kernel-5.10/arch/arm64/boot/dts/mediatek
cust_mt6789_camera.dtsi
(1)修改 cust_mt6789_camera.dtsi
中 pio
节点的各个Pin number
,其中 1 对应 sensor index
, 最好是将其他不相关的 sensor
定义都删除,排除干扰,提供一个干净整洁的代码!并将文件中 kd_camera_hw1
节点中的 pin
增加对应节点,rst
引脚和 mclk
引脚需要根据原理图上的信息去 map
查找,具体对应的是哪个 gpio
引脚,pinctrl
也只需要保留对应节点即可(必须从0开始递增,否则遍历会出错!),如下图红圈部分:
(2) 在 cust_mt6789_camera.dtsi
文件中 kd_camera_hw1
节点中将采用 PMIC
供电方式的 pin
增加如下子节点,再加一个 cust-sensor = “sensor_mipi_raw”
,或者是 cam1_enable_sensor = “sensor_mipi_raw ”
(方便匹配指定sensor
):
(3)在对应的 i2c
总线中定义 camera
设备,i2c0
到 i2c8
,具体是哪一条 i2c
路线需要到原理图查找,同时设备在 i2c
线上的地址是 sensor
的物理地址的高七位的值(实际过程中此地址只需要不和 i2c
路线的其它设备地址冲突即可,但是为了便于查找,尽量使用高七位的地址),同时删除无关的设备配置,包括其它的camera sensor
、eeprom
相关、点亮 sensor
的原理图上不存在的引脚配置。
/kernel-5.10/drivers/misc/mediatek/imgsensor/src/common/v1_1
hi1634q_mipi_raw
此目录下添加驱动文件,仿照类似型号 sensor
修改成自己的,然后改成自己的名字,删除 mipi_raw
下的eeprom
以及 makefile
中的 eeprom
相关,排除干扰项。
到 sensor.c
和 sensor.h
文件修改具体内容,主要包括 imgsensor_info
、init_setting
、preview_setting
等 mode setting
中的数据、winsize_info
数据修改,最后修改 driver
的入口函数 XXX_MIPI_RAW_SensorInit()
,一般在 sensor.c
文件最下面。
imgsensor_sensor_list.c
imgsensor_sensor_list.h
imgsensor_sensor_list.h
中添加相应的 sensor
的 init
(入口函数) 的函数;
imgsensor_sensor_list.c
中添加相应的 sensor
的id
、name
、init
(入口函数) ,注意顺序和 vendor
层相对应,此处需要注意的是最好把位置放在你对应sensor idx
的位置上,这样就不会有匹配出错的情况出现。
imgsensor_pwr_seq.c
此文件中修改引脚电压值以及上电延时等信息,注意 sensor driver name
的大小写,同时严格按照 sensor data
上电模块的说明,添加延时。需要注意的是 AVDD, DVDD, DOVDD
的电压需要确认是否正确,并且在上完前两路电之后第三路电最好加个 1ms 的延迟,不然可能会出现意料之外的问题;
/kernel-5.10/drivers/misc/mediatek/imgsensor/src/common/v1_1/camera_hw/
imgsensor_cfg_table.c
此处修改硬件配置信息,主要是三路电的配置,是 regulator 还是 gpio类型的,如果 sensor 原理图有其它引脚,也可以继续添加,同时删除原理图不存在的引脚,例如 pdn 引脚。
2.3、Vender Config Files
/vendor/mediatek/proprietary/custom/common/hal/imgsensor_src
sensorlist.cpp
Note: sensorlist.cpp
中的 SensorList[]
与 imgsensor_sensor_list.c
中的 gimgsensor_sensor_list
的 sensor
的顺序必须一致,否则 user space
和 kernel space
在通过 ioctl
传递命令 id
时会对应错误。
/vendor/mediatek/proprietary/custom/mt6789/hal/imgsensor_src
cfg_setting_imgsensor.cpp
注意:kernel 底层的MCLK_0/1/2 ----> 分别对应HAL层的 MCLK_1/2/3
Tunning文件
Note:
(1)Tuning Parameter 与 Metadata 可以采用下图作为参考,参考复制对应文件夹并将其中所有的Sensor Name、Sensor Id等更改成当前需要porting的sensor的对应名称,一共三处。此处需要注意:参考的sensor tunning 配置必须对应上,例如 前摄只能参考和 sub 相关的文件配置,否则会出现踩内存现象;
(2) 修改过程中注意 sensor name 和 driver 驱动的大小写问题即可,具体的 mediatek 信息不会影响点亮阶段,但会对后续的出图细节有影响,需要点亮之后再进行调试
(3)Kernel
版本号可以根据当前 Project
的 ProjectConfig.mk
中的 LINUX_KERNEL_VERSION
得知。
Driver
是 v1_1
或者其他版本可以通过 Platform
下的 Makefile
中的 COMMON_VERSION
得知。
/vendor/mediatek/proprietary/custom/mt6789/hal/imgsensor/ver1/
/vendor/mediatek/proprietary/custom/mt6789/hal/imgsensor_metadata/
/vendor/mediatek/proprietary/custom/common/hal/imgsensor_metadata/sensor/
/vendor/mediatek/proprietary/scripts/soong/mtkcam/
mtkcamvars.go
/vendor/mediatek/proprietary/tools/dct/dws/mt6789
-
k6789v1_64.dws
dws(设备树相关)check gpio,一般不需要改动。
/vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/drv/
IHalSensor.h
检查一下信息是否和 kernel
层信息相同或者是否需要添加 sensor
,一般不需要改动。
3、总结
通过上面的代码流程,可以知道上开机时,camera
模块先会将所有的MCLK
打开,然后对依次对对应的sensor
进行上电,读取ID
(判断I2C
是否正常通讯)。这部分调试过程中遇到的问题总结如下:
3.1、注意事项
kernel
重要的是module
的驱动代码和设备树添加,驱动代码的改动需要根据模组厂给的配置文档,一般里面包含了驱动的所有信息,包括一些dts
配置、init setting
、i2c_addr
、分辨率(注意屏比例)、上电时序等一些重要信息device
中config.mk
文件修改后,要将out
相关所有目录删除,再全部编译,否则会导致踩内存的橙色界面vender
参考的sensor tunning
配置必须对应上,例如 前摄只能参考和sub
相关的文件配置,否则会出现踩内存现象- 参考
sensor
进行复制替换时注意大小写的问题!!! - 注意排除干扰项、无关项,单独点亮一颗
sensor
时,先到config
文件删除其余无关的sensor
驱动,eeprom
相关的也删除,camera
设备原理图没有的引脚也要到dtsi
和上电相关的文件cfg_table.c
中删除。
3.2、ID读取不到,I2C不通
- 检查上电时序,3项电压(
AVDD/DVDD/IOVDD
)是否正确; - 检查
kernerl
层的imgsensor_sensor_list.c
和vendor
层的sensorlist.cpp
中的位置是否一致。 I2C
地址及通道设置是否正确;- 确认
i2c
可以正常通信,通过万用表看看有无电流,万用表也可以用来测量配置的regulator
是否正确,测量电压时首先屏蔽imgsensor_hw.c
中的下电代码,最后编译完成,通过i2c write/read
工具读写寄存器,将对应regulator
的所有电源全部打开,之后测量电压。 - 检查
cfg_setting_imgsensor.cpp
中MCLK
和HW
链接配置是否正确; - 如果还是无法读到
sensor id
,先熟悉以下驱动代码以及上电代码,通过打印 log 的方式检查具体执行到哪个模块:camera
的入口在imgsensor.c
最下方的 init 函数,通过它绑定一个platform
的驱动,我们在到驱动对应的probe
函数下看它如何执行,主要包括设备的匹配注册,imgsensor_hw_init
,imgsensor_proc_init
,sensorlist_init
,其中上电部分的代码通过imgsensor_hw_init
到达imgsensor_hw.c
文件,获取硬件信息配置之后分别到平台定义的标准化接口mclk.c
、regulator.c
、gpio.c
中执行标准化接口,这样一路打印 log,大概率会发现上电过程哪里出现问题,根据问题去检查对应模块。 - 读到
sensor id
之后,如果相机无法预览,需要到imgsensor.c
以及驱动代码中检查open
之后的执行情况,check 驱动中的init_setting
、mode setting
、imgsensor_winsize_info
是否正确。
3.3、Camera 启动时间过长
- 检查
Sensor
上电时序要求的延时,是否有偏长的情况; - 去掉多余的
I2C
地址,因为大部分驱动会多添加一些地址; OTP
的加载调整到每次开机时第一次打开加载,之后不加载;sensorInit
如果时间过长,可以调节I2C speed(400->1000)
;