mtk camera加载流程

平台:mt6735

从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要配置一下,否则不会去搜寻辅摄像头的。

你可能感兴趣的:(mtk开发)