OTP学习

//TODO高通部分的介绍参考网上某篇模块,找到后会在这里加上引用

1、名词解释

1.1 OTP

Camera Module一般会采取两种方式来记录该Sensor的一些信息

1、OTP:One Time Programmable。

在嵌入式系统中,所有代码和系统数据都被存储在FLASH芯片内部。FLASH芯片可多次擦写,且掉电数据不丢失。为了保护FLASH中的数据,厂商提供OTP寄存器,OTP这个寄存器只可以编写一次,之后不能修改。

2、EEPROM:全称“电可擦除可编程只读存储器”( Electrically Erasable Programmable Read - Only Memory),手机中camera模块的EEPROM主要用来存储OTP数据,用来进行校准,来保持模组一致性。

1.2 OTP数据包括

Module Info:物料ID、日期、镜头、VCM等基本信息

 LSC:lens shading calibration data

 AWB:R、Gr、Gb、B的通道值或比值

 AF:远、近焦的position对应DAC值

PDAF:SPC和DCC的data

1.3 Platform OTP

    Sensor没有OTP自校准功能,需要我们BB端进行校正。从存储空间(外挂eeprom或者sensor内部存储空间)中读出数据,然后将数据送到BB端进行校正

1.4 Sensor OTP

    Sensor有OTP自校准功能, 从存储空间(外挂eeprom或者sensor内部存储空间)中读出数据,然后写回sensor寄存器,送到BB端的Raw Data是已经校准过的数据

2、OTP存储方式

Sensor:在sensor芯片中ROM,和sensor公用I2C bus和read/write id

OTP数据烧录在sensor的寄存器中。 这种方案省钱,不需要额外的存储器件,但是存储空间小,如果需要烧录的数据量过大,就不适用。

Sensor:sensor外挂的EEPROM,和sensor公用I2C bus,但具有不同的read/write id

该方案优势是存储空间大,如果数据量过多,就需要这种方案,缺点是多一个独立的EEPROM存储器件。

3、OTP作用

       OTP是用来给camera sensor做calibration(校准)用的。 因为模组生产出来会有很大的差异性,为了保证效果一致性, 模组厂会挑选一部分模组作为golden,然后将其他模组的相应参数校准到和这些golden一样, (golden不是最好的模组,也不是最差的模组,而是各方面最平均的模组)

4、代码实现

    4.1 MTK代码

     4.1.1 Platform OTP

 如果是MTK平台,首先需要读文档:MT6779_OTP_Porting_Guide.pdf

Using eeprom_drive.c, cam_cal_list.c as OTP adapter

Kernel modification

/Kernel-4.9/arch/arm64/boot/dts/mediatek/cust_tb8768_camera.dtsi

/kernel-4.9/drivers/misc/mediate/dws/mediatek/mt6765/tp8768tp1_64_bsp.dws

/Kernel-4.9/arch/arm64/configs/achilles6_prc_wifi_defconfig

/Kernel-4.9/arch/arm64/configs/ achilles6_prc_wifi_debug_defconfig

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/common/v1/eeprom_drive.c

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/mk6765/cam_cal_list.c

 

Hal modification

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal.cpp

Platform OTP 框架

OTP学习_第1张图片

Step1check dtsi and defconfig

/kernel-4.9/drivers/misc/mediate/dws/mediatek/mt6765/tp8768tp1_64_bsp.dws

配置main/sub eeprom地址,不能配置一样就行避免冲突(但实际上这块配置在不同CHANNEL,不会有冲突)。这块有工具配置(dws 工具路径:

./vendor/mediatek/proprietary/scripts/dct/DrvGen.exe

        

  

通过上述截图可以发现,CAMERA_MAIN_EEPROM、CAMERA_SUB_EEPROM的通讯地址分别是0x50、0x52。对应生成cust.dtsi文件

cust.dtsi在对camera的配置

文件路径:

/out/target/product/tb8768tp1_64_bsp/obj/KERNEL_OBJ/arch/arm/boot/dts/ tb8768tp1_64_bsp /cust.dtsi

OTP学习_第2张图片

代码中想要成功调用到对应的 eeprom_hw_i2c_probe() 和eeprom_hw_i2c_probe2() 函数需要分别匹配上 cust.dtsi 文件中的 compatible 节点 “mediatek,camera_main_eeprom” 和 "mediatek,camera_sub_ eeprom "

OTP学习_第3张图片

OTP学习_第4张图片

 

配置defconfig 文件

/Kernel-4.9/arch/arm64/configs/achilles6_prc_wifi_defconfig

/Kernel-4.9/arch/arm64/configs/ achilles6_prc_wifi_debug_defconfig

 

Step2OTP Adapter

/kernel-4.9/drivers/misc/mediatek/cam_cal/src/mk6765/cam_cal_list.c

OTP学习_第5张图片

 

Step3:OTP Hal

NULL表示不支持OTP,否则表示支持

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/sensor_list.cpp

OTP学习_第6张图片

 

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal.cpp   默认sensor流程

/vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/camera_calibration_cam_cal_ov13b10.cpp       特定sensor

OTP学习_第7张图片

 

 

DoCamCal2Again()其他的函数和DoCamCalSingleLsc()实现很相似

OTP学习_第8张图片

 

配置像素ID:如果要进行Isc校准,需要在camera_isp_isc_xxxmipirow .h中配置像素id与模块厂商确定烧成OTP的第一个像素,然后修改vendor/mediatek/proprietary /custom / mt6765/hal/ imgsensor / xxx_mipi_raw/ camera_isp_Isc_xxxmipiraw.h

SensorGoldenCalTable{ //SensorGoldenCalTable

pixId: 3, //0,1,2,3: B, Gb, Gr,R

SlimLscType: 0

 Width:0

}

 

OTP Read Flow

OTP学习_第9张图片

OTP学习_第10张图片

     4.1.2 Sensor OTP

       Sensor OTP代码和Platform OTP代码类似,在custom_camera_msdk.cpp中GetCameraCalData()函数来区分走默认函数CAM_CALGetCalData(),就是sensor OTP。Sensor

OTP学习_第11张图片

1、这块可以修改rg bg的值,刷版本看预览是否偏色,来看OTP是否正常(偏色)应用

2、这一抓kernel log来看OTP数据,是否正常。这块可以联系模组厂fae看OTP数据是否正常。

  adb reboot

  adb root

  adb shell dmesg > D:\log\kernel.txt

sensor OTP的函数 》sensor型号_read_data_kernel《,获取有差异,但是大同小异。这里讲一个不一样的,万一找不到,从datasheet中找出OTP的寄存器,然后在驱动代码中搜寄存器就找到了;platform OTP可以根据camera_custom_msdk.cpp中GetCameraCalData()函数来看走那个函数来分析。

    4.2.高通代码

4.2.1.kernel层

(1)eeprom初始化

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

OTP学习_第12张图片

 

函数主要是实现了两个功能:

  • 通过platform_driver_register函数注册平台驱动(有match device和driver的动作)(msm_eeprom_platform_driver)
  • 将msm_eeprom_i2c_driver挂载i2c总线上

(2)match驱动和设备
这之后,就会根据名称匹配驱动driver和设备device

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

OTP学习_第13张图片

 

./kernel/msm-4.14/arch/arm/boot/dts/qcom/sm8150-camera-sensor-qrd.dtsi(//举个例子)

 

在dtsi中是设备的定义

平台 + 驱动 + 设备

 

OTP学习_第14张图片

**compatible = “qcom,eeprom”**和 .driver = {.name = “qcom,eeprom”,匹配上了,
系统就去调用probe函数probe = msm_eeprom_i2c_probe

 

 

(3)match成功,调用probe

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

   OTP学习_第15张图片  

OTP学习_第16张图片

OTP学习_第17张图片

 

这个函数主要工作:

  • msm_eeprom_get_dt_data(e_ctrl);读取dtsi配置的上电时序配置/
  • msm_eeprom_parse_memory_map用于解析以下节点

OTP学习_第18张图片

  • msm_camera_power_up上电
  • read_eeprom_memory读取OTP数据
  • msm_camera_power_down下电

说白了,前面无非就是去读取dtsi的配置,进行上电,然后读取OTP数据下电
这就是整个probe函数的流程!

 

 

(4)读取OTP数据:read_eeprom_memory

OTP学习_第19张图片

 OTP学习_第20张图片
qcom,page0 =
= <
有效值 地址 地址类型 数据 数据类型 延迟>

qcom,page7 = <1 0x3d81 2 0x01 1 10>;/*往0x3d81写入0x01:把OTP数据加载到buffer中 */

        qcom,pageen7 = <0 0x0 0 0x0 0 0>;

        qcom,poll7 = <0 0x0 0 0x0 0 0>;

        qcom,mem7 = <256 0x7010 2 0 1 1>;/*从0x7010开始读取256个数据*/

 

4.2.2.User层

在kernel层,数据最后被保存到memptr指向的地址里

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/eeprom.c

OTP学习_第21张图片

OTP学习_第22张图片

用户态通过ioctl下到内核,我们看下内核的接受者函数

./kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c

OTP学习_第23张图片

OTP学习_第24张图片

OTP学习_第25张图片

Copy_to_user中将cal_data.mapdata的num_bytes个数据放到cfg.read_data.dbuffer

 

 

你可能感兴趣的:(Camera驱动,MTK,Cam,Hal3,mtk,otp)