MTK Camera上電流程分析

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;}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章