MTK Camera上电流程分析

2019-04-13 13:02发布

1、Camera上电过程中,系统会初始化一系列的服务,其中 就有CameraServer的相关服务,系统通过FrameWorks层调用get_number_of_camera函数,调用到hal层上vendor/mediatek/proprietary/hardware/mtkcam./legacy/module_hal/devicemgr/CamDeviceManagerBash.cpp里的函数 int32_t CamDeviceManagerBase:: getNumberOfDevices() { RWLock::AutoWLock _l(mRWLock); // if ( 0 != mi4DeviceNum ) { #if MTK_CROSSMOUNT_SUPPORT mi4DeviceNum = mEnumMap.size() + mExternalDeviceInfoMap.size() - 1; MY_LOGD("#devices:%d #remote:%u mEnumMap:%u", mi4DeviceNum, mExternalDeviceInfoMap.size(), mEnumMap.size()); #else MY_LOGD("#devices:%d", mi4DeviceNum); #endif } else { Utils::CamProfile _profile(__FUNCTION__, "CamDeviceManagerBase"); mi4DeviceNum = enumDeviceLocked(); _profile.print(""); } // return mi4DeviceNum; } 这里只是调用了enumDeviceLocked函数,并将它的返回值(camera的个数),返回到上层。enumDeviceLocked的实现如 int32_t CamDeviceManagerImp:: enumDeviceLocked() { status_t status = OK; int32_t i4DeviceNum = 0; // #if '1'==MTKCAM_HAVE_METADATA NSMetadataProviderManager::clear(); #endif #if OPTION__NEED_DEVMETAINFO DevMetaInfo::clear(); #endif mEnumMap.clear(); //------------------------------------------------------------------------------ #if '1'==MTKCAM_HAVE_SENSOR_HAL // IHalSensorList*const pHalSensorList = IHalSensorList::get(); size_t const sensorNum = pHalSensorList->searchSensors(); #if 0 SensorHal::createInstance()->searchSensor();; #endif 重点关注pHalSensorList->searchSensors()的调用流程 MUINT HalSensorList:: searchSensors() { Mutex::Autolock _l(mEnumSensorMutex); // MY_LOGD("searchSensors"); return enumerateSensor_Locked(); }MUINT HalSensorList:: enumerateSensor_Locked() { int ret_count = 0; int ret = 0; // #warning "[WARN] Simulation for enumerateSensor_Locked()" MUINT halSensorDev = SENSOR_DEV_NONE; NSFeature::SensorInfoBase* pSensorInfo ; SensorDrv *const pSensorDrv = SensorDrv::get(); SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance(); if(!pSeninfDrv) { MY_LOGE("pSeninfDrv == NULL"); return 0; } ret = pSeninfDrv->init(); if(ret < 0) { MY_LOGE("pSeninfDrv->init() fail"); return 0; } pSeninfDrv->setMclk1(1, 1, 1, 0, 1, 0, 0); pSeninfDrv->setMclk2(1, 1, 1, 0, 1, 0, 0); //pSeninfDrv->setMclk3(1, 1, 1, 0, 1, 0, 0); /* No main2 */ int const iSensorsList = pSensorDrv->impSearchSensor(NULL); //query sensorinfo querySensorDrvInfo(); //fill in metadata buildSensorMetadata();接着比较重要的就是impSearchSensor的实现。 MINT32 ImgSensorDrv::impSearchSensor(pfExIdChk pExIdChkCbf) { MUINT32 SensorEnum = (MUINT32) DUAL_CAMERA_MAIN_SENSOR; MUINT32 i,id[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0,0}; MBOOL SensorConnect=TRUE; UCHAR cBuf[64]; MINT32 err = SENSOR_NO_ERROR; MINT32 err2 = SENSOR_NO_ERROR; ACDK_SENSOR_INFO_STRUCT SensorInfo; ACDK_SENSOR_CONFIG_STRUCT SensorConfigData; ACDK_SENSOR_RESOLUTION_INFO_STRUCT SensorResolution; MINT32 sensorDevs = SENSOR_NONE; IMAGE_SENSOR_TYPE sensorType = IMAGE_SENSOR_TYPE_UNKNOWN; IMGSENSOR_SOCKET_POSITION_ENUM socketPos = IMGSENSOR_SOCKET_POS_NONE; //! If imp sensor search process already done before, //! only need to return the sensorDevs, not need to //! search again. if (SENSOR_DOES_NOT_EXIST != m_mainSensorId) { //been processed. LOG_MSG("[impSearchSensor] Already processed "); if (BAD_SENSOR_INDEX != m_mainSensorIdx) { sensorDevs |= SENSOR_MAIN; } if (BAD_SENSOR_INDEX != m_main2SensorIdx) { sensorDevs |= SENSOR_MAIN_2; } if (BAD_SENSOR_INDEX != m_subSensorIdx) { sensorDevs |= SENSOR_SUB; } #ifdef ATVCHIP_MTK_ENABLE sensorDevs |= SENSOR_ATV; #endif return sensorDevs; } GetSensorInitFuncList(&m_pstSensorInitFunc); LOG_MSG("SENSOR search start "); if (-1 != m_fdSensor) { ::close(m_fdSensor); m_fdSensor = -1; } sprintf(cBuf,"/dev/%s",CAMERA_HW_DEVNAME); m_fdSensor = ::open(cBuf, O_RDWR); if (m_fdSensor < 0) { LOG_ERR("[impSearchSensor]: error opening %s: %s ", cBuf, strerror(errno)); return sensorDevs; } // search main/main_2/sub 3 sockets // DUAL_CAMERA_MAIN_SENSOR = 1 DUAL_CAMERA_SUB_SENSOR = 2 #ifdef MTK_MAIN2_IMGSENSOR for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_MAIN_2_SENSOR; SensorEnum <<= 1) { LOG_MSG("impSearchSensor search to main_2 "); #else #ifdef MTK_SUB_IMGSENSOR for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) { LOG_MSG("impSearchSensor search to sub "); #else for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum < DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) { LOG_MSG("impSearchSensor search to main "); #endif #endif // for (i = 0; i < MAX_NUM_OF_SUPPORT_SENSOR; i++) { //end of driver list if (m_pstSensorInitFunc[i].getCameraDefault == NULL) { LOG_MSG("m_pstSensorInitFunc[i].getCameraDefault is NULL: %d ", i); break; } //set sensor driver id[KDIMGSENSOR_INVOKE_DRIVER_0] = (SensorEnum << KDIMGSENSOR_DUAL_SHIFT) | i; LOG_MSG("set sensor driver id =%x ", id[KDIMGSENSOR_INVOKE_DRIVER_0]); err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] ); if (err < 0) { LOG_ERR("ERROR:KDCAMERAHWIOC_X_SET_DRIVER "); } //err = open(); err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE); if (err < 0) { LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) ", strerror(errno)); } // sensorType = this->getCurrentSensorType((SENSOR_DEV_ENUM)SensorEnum); // socketPos = this->getSocketPosition((CAMERA_DUAL_CAMERA_SENSOR_ENUM)SensorEnum); //check extra ID , from EEPROM maybe 在impSearchSensor的实现中,它最先调用的GetSensorInitFuncList(&m_pstSensorInitFunc);去挂载hal层的功能函数。 ImgSensorDrv:: ImgSensorDrv() : SensorDrv() , m_fdSensor(-1) , m_mainSensorId(SENSOR_DOES_NOT_EXIST) , m_main2SensorId(SENSOR_DOES_NOT_EXIST) , m_subSensorId(SENSOR_DOES_NOT_EXIST) , m_mainSensorIdx(BAD_SENSOR_INDEX) , m_main2SensorIdx(BAD_SENSOR_INDEX) , m_subSensorIdx(BAD_SENSOR_INDEX) , m_pMainSensorInfo(NULL) , m_pSubSensorInfo(NULL) , m_pstSensorInitFunc(NULL) , mUsers(0)查看类的构造,找到类的成员 MSDK_SENSOR_INIT_FUNCTION_STRUCT* m_pstSensorInitFunc;继续查找MSDK_SENSOR_INIT_FUNCTION_STRUCT*
#define YUV_INFO(_id, name, getCalData) { _id, name, NSFeature::YUVSensorInfo<_id>::createInstance(name, #name), (NSFeature::SensorInfoBase*(*)()) NSFeature::YUVSensorInfo<_id>::getInstance, NSFeature::YUVSensorInfo<_id>::getDefaultData, getCalData, NSFeature::YUVSensorInfo<_id>::getNullFlickerPara } #define RAW_INFO(_id, name, getCalData) { _id, name, NSFeature::RAWSensorInfo<_id>::createInstance(name, #name), (NSFeature::SensorInfoBase*(*)()) NSFeature::RAWSensorInfo<_id>::getInstance, NSFeature::RAWSensorInfo<_id>::getDefaultData, getCalData, NSFeature::RAWSensorInfo<_id>::getFlickerPara } //MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[MAX_NUM_OF_SUPPORT_SENSOR] = MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] = { #if defined(S5K5E2YA_MIPI_RAW) || defined(S5K5E2YA_MIPI_RAW_9013) RAW_INFO(S5K5E2YA_SENSOR_ID, SENSOR_DRVNAME_S5K5E2YA_MIPI_RAW, NULL), #endif #if defined(ST55A_MIPI_RAW_9013) RAW_INFO(ST55A_SENSOR_ID, SENSOR_DRVNAME_ST55A_MIPI_RAW, NULL), #endif #if defined(GC2755MIPI_RAW_9013) RAW_INFO(GC2755_SENSOR_ID, SENSOR_DRVNAME_GC2755_MIPI_RAW,NULL), #endifUINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList) { if (NULL == ppSensorList) { ALOGE("ERROR: NULL pSensorList "); return MHAL_UNKNOWN_ERROR; } *ppSensorList = &SensorList[0]; return MHAL_NO_ERROR; } // GetSensorInitFuncList()至此hal层和mtkcam开始关联起来,以上全红的文字是实现上比较巧妙的地方,框架中提供了一个单例实例,并让各种Sensor单独去实现以下比较重要的2个接口。 typedef NSFeature::RAWSensorInfo SensorInfoSingleton_T; namespace NSFeature { template <> UINT32 SensorInfoSingleton_T:: impGetDefaultData(CAMERA_DATA_TYPE_ENUM const CameraDataType, VOID*const pDataBuf, UINT32 const size) const { UINT32 dataSize[CAMERA_DATA_TYPE_NUM] = {sizeof(NVRAM_CAMERA_ISP_PARAM_STRUCT), sizeof(NVRAM_CAMERA_3A_STRUCT), sizeof(NVRAM_CAMERA_SHADING_STRUCT), sizeof(NVRAM_LENS_PARA_STRUCT), sizeof(AE_PLINETABLE_T), 0, sizeof(CAMERA_TSF_TBL_STRUCT)}; if (CameraDataType > CAMERA_DATA_TSF_TABLE || NULL == pDataBuf || (size < dataSize[CameraDataType])) { return 1; } switch(CameraDataType) { case CAMERA_NVRAM_DATA_ISP: memcpy(pDataBuf,&CAMERA_ISP_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_ISP_PARAM_STRUCT)); break; case CAMERA_NVRAM_DATA_3A: memcpy(pDataBuf,&CAMERA_3A_NVRAM_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_3A_STRUCT)); break; case CAMERA_NVRAM_DATA_SHADING: memcpy(pDataBuf,&CAMERA_SHADING_DEFAULT_VALUE,sizeof(NVRAM_CAMERA_SHADING_STRUCT)); break; case CAMERA_DATA_AE_PLINETABLE: memcpy(pDataBuf,&g_PlineTableMapping,sizeof(AE_PLINETABLE_T)); break; case CAMERA_DATA_TSF_TABLE: memcpy(pDataBuf,&CAMERA_TSF_DEFAULT_VALUE,sizeof(CAMERA_TSF_TBL_STRUCT)); break; default:
typedef NSFeature::RAWSensorInfo SensorInfoSingleton_T; namespace NSFeature { template <> UINT32 SensorInfoSingleton_T:: impGetFlickerPara(MINT32 sensorMode, MVOID*const pDataBuf) const { ALOGD("impGetFlickerPara+ mode=%d", sensorMode); ALOGD("prv=%d, vdo=%d, cap=%d, zsd=%d", (int)e_sensorModePreview, (int)e_sensorModeVideoPreview, (int)e_sensorModeCapture, (int)e_sensorModeZsd ); FLICKER_CUST_PARA* para; para = (FLICKER_CUST_PARA*)pDataBuf; if(sensorMode == e_sensorModePreview) get_flicker_para_by_Preview(para); else if(sensorMode == e_sensorModeVideo) { get_flicker_para_by_Video(para); } else if(sensorMode == e_sensorModeCapture) { get_flicker_para_by_Capture(para); } else if(sensorMode == e_sensorModeVideo1) {分析完了hal层的关联,接着我们分析kenel层中camear sensor driver的关联 err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] ); if (err < 0) { LOG_ERR("ERROR:KDCAMERAHWIOC_X_SET_DRIVER "); } //err = open(); err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE); if (err < 0) { LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) ", strerror(errno)); }从代码上看,mtkcam是通过ioctl去设置加载对应的driver并执行上下电id检测。
在kd_sensorlist.c里可以查看到相关的调用 #endif case KDIMGSENSORIOC_X_SET_DRIVER: i4RetValue = kdSetDriver((unsigned int *)pBuff); break;int kdSetDriver(unsigned int *pDrvIndex) { ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL; u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0, 0};//这个数组的大小是2 u32 i; /* set driver for MAIN or SUB sensor */PK_INF("pDrvIndex:0x%08x/0x%08x ", pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0], pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_1]);/* Camera information */gDrvIndex = pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0]; //获取driver层imgsensor的功能函数列表if (0 != kdGetSensorInitFuncList(&pSensorList)) {PK_ERR("ERROR:kdGetSensorInitFuncList() ");return -EIO;} //KDIMGSENSOR_INVOKE_DRIVER_0 = 0, KDIMGSENSOR_MAX_INVOKE_DRIVERS = 2 所以这里会被执行2次for (i = KDIMGSENSOR_INVOKE_DRIVER_0; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS; i++) {/* */spin_lock(&kdsensor_drv_lock);
//设置为FALSE
  g_bEnableDriver[i] = FALSE;
//前后摄标志获取,1为后摄,2为前摄
 g_invokeSocketIdx[i] = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_MSB) >> KDIMGSENSOR_DUAL_SHIFT);spin_unlock(&kdsensor_drv_lock);
//获取从上层传递下来的hal层的sensorlist里面排在第i顺序的imgsensor 的index
 drvIdx[i] = (pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_LSB);/* */
//判断数组里是否已经存在了driver
 if (DUAL_CAMERA_NONE_SENSOR == g_invokeSocketIdx[i]) {continue;}if (DUAL_CAMERA_SUB_SENSOR == g_invokeSocketIdx[i]) {spin_lock(&kdsensor_drv_lock);gI2CBusNum = SUPPORT_I2C_BUS_NUM2;spin_unlock(&kdsensor_drv_lock);/* PK_XLOG_INFO("kdSetDriver: switch I2C BUS2 "); */} else {spin_lock(&kdsensor_drv_lock);gI2CBusNum = SUPPORT_I2C_BUS_NUM1;spin_unlock(&kdsensor_drv_lock);/* PK_XLOG_INFO("kdSetDriver: switch I2C BUS1 "); */}#endifPK_INF("g_invokeSocketIdx[%d]=%d,drvIdx[%d]=%d ", i, g_invokeSocketIdx[i], i, drvIdx[i]);/* PK_INF("[kdSetDriver]drvIdx[%d] = %d ", i, drvIdx[i]); *//* */if (MAX_NUM_OF_SUPPORT_SENSOR > drvIdx[i]) {if (NULL == pSensorList[drvIdx[i]].SensorInit) {PK_ERR("ERROR:kdSetDriver() ");return -EIO;} pSensorList[drvIdx[i]].SensorInit(&g_pInvokeSensorFunc[i]);if (NULL == g_pInvokeSensorFunc[i]) {PK_ERR("ERROR:NULL g_pSensorFunc[%d] ", i);return -EIO;}/* */spin_lock(&kdsensor_drv_lock);g_bEnableDriver[i] = TRUE;spin_unlock(&kdsensor_drv_lock);/* get sensor name */memcpy((char *)g_invokeSensorNameStr[i], (char *)pSensorList[drvIdx[i]].drvname, sizeof(pSensorList[drvIdx[i]].drvname));/* return sensor ID *//* pDrvIndex[0] = (unsigned int)pSensorList[drvIdx].SensorId; */PK_INF("[%d][%d][%d][%s] ", i, g_bEnableDriver[i], g_invokeSocketIdx[i], g_invokeSensorNameStr[i]);}}return 0;}