根据官方文档可以知道,ais camera驱动框架包含以下几个部分:
每一个对应的模块在工程中的代码目录:
当配置好xx_8295.c后,ais_server启动,会初始化ais_enging句柄,然后通过CameraDeviceManager管理lib,接着根据xx_8295.c配置的lib名称和open函数获取驱动文件注册
执行到驱动的open接口
其lib调用过程如下:
AisEngine::Initialize->CameraDeviceManager::CreateInstance() ->
[cameradevicelcameradevicemanager.cpp]
CameraDeviceManager::Initialize->
CameraDeviceManagerGetStaticsTable(打开和初始化csi,ife,配置时钟等等
qnx_ap\Amss\multimedia\camera\ais\CameraDevicesrc\CameraDeviceStatics.cpp)
->[CAMERACONFIG\SRCCAMERACONFIG.C] GetCameraConfigInterface
CameraDeviceManager->RegisterDeviceFromLib->(CameraConfig\src\CameraConfigSA8295.c)
CameraSensorDevice_Open_max96712 (apps\qnx_ap\vendor\services\cameralSensorLibs\qcom_max96712_1ib\src\max96712_1ib.c)->
CameraSensorDevice_Open(apps\qnx_ap\AMsS\multimedia\camera\ais\ImagingInputs\ImagingInputDriver\src\CameraSensorDevice.cpp)
->max96712_sensor_open_lib(vendor/services/camera/SensorLibs/acom/max96712lib.c)
->qnx_ap\AMss\multimedia\camera\ais\ImagingInputs\ImagingInputDriver\src\SensorDriver.cpp
->apps\qnx_ap\AMss\multimedia\camera\ais\ImagingInputs\ImagingInputDriver
\src\commonlsensorPlatform.cpp
->apps\qnx_ap\AMss\multimedia\camera\ais\CameraPlatform\qnx\下面的i2c等驱动
后续当需要配置的时候,通过config_param去执行解串器和串行器的寄存器配置流程,实际上的解串器驱动运行文件位于vendor/services/camera/SensorLibs/acom/max96712lib.c
流程:
max96712_sensor_open_lib-> max96712sensor_detect_device->
max96712_sensor_detect_device_channels->max96712sensor_init_setting
1)max96712_sensor_detect_device接口只需要判断读写712的芯片id正确并返回detect状态就可以
2)max96712_sensor_detect_device_channels接口初始化解串器,
->max96712_sensor_remap_channels 里面通过不同的type获取不同的串行器的句柄并调用max96717串行器的detect接口,针对sensor的i2c地址做分配。
3)max96712_sensor_init_setting根据不同串行器和不同sensor类型配置解串器通信格式等,并且调用了串行器的init_link接口,执行max96717配置和初始化。
4)max96712_sensor_detect_device_channels中还需要对解串器初始化,然后调用到的sensor里面的detect接口除了分配好串行器的地址后,还需要分配好sensor的地址,通过串行器的0x41,0x42寄存器配置。(重点)
5)针对xx_init_setting 里面会调用到sensor的init_link接口,主要是针对串行器的初始化,然后下来是对串行器出图的配置。
之后就是用户ais_open后,执行start_stream对解串器输出操作和串行器start_link操作。
max96712_sensor_open_lib
max96712_sensor_detect_device
max96712_sensor_detect_device_channels -> max96712_sensor_remap_channels
到这个流程为止,sensor状态应为SENSOR_STATE_DETECTED,为init_link作准备max96712_sensor_init_setting -> max96712_set_init_sequence->
max96717_init_link,状态应为SENSOR_STATE_INITIALIZED
为startstream作准备,在init_link之后,还需做解串器依据不同的串行器做配置初始化,包括mipi链路输出,数据格式等
max96717_start_link。开启输出
以上流程重点就是这个入口函数。通过CameraDeviceManager->RegisterDeviceFromLib
(会遍历配置的config camera解串器配置)-> CameraSensorDevice_Open 接口
extern
"c" CameraResult CameraSensorDevice_Open (CameraDeviceHandleType** ppNewHandle,
CameraDeviceIDType deviceId, sensor_lib_interface t* pSensorLibInterface)
{
CameraResult result = CAMERA SUCCESS;
CameraSensorDevice* pCameraSensorDevice = NuLL;
AIs_LoG(SENSOR DEV,HIGH,"Opening device Ox%x", deviceId);
// Sanity check input parameters
if(ppNewHandle = NULL || pSensorLibInterface == NULL)
{
AIS_LOG(SENSOR DEV,ERROR,"null params");
return CAMERA_EMEMPTR;
}
// Allocate instance memory
pCameraSensorDevice = new CameraSensorDevice(deviceId, pSensorLibInterface):
if (pCameraSensorDevice != NULL)
{
result = pCameraSensorDevice->Initialize();
//->SensorDriver.cpp(SensorDriver::Initialize)->SensorPlatform::SensorPlatformInit
if (CAMERA_SUCCESS==result){
*ppNewHandle = pCameraSensorDevice;
}else
{
delete pCameraSensorDevice;
*ppNewHandle = NULL;
}
}
else
{
reSult = CAMERA_ENOMEMORY;
}
AIs LoG(sENsoR DEV,HIGH,"Opende Vi CeOxxreturn #d",deviceId, result);
return result;
}// CameraSensorDevice Open
//cameraPlatformInit //注册gPlat formCtxt
CameraResult CameraSensorDevice :: InitialiZe()
{
CameraResult result = CAMERA SUCCESS#
m pfnClientCallback = NULL;
m pClientData = NULL;
result = LoadSensorLibs ();
if (CAMERA SUCCESS == result)
{
result = DriverInitialize ()://->
//m_SensorDriver.InitialiZe (thiS, m_SensorData.ps_SensorLibData);
//-> m_pSensorPlatform = SensorPlatform::SensorPlatformInit(m pSensorLib);
//->SensorPlatformCommon::Init()(配置i2c和lgpio等)->
//cameraSensorGPIoConfigCamera (m eCameraInterface)
// result = pSensorData->senSor Custom_func.sensor_set_platform_func_table(
//lib中的table接口
//pSensorData,&plat_form_func_table);
if (CAMERA_SUCCESS != reSult)
(void)UnloadSensorLibs ();
}
return result;
}
CameraResult SensorPlatformCommon::Init()
{
CameraResult rc;
m_eCameraInterface = m_pSensorLib->sensor_slave_info.camera_id;
AIS_LoG(ISENSOR PLATFORM,HIGH,"SenSOr Plat form init camera id d"
m_eCameraInterface);
if (TRUE==CameraSensorGPIoConfigCamera (m_eCameraInterface))
{
rc = CameraCreateMutex(&m_i2cMutex);
if (rc == CAMERA_SUCCESS)
{
memset(m aInterrupts,OxO,sizeof(m_aInterrupts));
CameraPlatform_GetI2cMasterInfo(m_eCameraInterface
&m_cciDeviceIndex,&m_I2CMasterIndex);
//从1ib中解析得到i2c参数
//* param[out] cciDeviceCore CCI Device Core ID
//* param[out] i2cMasterIndex I2C bus Master Index
switch (m_pSensorLib->sensor_slave_info.i2c_freq_mode)
{
case SENSOR_I2C_MODE_FAST_PLUS:
m_I2CBusFrequency = CAMSENSOR_I2C_1000KHZ;
break;
case SENSOR_I2C_MODE_CUSTOM:
case SENSOR_I2C_MODE_FAST:
m_I2CBusFrequency = CAMSENSOR_I2C_400KHZ;
break;
case SENSOR_I2C_MODE_STANDARD:
default:
m_I2CBusFrequency = CAMSENSoR_I2c_100KHZ;
break;
}
m_I2cslaveAddr = m_pSensorLib->sensor_slave_info.slave_addr;
SensoPlatform GetRegisterandDataSize(
m_pSensorLib->sensor_slave_info.addr_type,
m_pSensorLib->sensor_slave_info.data_type,
&m_I2CRegisterSize, &m_I2cDataSize,&m_I2cEndian);
}
else
CameraSensorGPIoUnConfigCamera(m_eCameraInterface);
}
else
rC = CAMERA_EFAILED:
return rC;
}
CameraResult CameraSensorDevice::LoadSensorLibs ()
{
CameraResult result = CAMERA_SUCCESS;
sensor_open_lib_t device_info = {};
device_info.boardType = CameraPlatformGetCameraHwBoardType ();
device_info.config = CameraPlatformGetInputDeviceConfig(m_deviceId,
&device_info.cameraId);
//解析lapps\qnx_ap\AMss\multimedialcamera\ais\CameraConfig\src\CameraConfigSA8295.c\devconfig
m_SensorData.ps_SensorLibData =
(sensor_lib_t*) m_sensorLibInterface.sensor_open_lib(
//这个接口就调用到max96712_sensor_open_lib
//(CameraConfigSA8295.c配置的pfnCameraDevice0pen)
&m_SensorDriver
&device_info);
//传递进去lib中解析,从cameraConfigSA8295.c解析csi,i2c等,在从1ib中解析sensor的管理。
//并且通过这个接口返回1ib操作的结构指针
if (NuLL == m_SensorData.ps_SensorLibData)
{
// Failed to open the Sensor Data File,
SENSOR_ERROR("Sensor Data Not Found.");
reSult = CAMERA_EUNSUPPORTED;
}
return result;
}
CAM_API CameraResult CameraSenSOrDevice_Open_max96712(
CameraDeviceHandleType** ppNewHandle,CameraDeviceIDType deviceId)
{
sensor_lib_interface_t sensor_lib_interface ={
.sensor_open_lib = max96712_sensor_open_lib,
}
return CameraSensorDevice_Open(ppNewHandle, deviceId,&sensor_lib_interface);
}
/****************
FUNCTIoN SensorDriver::Initialize
DEsCRIPTIoN Initialize the driver interface
DEPENDENCIES None
PARAMETERS this
RETURN VALUE CameraResult
SIDE EFFECTS None
******************/
CameraResult SensorDriver::Initialize(CameraSensor_Device* pCameraSensorDevice,
sensor_lib_t *pSensorData)
{
CameraResult result = CAMERA_SUCCESS;
SENSOR_FUNCTIONENTRY("");
m_pDeviceContext = pCameraSensorDeViCe;
m_pSensorLib = pSensorData;
// Initialize sensor parameters using sensor data
std_strlcpy(m_szSensorName, pSensorData->sensor_slave_info.sensor_name,
STD_ARRAY_SIZE(m_szSensorName));
AIS_LOG(SENSOR_DEV,LOW, "m szModelNameAndNumber = %s",m_szSensorName);
m_pSensorPlatform = SensorPlatform::SensorPlatformInit(m_pSensorLib);
if (!m_pSensorPlatform)
{
SENsOR_ERROR("Platform Initialization failed");
result = CAMERA_EFAILED;
}
if (cAMERA_SUccESs == result && pSensorData->use_sensor_custom_func &&
pSensorData->sensor_custom_func.sensor_set_platform_func_table)
{
sensor_platform_func_table_t platform_func_table = ():
platform_func_table.i2c_read = NULL;
platform_func_table.i2c_write_array = NULL;
platform_func_table.i2c_slave_read = &SensorDriver_SlaveReadRegister;
platform_func_table.i2c_slave_read_bulk = &SensorDriver_SlaveBulkRead;
platform_func_table.i2c_slave_write_array = &SensorDriver_SlaveWriteRegisters;
platform_func_table.i2c_slave_write_bulk = &SensorDriver_SlaveBulkWrite;
platform_func_table.i2c_slave_write_array_sync = &SensorDriver_SlaveWriteReqisters;
platform_func_table.i2c_slave_bulk_write_then_read =
&SensorDriver_SlaveBulkWriteRead,
platform_func_table.execute_power_setting = &SensorDriver_ExecutePowerSetting:
platform_func_table.setup_gpio_interrupt = &SensorDriver_SetupGpioInterrupt;
platform_func_table.setup_cci_frame_sync = &SensorDriver_SetupCciFrameSync;
platform_func_table.trigger_cci_frame_sync = &SensorDriver_TriggerCciFrameSync;
platform_func_table.event_cb = &SensorDriver_Inputcallback;
result = pSensorData->sensor_custom_func.sensor_set_platform_func_table(
//通过这个接口,往1ib中注册i2c操作读写接口
pSensorData,&platform_func_table);
}
if(CAMERA_SUCCESS==result)
{
SENSOR_LOG("SuCCeSS");
}else
{
SENSOR_ERROR("Initialization failed"):
}
return result;
}
/*
FUNcTIoN: max96712 sensor set platform func table
DEscRlPTIoN:Copies the initialization table in pctxt.
*/
static int max96712_sensor_set_platform_func_table(void* ctxt,
sensor_platform_func_table t* table)
{
SHIGH("max96712 sensor set platform func table");
if(ctxt == NULL)
{
SERR("Invalid ctxt pointer (Oxox)",ctxt);
return -l;
}
max96712_context_t* pCtxt = (max96712_context_t*)ctxt;
if (!pctxt->platform_fcn_tbl_initialized)
{
if (!table || !table->i2c_slave_write_array || !table->i2c_slave_read)
{
//i2c这两个读写接口是必须的
SERR("Invalid i2c func table param");
return -l;
}
pCtxt-platform_fcn_tbl =*table;//赋值table,可以通过这个指针操作i2c
pCtxt->platform_fcn_tbl_initialized = 1:
SLow("i2c func table set");
}
return 0;
}