MTK camera drv]如何实现同Sensor IC不同摸组的Driver和参数的兼容

本文介绍如何通过软件配置区分不同模组厂生产的OV5647摄像头模组,包括定义Sensor_ID、注册sensor、修改驱动及验证模组参数等步骤。

 

 

如下以 OV5647 为例

假设 OV5647AB OV5647BC 是两个不同模组厂的模组。

 

1:在kd_imgsensor.h 內定义不同的Sensor_ID

#define OV5647AB_SENSOR_ID                        0x5647

#define OV5647BC_SENSOR_ID                        0x5648

 

2ProjectConfig.mk  中加入 OV5647AB OV5647BC sensor 注册。

可以参考如下部分。

CUSTOM_HAL_IMGSENSOR=ov5647AC_raw ov5647BC_raw

CUSTOM_HAL_MAIN_IMGSENSOR=ov5647AC_raw

CUSTOM_HAL_MAIN_BACKUP_IMGSENSOR=ov5647BC_raw

 

CUSTOM_KERNEL_IMGSENSOR=ov5647AC_raw ov5647BC_raw ov7690_yuv

CUSTOM_KERNEL_MAIN_BACKUP_IMGSENSOR=ov5647BC_raw

CUSTOM_KERNEL_MAIN_IMGSENSOR=ov5647AC_raw

 

3Driver 部分的修改

mediatek\custom\common\kernel\imgsensor 这个目录下之前的 OV5647 分别命名为OV5647AB OV5647BCDriver 里面的函数也做同步修改。

 

4:在 mediatek\custom\common\kernel\imgsensor 目录下的 ov5647AC_Sensor .c ov5647BC_Sensor.c 中的 OV5647GetSensorID_BC 这个函数中做如下修改。

 

*sensorID=((OV5647BC_read_cmos_sensor(0x300A) << 8) | OV5647BC_read_cmos_sensor(0x300B));

sensorID +=1;

在这个函数中再加入判读模组信息的判断。

加入 AC 模组的 MID 也就是模组厂的标志位 的读取可以参考如下说明。具体的地址寄存器可以参考对应的sensor DataSheet  。模组厂的MID可以请模组厂帮忙提供。

static UINT32 OV5647AC_OTP_combination_read(void)

{

       kal_int8 mid = 0x00;

      

    OV5647AC_write_cmos_sensor (0x3D21, 0x01);

    Sleep(50); // 50ms

  

    mid = OV5647AC_read_cmos_sensor (0x3D05); 

    mid &= 0x7F;

       printk("*********************************************MID = %d\n",mid);

    OV5647AC_write_cmos_sensor (0x3D21, 0x00);

    if (2 == mid)

    {

        return TRUE;

    }

    else

    {

        return FALSE;

    }

}

 

然后在OV5647GetSensorID_AC 这个函数中加入如下部分。关键是如果sensor MID 不对的话此时需要将 sensorID 设置为0xFFFFFFFF

if (!OV5647AC_OTP_combination_read())

{

      *sensorID = 0xFFFFFFFF;

      SENSORDB("OV5647ACOpen, MID != 0 \n");

 

      return ERROR_SENSOR_CONNECT_FAIL;

}

 

OV5647GetSensorID_BC 也做类似的修改。

 

5:最后一步判断是否真正的区分了对应模组的参数。

mediatek\custom\common\hal\imgsensor\ov5647AC_raw 或者

mediatek\custom\common\hal\imgsensor\ov5647BC_raw 文件中的

camera_isp_regs_ov5647AC_mt65XX.c 中的 CCM 部分修改成

CCM:{

    {set:{//00

        0x01000000, 0x00000000, 0x01000000, 0x00000000, 0x01000000,

    }},

    {set:{//01

        0x01000000, 0x00000000, 0x01000000, 0x00000000, 0x01000000,

    }},

    {set:{//02

        0x01000000, 0x00000000, 0x01000000, 0x00000000, 0x01000000,

    }}

},

重新build 。确认两颗模组的色彩表现是否不同。如果一个色彩比较暗淡,则修改OK

### MTK 平台下相机模块 MCLK 设置为 19.2 MHz 的相关配置 在 MTK 平台上,MCLK 是图像传感器的重要时钟信号之一,其频率直接影响到图像传感器的工作状态性能表现。如果需要将 MCLK 配置为 19.2 MHz,则需重点检查以下几个方面: #### 1. **cfg_setting_imgsensor.cpp 文件中的 MCLK HW 链接配置** cfg_setting_imgsensor.cpp 文件用于定义图像传感器的基础参数配置,其中包括 MCLK 的设置。通常情况下,该文件会指定默认的 MCLK 值,并将其传递给硬件层进行实际配置[^1]。 如果需要调整 MCLK 到 19.2 MHz,可以修改如下类似的代码片段: ```cpp static struct imgsensor_info_struct imgsensor_info = { .SensorClockFreq = 19200, // 单位为 KHz,默认值可能不同 ... }; ``` 此外,还需确认 `cfg_setting_imgsensor` 是否正确映射到了具体的硬件资源链路中,以确保所设 MCLK 能够正常生效。 #### 2. **imgsensor_drv.cpp 中的具体实现** 在 vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/imgsensor_drv.cpp 文件中,实现了与图像传感器交互的核心逻辑。此文件可能会进一步处理来自上层应用或 HAL 层传入的 MCLK 参数并完成最终写入操作[^2]。 可能涉及的关键代码段包括但不限于以下内容: ```cpp static kal_uint32 set_sensor_mclk(kal_uint32 mclk_khz) { if (mclk_khz != SENSOR_DEFAULT_CLOCK_FREQ_KHZ) { LOG_INF("Set MCLK to %d kHz", mclk_khz); // 实际调用底层接口更改 MCLK write_to_hardware_register(MCLK_REGISTER_ADDR, mclk_khz / 1000); // 将单位转换为 MHz } return ERROR_NONE; } ``` #### 3. **Kernel 部分的驱动程序支持** Kernel 驱动部分主要由 image sensor driver 构成,这部分负责具体型号传感器的功能实现,例如 ID 检测、电源管理以及寄存器配置等。对于 MCLK 的设置,可以在 kernel-4.19/drivers/misc/mediatek/imgsensor 下找到对应源码[^5]。 特别需要注意的是,在某些特定场景下(如预览模式),MCLK 的稳定性至关重要。因此建议验证以下几点: - 确认当前使用的 Sensor Driver 支持动态调节 MCLK; - 测试是否存在因低频导致的数据传输延迟或其他异常现象。 #### 4. **I2C 初始化过程中的兼容性考虑** I2C 总线作为连接主机控制器与图像传感器的主要通信方式,在初始化阶段也会涉及到 MCLK 的分配问题。通过分析 imgsensor_i2c_create 函数可知,它会在系统启动期间逐一加载各个子设备驱动程序[^4]。 若发现无法成功切换至目标频率(即 19.2 MHz),则可能是由于以下原因引起: - 当前硬件版本不完全适配新频率范围; - 或者存在竞争条件使得其他件抢占了优先级更高的时钟资源。 --- ### 示例代码:动态调整 MCLK 至 19.2 MHz 以下是基于上述理论的一个简单示例,展示如何尝试动态改变 MCLK 频率: ```c #include <linux/i2c.h> #include <linux/module.h> static int adjust_mclk(struct i2c_client *client, unsigned long target_freq_hz) { u8 reg_addr = MCLK_CONFIG_REG; // 替换为目标寄存器地址 u8 value = target_freq_hz / 1000000; // 计算整数值部分 dev_dbg(&client->dev, "Setting MCLK to %lu Hz\n", target_freq_hz); /* 发送命令 */ s32 ret = i2c_smbus_write_byte_data(client, reg_addr, value); if (ret < 0) { dev_err(&client->dev, "Failed to set MCLK: %d\n", ret); return ret; } return 0; } module_init(adjust_mclk_init); MODULE_LICENSE("GPL"); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值