從imgsensor_drv.cpp中的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
#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
//may need to keep power here
if (NULL != pExIdChkCbf) {
err2 = pExIdChkCbf();
if (err2 < 0) {
LOG_ERR("Error:pExIdChkCbf() \n");
}
}
//power off sensor
//close(SensorEnum);//ToDo: Check if necessary
if (err < 0 || err2 < 0) {
LOG_MSG("sensor ID mismatch\n");
}
else {
if (SensorEnum == DUAL_CAMERA_MAIN_SENSOR) {
//m_mainSensorIdx = i;
//m_mainSensorId = m_pstSensorInitFunc[m_mainSensorIdx].SensorId;
m_mainSensorDrv.index[m_mainSensorDrv.number] = i;
m_mainSensorDrv.type[m_mainSensorDrv.number] = sensorType;
if ( IMAGE_SENSOR_TYPE_RAW == sensorType && BAD_SENSOR_INDEX == m_mainSensorDrv.firstRawIndex ) {
m_mainSensorDrv.firstRawIndex = i;
}
else if ( IMAGE_SENSOR_TYPE_YUV == sensorType && BAD_SENSOR_INDEX == m_mainSensorDrv.firstYuvIndex ) {
m_mainSensorDrv.firstYuvIndex = i;
}
m_mainSensorDrv.position = socketPos;
m_mainSensorDrv.sensorID = m_pstSensorInitFunc[m_mainSensorDrv.index[m_mainSensorDrv.number]].SensorId;
// LOG_MSG("MAIN sensor m_mainSensorDrv.number=%d, m_mainSensorDrv.index=%d\n",m_mainSensorDrv.number,m_mainSensorDrv.index[m_mainSensorDrv.number]);
m_mainSensorDrv.number++;
//
m_pMainSensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
if ( m_pMainSensorInfo )
{
NSFeature::SensorInfoBase* pSensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
LOG_MSG("found <%#x/%s/%s>", pSensorInfo->GetID(), pSensorInfo->getDrvName(), pSensorInfo->getDrvMacroName());
}
else
{
LOG_WRN("m_pMainSensorInfo==NULL\n");
}
LOG_MSG("MAIN sensor found:[%d]/[0x%x]/[%d]/[%d] \n",i,id[KDIMGSENSOR_INVOKE_DRIVER_0],sensorType,socketPos);
//break;
}
else if (SensorEnum == DUAL_CAMERA_MAIN_2_SENSOR) {
//m_main2SensorIdx = i;
//m_main2SensorId = m_pstSensorInitFunc[m_main2SensorIdx].SensorId;
m_main2SensorDrv.index[m_main2SensorDrv.number] = i;
m_main2SensorDrv.type[m_main2SensorDrv.number] = sensorType;
if ( IMAGE_SENSOR_TYPE_RAW == sensorType && BAD_SENSOR_INDEX == m_main2SensorDrv.firstRawIndex ) {
m_main2SensorDrv.firstRawIndex = i;
}
else if ( IMAGE_SENSOR_TYPE_YUV == sensorType && BAD_SENSOR_INDEX == m_main2SensorDrv.firstYuvIndex ) {
m_main2SensorDrv.firstYuvIndex = i;
}
m_main2SensorDrv.position = socketPos;
m_main2SensorDrv.sensorID = m_pstSensorInitFunc[m_main2SensorDrv.index[m_main2SensorDrv.number]].SensorId;
//LOG_MSG("MAIN2 sensor m_main2SensorDrv.number=%d, m_main2SensorDrv.index=%d\n",m_main2SensorDrv.number,m_main2SensorDrv.index[m_main2SensorDrv.number]);
m_main2SensorDrv.number++;
//
m_pMain2SensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
if ( m_pMain2SensorInfo )
{
NSFeature::SensorInfoBase* pSensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
LOG_MSG("found <%#x/%s/%s>", pSensorInfo->GetID(), pSensorInfo->getDrvName(), pSensorInfo->getDrvMacroName());
}
else
{
LOG_WRN("m_pMain2SensorInfo==NULL\n");
}
LOG_MSG("MAIN_2 sensor found:[%d]/[0x%x]/[%d]/[%d] \n",i,id[KDIMGSENSOR_INVOKE_DRIVER_0],sensorType,socketPos);
}
else if (SensorEnum == DUAL_CAMERA_SUB_SENSOR) {
//m_subSensorIdx = i;
//m_subSensorId = m_pstSensorInitFunc[m_subSensorIdx].SensorId;
m_subSensorDrv.index[m_subSensorDrv.number] = i;
m_subSensorDrv.type[m_subSensorDrv.number] = sensorType;
if ( IMAGE_SENSOR_TYPE_RAW == sensorType && BAD_SENSOR_INDEX == m_subSensorDrv.firstRawIndex ) {
m_subSensorDrv.firstRawIndex = i;
}
else if ( IMAGE_SENSOR_TYPE_YUV == sensorType && BAD_SENSOR_INDEX == m_subSensorDrv.firstYuvIndex ) {
m_subSensorDrv.firstYuvIndex = i;
}
m_subSensorDrv.position = socketPos;
m_subSensorDrv.sensorID = m_pstSensorInitFunc[m_subSensorDrv.index[m_subSensorDrv.number]].SensorId;
//LOG_MSG("SUB sensor m_subSensorDrv.number=%d, m_subSensorDrv.index=%d\n",m_subSensorDrv.number,m_subSensorDrv.index[m_subSensorDrv.number]);
m_subSensorDrv.number++;
//
m_pSubSensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
if ( m_pSubSensorInfo )
{
NSFeature::SensorInfoBase* pSensorInfo = m_pstSensorInitFunc[i].pSensorInfo;
LOG_MSG("found <%#x/%s/%s>", pSensorInfo->GetID(), pSensorInfo->getDrvName(), pSensorInfo->getDrvMacroName());
}
else
{
LOG_WRN("m_pSubSensorInfo==NULL\n");
}
LOG_MSG("SUB sensor found:[%d]/[0x%x]/[%d]/[%d] \n",i,id[KDIMGSENSOR_INVOKE_DRIVER_0],sensorType,socketPos);
//break;
}
}//
}
}
//close system call may be off sensor power. check first!!!
if(m_fdSensor >= 0)
{
::close(m_fdSensor);
m_fdSensor = -1;
}
//
if (BAD_SENSOR_INDEX != m_mainSensorDrv.index[0]) {
m_mainSensorId = m_mainSensorDrv.sensorID;
//init to choose first
m_mainSensorIdx = m_mainSensorDrv.index[0];
sensorDevs |= SENSOR_MAIN;
}
if (BAD_SENSOR_INDEX != m_main2SensorDrv.index[0]) {
m_main2SensorId = m_main2SensorDrv.sensorID;
//init to choose first
m_main2SensorIdx = m_main2SensorDrv.index[0];
sensorDevs |= SENSOR_MAIN_2;
}
if (BAD_SENSOR_INDEX != m_subSensorDrv.index[0]) {
m_subSensorId = m_subSensorDrv.sensorID;
//init to choose first
m_subSensorIdx = m_subSensorDrv.index[0];
sensorDevs |= SENSOR_SUB;
}
#ifdef ATVCHIP_MTK_ENABLE
sensorDevs |= SENSOR_ATV;
#endif
if (sensorDevs == SENSOR_NONE) {
LOG_ERR( "Error No sensor found!! \n");
}
//
LOG_MSG("SENSOR search end: 0x%x /[0x%x][%d]/[0x%x][%d]/[0x%x][%d]\n", sensorDevs,
m_mainSensorId,m_mainSensorIdx,m_main2SensorId,m_main2SensorIdx,m_subSensorId,m_subSensorIdx);
return sensorDevs;
}//
1. 首先獲取hal層的sensor列表。
GetSensorInitFuncList(&m_pstSensorInitFunc);
GetSensorInitFuncList()函數代碼如下(sensorlist.cpp)
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()
也就是得到一個sensor列表。如果你要新增一個camera,必須在這個數組中使用RAW_INFO或YUV_INFO宏新增一個成員。
然後使用open函數打開一個字符設備,hal層同驅動層的接口實際上實際上是通過一個字符設備,這個字符設備提供了相應的fops操作,使用最多的當然是ioctl函數。
2. set driver
默認android中只支持兩個camera,即前camera、後camera,所以在這裏首先是要找到這兩個camera(先後camera、再前camera)。
而在mtk平臺代碼中,最多支持16種攝像頭配置,然後是調用ioctl函數。
ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,&id[KDIMGSENSOR_INVOKE_DRIVER_0] );
ioctl接口函數爲kd_sensorlist.c的中的CAMERA_HW_Ioctl()函數。
而kdSetDriver代碼如下:
int kdSetDriver(unsigned int *pDrvIndex)
{
ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;
u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0, 0};
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];
if (0 != kdGetSensorInitFuncList(&pSensorList))
{
PK_ERR("ERROR:kdGetSensorInitFuncList()\n");
return -EIO;
}
for (i = KDIMGSENSOR_INVOKE_DRIVER_0; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS; i++) {
/* */
spin_lock(&kdsensor_drv_lock);
g_bEnableDriver[i] = FALSE;
g_invokeSocketIdx[i] = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_MSB)>>KDIMGSENSOR_DUAL_SHIFT);
spin_unlock(&kdsensor_drv_lock);
drvIdx[i] = (pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_LSB);
/* */
if (DUAL_CAMERA_NONE_SENSOR == g_invokeSocketIdx[i]) { continue; }
#if 0
if (DUAL_CAMERA_MAIN_SENSOR == g_invokeSocketIdx[i] || DUAL_CAMERA_SUB_SENSOR == g_invokeSocketIdx[i] || DUAL_CAMERA_MAIN_2_SENSOR == g_invokeSocketIdx[i]) {
spin_lock(&kdsensor_drv_lock);
gI2CBusNum = SENSOR_I2C_BUS_NUM[g_invokeSocketIdx[i]];
spin_unlock(&kdsensor_drv_lock);
PK_XLOG_INFO("kd_MultiSensorOpen: switch I2C BUS%d\n", gI2CBusNum);
}
#else
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"); */
}
#endif
PK_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;
}
kdSetDriver()函數有一個參數,這個參數是由impSearchSensor()傳下來的,如果主(後)camera,那麼這個值是10000、10001、10002等,如果是次(前)camera,那麼這個值是20000、20001、20002等。在kdSetDriver函數中,首先調用kdGetSensorInitFuncList()函數去獲得kernel中定義的sensor列表。
來到for循環那裏,如果是後camera,那麼g_invokeSocketIdx[0]的值應爲1,如果是前camera,那麼應是2。而drvIdx[0]的值是sensor驅動列表的索引號,例如0、1、2等。
設置i2c的總線號,再來到最後面的if語句處,根據drvIdx[0]找到驅動中定義的sensor代碼,調用驅動中的SensorInit函數,這樣就得到了具體sensor驅動的接口。
最後把sensor驅動的name字段拷貝到g_invokeSensorNameStr[0]這裏。
注意傳給kdSetDriver()的id值只有一個,例如10000,所以第2遍for循環是不會走到最後的(continue掉)。
再回到impSearchSensor()。
3. check is alive
前面已經指定了一個sensor驅動,那麼這裏就會調用ioctl函數去檢查驅動和camera設備是否匹配。
調用的是kd_sensorlist.c中的adopt_CAMERA_HW_CheckIsAlive()函數。
inline static int adopt_CAMERA_HW_CheckIsAlive(void)
{
UINT32 err = 0;
UINT32 err1 = 0;
UINT32 i = 0;
MUINT32 sensorID = 0;
MUINT32 retLen = 0;
#ifndef CONFIG_MTK_FPGA
KD_IMGSENSOR_PROFILE_INIT();
/* power on sensor */
kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM *)g_invokeSocketIdx, g_invokeSensorNameStr, true, CAMERA_HW_DRVNAME1);
/* wait for power stable */
mDELAY(10);
KD_IMGSENSOR_PROFILE("kdModulePowerOn");
/* initial for search sensor function */
g_CurrentSensorIdx = 0;
/* Search sensor keep i2c debug log */
g_IsSearchSensor = 1;
/* Camera information */
if(gDrvIndex == 0x10000)
{
memset(mtk_ccm_name,0,camera_info_size);
}
if (g_pSensorFunc) {
for (i = KDIMGSENSOR_INVOKE_DRIVER_0; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS; i++) {
if (DUAL_CAMERA_NONE_SENSOR != g_invokeSocketIdx[i]) {
err = g_pSensorFunc->SensorFeatureControl(g_invokeSocketIdx[i], SENSOR_FEATURE_CHECK_SENSOR_ID, (MUINT8 *)&sensorID, &retLen);
if (sensorID == 0) { /* not implement this feature ID */
PK_DBG(" Not implement!!, use old open function to check\n");
err = ERROR_SENSOR_CONNECT_FAIL;
}
else if (sensorID == 0xFFFFFFFF) { /* fail to open the sensor */
PK_DBG(" No Sensor Found");
err = ERROR_SENSOR_CONNECT_FAIL;
}
else {
PK_INF(" Sensor found ID = 0x%x\n", sensorID);
snprintf(mtk_ccm_name,sizeof(mtk_ccm_name),"%s CAM[%d]:%s;",mtk_ccm_name,g_invokeSocketIdx[i],g_invokeSensorNameStr[i]);
err = ERROR_NONE;
}
if (ERROR_NONE != err)
{
PK_DBG("ERROR:adopt_CAMERA_HW_CheckIsAlive(), No imgsensor alive\n");
}
}
}
}
else {
PK_DBG("ERROR:NULL g_pSensorFunc\n");
}
/* reset sensor state after power off */
err1 = g_pSensorFunc->SensorClose();
if (ERROR_NONE != err1) {
PK_DBG("SensorClose\n");
}
/* */
kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM *)g_invokeSocketIdx, g_invokeSensorNameStr, false, CAMERA_HW_DRVNAME1);
/* */
KD_IMGSENSOR_PROFILE("CheckIsAlive");
#else
err = ERROR_SENSOR_CONNECT_FAIL;
#endif
g_IsSearchSensor = 0;
return err ? -EIO:err;
} /* adopt_CAMERA_HW_Open() */
首先是調用kdModulePowerOn()給模塊上電,等待10毫秒,來到for循環這裏。調用sensor驅動的SensorFeatureControl接口去讀取sensor的id。sensor id只要大於0、小於0xffffffff都是合法的。
sensor id讀取完成之後再關閉掉模塊電源。
再回到impSearchSensor()。
只要這個id值找到,那麼表示驅動已經匹配上了,但是在impSearchSensor()函數中,找到並不意味着結束,for循環還是會繼續進行下去的,就是所有定義的sensor驅動都還是會去遍歷一遍。那麼這就是找到一個sensor的流程,先主(後)camera,後次(前)camera。
找後camera,會遍歷一遍sensor列表,找前camera,再遍歷一遍sensor列表,注意模塊的上電,id值的讀取。
// 2016-10-21 add
根據impSearchSensor()函數,如果有定義輔攝像頭,那麼需要定義宏MTK_SUB_IMGSENSOR,否則的話是不會去搜索輔攝像頭的。
MTK_SUB_IMGSENSOR宏是在hal層的Android.mk中被定義的,定義的前提是在ProjectConfig.mk中CUSTOM_KERNEL_SUB_IMGSENSOR要配置一下,否則不會去搜尋輔攝像頭的。