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 \n");
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 \n");
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 \n", 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\n");
#else
#ifdef MTK_SUB_IMGSENSOR
for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum <= DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {
LOG_MSG("impSearchSensor search to sub\n");
#else
for (SensorEnum = DUAL_CAMERA_MAIN_SENSOR; SensorEnum < DUAL_CAMERA_SUB_SENSOR; SensorEnum <<= 1) {
LOG_MSG("impSearchSensor search to main\n");
#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 \n", i);
break;
}
//set sensor driver
id[KDIMGSENSOR_INVOKE_DRIVER_0] = (SensorEnum << KDIMGSENSOR_DUAL_SHIFT) | i;
LOG_MSG("set sensor driver id =%x\n", 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\n");
}
//err = open();
err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE);
if (err < 0) {
LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) \n", 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),
#endif
UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
if (NULL == ppSensorList) {
ALOGE("ERROR: NULL pSensorList\n");
return MHAL_UNKNOWN_ERROR;
}
*ppSensorList = &SensorList[0];
return MHAL_NO_ERROR;
} // GetSensorInitFuncList()
至此hal層和mtkcam開始關聯起來,以上全紅的文字是實現上比較巧妙的地方,框架中提供了一個單例實例,並讓各種Sensor單獨去實現以下比較重要的2個接口。
typedef NSFeature::RAWSensorInfo<SENSOR_ID> 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<SENSOR_ID> 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\n");
}
//err = open();
err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_CHECK_IS_ALIVE);
if (err < 0) {
LOG_MSG("[impSearchSensor] Err-ctrlCode (%s) \n", 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\n", 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()\n");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\n"); */} else {spin_lock(&kdsensor_drv_lock);gI2CBusNum = SUPPORT_I2C_BUS_NUM1;spin_unlock(&kdsensor_drv_lock);/* PK_XLOG_INFO("kdSetDriver: switch I2C BUS1\n"); */}#endifPK_INF("g_invokeSocketIdx[%d]=%d,drvIdx[%d]=%d\n", i, g_invokeSocketIdx[i], i, drvIdx[i]);/* PK_INF("[kdSetDriver]drvIdx[%d] = %d\n", i, drvIdx[i]); *//* */if (MAX_NUM_OF_SUPPORT_SENSOR > drvIdx[i]) {if (NULL == pSensorList[drvIdx[i]].SensorInit) {PK_ERR("ERROR:kdSetDriver()\n");return -EIO;} pSensorList[drvIdx[i]].SensorInit(&g_pInvokeSensorFunc[i]);if (NULL == g_pInvokeSensorFunc[i]) {PK_ERR("ERROR:NULL g_pSensorFunc[%d]\n", 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]\n", i, g_bEnableDriver[i], g_invokeSocketIdx[i], g_invokeSensorNameStr[i]);}}return 0;}