MTK平台,camera移植步骤
Device:
1、 修改imgsensor相关(ProjectConfig.mk文件)
device/mediateksample/{$PLATFORM}/ProjectConfig.mk
此文件用于将相关模块加入编译。
2、添加sensor信息
在头文件中添加sensor id和 sensor name宏定义,sensor id在该sensor的规格书(datasheet)中搜索寄存器地址。(kd_imgsensor.h)
device/mediatek/common/kernel-headers/kd_imgsensor.h
Kernel:
1、添加驱动
将sensor原厂或是模组厂提供的sensor 驱动放置到如下文件夹:
kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1_1
注意:v1_1这个路径最好看下面路径下的Makefile文件:
kernel-4.19/drivers/misc/mediatek/imgsensor/src/{$PLATFORM}/Makefile
注意看Makefile文件里COMMON_VERSION这个参数是v1还是v1_1,如果是v1,则证明代码最后会编译的是v1,你需要将驱动加在v1路径下,反之亦然。同时还可以去out路径下,看代码编译的哪里,调试的时候out文件是一个重要的参考,调试时看out可以让你知道你的驱动代码有没有被编进内核。out路径参考如下:
out\target\product\{$Project}\obj\KERNEL_OBJ\drivers\misc\mediatek\imgsensor\src\common
这个KERNEL_OBJ就是kernel-4.19这个内核里已经编译到的驱动。
2、 将模组信息添加到头文件
kernel-4.19/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h
3、 在defconfig中添加宏定义让驱动文件编译
kernel-4.19/arch/arm64/configs/xxx_debug_defconfig
kernel-4.19/arch/arm64/configs/xxx_defconfig
4、修改sensorlist
在SensorList中添加sensor id ,sensor name与sensor driver init函数
kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1_1/imgsensor_sensor_list.h
在上面路径的文件里添加函数声明
kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1_1/imgsensor_sensor_list.c
在上面路径的文件里添加数组成员
5、 上电时序配置
kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1_1/imgsensor_pCLKwr_seq.c (没有此文件可不用修改,说明上电时序的配置被移到imgsensor_cfg_table.c这个文件里,这个文件路径在下面的供电方式的配置里)
6、 供电方式配置
需要注意配置的引脚是PMIC供电还是GPIO控制,如果供电由PMIC控制,则需要在对应位置修改为IMGSENSOR_HW_ID_REGULATOR,如果是GPIO配置,则应该为IMGSENSOR_HW_ID_GPIO
Kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6853/camera_hw_mt6833/imgsensor_cfg_table.c
VCAMD:就是DVDD数字供电,主要给ISP供电,所以有些没有ISP的模组没有这个引脚。
VCAMA:就是AVDD模拟供电,主要给感光区和ADC部分供电。
VCAMIO:就是VDDIO数字IO供电,主要给I2C部分供电。
VCAMAF:对焦马达供电。
7、 dtsi相关配置
kernel-4.19/arch/arm64/boot/dts/mediatek/cust_mt6739_camera.dtsi
可以参考其他项目的设备树是如何配置的。
cam0_rst0:后主摄,rst引脚,输出低电平;对应的是pinctrl-1,引用camera_pins_cam0_rst_0这个节点
cam0_rst1:后主摄,rst引脚,输出高电平;对应的是pinctrl-2,引用camera_pins_cam0_rst_1这个节点上下一一对应
以此类推,clk和RST为GPIO供电,需要在&pio中添加子节点定义在GPIO list中搜索R_CAM1_CLK1,R_CAM1_RST1找到对应的GPIO号
RST这路电需要配置的gpio口为GPIO56,camera_pins_cam0_rst_0和camera_pins_cam0_rst_1这两个节点中配置的GPIO口为56, CLK这路电需要配置的gpio口为GPIO50
8、 DWS配置
配置修改dws文件需要使用dtc工具,在代码中如下位置:
vendor/mediatek/proprietary/tools/dct
其中包含了linux版本与windows版本工具。dws文件存放位置如下:
kernel-4.19/drivers/misc/mediatek/dws/
工具中可以配置gpio引脚信息状态,i2c总线上挂载的设备等功能。
注意:在camera点不亮时可以通过在dws里,将gpio强制拉高去排除供电的影响。gpio可以通过dws去拉高,而pmic控制的引脚则可以通过原理图,看该供电引脚是哪个pmic芯片控制,去到对应芯片的dts里,找到这个regulartor的引脚,在后面加上regulator-always-on即可,具体实例如下:
比如你的dts里这样写的:cam0_vcamio-supply = <&mt_pmic_vcamio_ldo_reg>;
同时你的iovdd引脚使用6385芯片供电。那么你就到mt6385这个dts里去找mt_pmic_vcamio_ldo_reg。然后按如下修改:
mt_pmic_vcamio_ldo_reg: ldo_vcamio {
regulator-name = "vcamio";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-enable-ramp-delay = <270>;
+++ regulator-always-on; //配置该引脚常供电
};
Vendor:
1、 在SensorList中添加sensor id ,sensor name与sensor driver init函数
vendor/mediatek/proprietary/custom/common/hal/imgsensor_src/sensorlist.cpp
2、 根据原理图配置MIPI PORT(csi通道号)和MLCK
vendor/mediatek/proprietary/custom/{$Platform}/hal/imgsensor_src/cfg_setting_imgsensor.cpp
3、 新增metadata文件和效果参数文件
vendor/mediatek/proprietary/custom/mt6739/hal/imgsensor/ver1
vendor/mediatek/proprietary/custom/common/hal/imgsensor_metadata/sensor/xxx_mipi_raw/
vendor/mediatek/proprietary/custom/mt6739/hal/imgsensor_metadata/xxx_mipi_raw/
注意:kernel下的imgsensor_sensor_list.c和vendor下的sensorlist.cpp下添加的前后摄前后顺序必须要一致,不然可能会出现相机无法打开、相机效果异常等问题。
资料作用:
Datasheet:用于获取slave address,上下电时序和要求。在配置sensor ID和供电方式时用到。
Gpio map:用于查找各引脚对应的gpio端口号。在配置dtsi的gpio端口号时用到。
硬件原理图:用于查看硬件的信息。用于供电方式供电配置中查看引脚是gpio供电还是pmic供电,在dws配置中查看I2C通道,查看csi和mclk的通道。
模组规格图:可以查看I2C地址,电压配置信息。用于上电时序中三路电压的配置。
附录杂项:
替换文件名字指令:
find 13870* |xargs -i echo mv "{}" "{}" | sed 's/13870/5648/2g' | sh
替换文件内容指令:
#替换单个文件下的内容,比如将文件中的"alidata"替换为"data".
sed -i "s/alidata/data/g" test.txt
#替换某个目录下所有文件中的内容,比如将root目录下所有文件中的"wwwroot"替换为"www".
sed -i "s/wwwroot/www/g" 'grep -rl wwwroot /root'
读取sensor id方法:
法一、adb shell后su切换超级权限使用cat /proc/drivers/camera_info查看
法二、使用手机里mtk自带log工具抓开机log,搜索关键字进行查找。或使用adb shell cat /proc/kmsg >./log.log抓log查看。
重要文件
kernel-4.19\drivers\misc\mediatek\imgsensor:
inc->kd_imgsensor.h -----定义sensor id 和sensor name
src->common->v1(此路径不绝对)->imgsensor_hw.c-----配置camera的供电
src->{project}->camera_hw->imgsensor_cfg_table.c-----配置供电方式以及上电时序
src->common->v1(此路径不绝对)->imgsensor.c-----camera驱动模块的加载,platform总线的注册
camera所遇问题总结:
问题总结:
sensor反向问题
反向180度可在驱动里添加mirror函数去控制摄像头的转向
//此函数用于控制各个模式的方向,如果预览方向异常,就可以在预览模式代码的最后添加此函数来控制相机方向
static void set_mirror_flip(kal_uint8 image_mirror)
{
printk("image_mirror = %d\n", image_mirror);
/********************************************************
*
* 0x3820[2] ISP Vertical flip
* 0x3820[1] Sensor Vertical flip
*
* 0x3821[2] ISP Horizontal mirror
* 0x3821[1] Sensor Horizontal mirror
*
* ISP and Sensor flip or mirror register bit should be the same!!
*
********************************************************/
switch (image_mirror) {
case IMAGE_NORMAL:
write_cmos_sensor(0x3820, ((read_cmos_sensor(0x3820) & 0xFB) | 0x00));
write_cmos_sensor(0x3821, ((read_cmos_sensor(0x3821) & 0xFB) | 0x04));
break;
case IMAGE_H_MIRROR:
write_cmos_sensor(0x3820, ((read_cmos_sensor(0x3820) & 0xFB) | 0x00));
write_cmos_sensor(0x3821, ((read_cmos_sensor(0x3821) & 0xFB) | 0x00));
break;
case IMAGE_V_MIRROR:
write_cmos_sensor(0x3820, ((read_cmos_sensor(0x3820) & 0xFB) | 0x04));
write_cmos_sensor(0x3821, ((read_cmos_sensor(0x3821) & 0xFB) | 0x04));
break;
case IMAGE_HV_MIRROR:
write_cmos_sensor(0x3820, ((read_cmos_sensor(0x3820) & 0xFB) | 0x04));
write_cmos_sensor(0x3821, ((read_cmos_sensor(0x3821) & 0xFB) | 0x00));
break;
default:
printk("Error image_mirror setting\n");
}
}
#endif
//上面的寄存器(0x3820等)根据需求进行替换,可以通过adb向这几个寄存器写值,来验证是否有作用。
反向90度可以在fg_setting_imgsensor.cpp文件里修改角度进行控制,但此文件一般不修改,此文件是相机安装角度,一般不会动。所以相机反向90度最常见的就是在上层进行修改。
I2C报错问题
此问题一般是i2c地址不对,或者相机的上电有问题,才会导致i2c报错。
地址问题可在驱动的.i2c_addr_table
里面修改地址,里面可添加多个地址,后续驱动会轮训验证此table里的地址。
上电问题可用万用表进行排查,量camera三路供电是否正常,avdd,dvdd,iovdd等。同时为了排除是相机的供电问题,可在dws里强行拉高三路供电的电平。拉高电平的方法已在上面dws的配置里有回答。
颜色问题
出现预览时颜色相反的问题(比如拍红色的物品,显示出来的是蓝色)可修改.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_B
此项代码,还可修改为SENSOR_OUTPUT_FORMAT_RAW_Gb、SENSOR_OUTPUT_FORMAT_RAW_Gr、SENSOR_OUTPUT_FORMAT_RAW_R,此四项总有一项是正确的。
分辨率问题
static struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info[5]
此函数可控制相机分辨率,如果配置不对会出现模式切换卡顿、预览画面放大等问题。修改分辨率的同时也要根据要求同步去修改以下内容:
.pre = {
.pclk = 60000000, //record different mode's pclk
- .linelength = 1864, //record different mode's linelength
- .framelength = 1072, //record different mode's framelength 1288
+ .linelength = 1736, //record different mode's linelength
+ .framelength = 1148, //record different mode's framelength
.startx = 0, //record different mode's startx of grabwindow
.starty = 0, //record different mode's starty of grabwindow
.grabwindow_width = 1280, //record different mode's width of grabwindow
.grabwindow_height = 960, //record different mode's height of grabwindow
/* following for MIPIDataLowPwr2HighSpeedSettleDelayCount by different scenario */
- .mipi_data_lp2hs_settle_dc = 14,
+ .mipi_data_lp2hs_settle_dc = 85,
/* following for GetDefaultFramerateByScenario() */
.max_framerate = 300,
},
.cap = {
.pclk = 60000000,
- .linelength = 1864,
- .framelength = 1072,
+ .linelength = 1736,
+ .framelength = 1148,
.startx = 0,
.starty = 0,
.grabwindow_width = 1280,
.grabwindow_height = 960,
- .mipi_data_lp2hs_settle_dc = 14,
- .max_framerate = 250,
+ .mipi_data_lp2hs_settle_dc = 85,
+ .max_framerate = 300,
},
......
//根据自己需求的模式进行修改
前摄对焦问题
要取消前摄的对焦功能,可按以下进行修改:
//vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/focus/src/
//com/mediatek/camera/feature/setting/focus/Focus.java
LogHelper.d(mTag, "[onSingleTapUp] + x " + x + ",y = " + y);
mNeedResetTouchFocus = false;
//step2:Check to restore af lock state and UI when needed.
handleAfLockRestore();
//step3:Clear any focus UI before show touch focus UI
mFocusViewController.clearFocusUi();
- if (mNeedShowFocusUi) {
- mFocusViewController.showActiveFocusAt((int) x, (int) y);
- }
+ // if (mNeedShowFocusUi) {
+ // mFocusViewController.showActiveFocusAt((int) x, (int) y);
+ // }
+ if(getCameraId() == 1){
+ LogHelper.d(mTag, "this.getCameraId() == 1");
+ return false;
+ }else{
+ if (mNeedShowFocusUi) {
+ mFocusViewController.showActiveFocusAt((int) x, (int) y);
+ }
+ }
+
+
mModeHandler.post(new Runnable() {
@Override
public void run() {
mNeedDoAfLock = false;
......
mLockPoint.set((int) x, (int) y);
if (isNeeedCancelAutoFocus) {
mFocusListener.cancelAutoFocus();
}
- triggerAfLock();
+ //triggerAfLock();
+ if(getCameraId() == 1){
+ return;
+ }else{
+ triggerAfLock();
+ }
+
}
});
return false;
}
开启闪光灯拍照,图片偏红问题
//vendor/mediatek/proprietary/custom/mt6771/hal/camera_3a/flashawb_tuning_custom.cpp
MBOOL
isFlashAWBv2Enabled(MINT32 i4SensorDev)
{
switch (i4SensorDev)
{
case NSIspTuning::ESensorDev_Main: // Main Sensor
- return MTRUE;
+ return MFALSE;
case NSIspTuning::ESensorDev_MainSecond: // Main Second Sensor
return MTRUE;
case NSIspTuning::ESensorDev_Sub: // Sub Sensor
return MFALSE;
case NSIspTuning::ESensorDev_SubSecond: // Sub Second Sensor
return MFALSE;
default:
return MTRUE;
}
}
注:以上皆为kernel-5.10之前的移植步骤,kernel-5.10后移植步骤都有了变化,详细参照以下操作。
一、大致区别:
1、camera编译路径新增/device/mediatek/{$platform}/cameraconfig.mk和devices-camera.mk文件
2、同时需要在
vendor\mediatek\proprietary\scripts\soong\mtkcam\mtkcamvars.go此路径添加tunning文件的编译,不然会出现无法点亮的问题。
3、kconfig统一由mgk_64_k510_defconfig来控制
4、如果使用最新的5g架构,那么原来的isp6可能会变为isp7。具体参考out编译哪一块的内容,看自己代码是走的isp6还是isp7的架构。
二、isp6与isp7区别
1、驱动代码路径有所改变kernel-xxx\drivers\misc\mediatek\imgsensor\src_v4l2\common\{$camdrv}
2、驱动架构有所区别,具体请自己看sensor的驱动代码,而且上电(imgsensor_cfg_table.c等上电文件)那一块的内容有所变化,上电已经移到sensor驱动里。