CAMERA的开机过程学习

下面分析下CAMERA的开机过程:

开机过程重要做了下面几件事情:

1,  camera service的注册。

2,  统计有效CAMERA的信息

 

STEP1:

\frameworks\av\services\camera\libcameraservice\CameraService.cpp

 

void CameraService::onFirstRef()

{

   ALOGI("CameraService process starting");

 

   BnCameraService::onFirstRef();

 

   // Update battery life tracking if service is restarting

   BatteryNotifier& notifier(BatteryNotifier::getInstance());

   notifier.noteResetCamera();

   notifier.noteResetFlashlight();

 

   camera_module_t *rawModule;

    int err =hw_get_module(CAMERA_HARDWARE_MODULE_ID,

            (const hw_module_t**)&rawModule);

/*

主要的事情都是在hw_get_module里面做的。会像HAL去搜索有效的SENSOR,并且获取SENSORINFO

*/

   if (err < 0) {

       ALOGE("Could not load camera HAL module: %d (%s)", err,strerror(-err));

       logServiceError("Could not load camera HAL module", err);

       mNumberOfCameras = 0;

       return;

    }

 

   mModule = new CameraModule(rawModule);

   ALOGI("Loaded \"%s\" camera module",mModule->getModuleName());

   err = mModule->init();

   if (err != OK) {

       ALOGE("Could not initialize camera HAL module: %d (%s)", err,

           strerror(-err));

       logServiceError("Could not initialize camera HAL module",err);

 

       mNumberOfCameras = 0;

       delete mModule;

       mModule = nullptr;

       return;

    }

 

   mNumberOfCameras = mModule->getNumberOfCameras();

   mNumberOfNormalCameras = mNumberOfCameras;

/*

 前面的参数已经获取到了,这里只是返回前面获取的参数而已。

*/

   mFlashlight = new CameraFlashlight(*mModule, *this);

   status_t res = mFlashlight->findFlashUnits();

   if (res) {

       // impossible because we haven't open any camera devices.

       ALOGE("Failed to find flash units.");

    }

 

   int latestStrangeCameraId = INT_MAX;

   for (int i = 0; i < mNumberOfCameras; i++) {

       String8 cameraId = String8::format("%d", i);

 

       // Get camera info

 

       struct camera_info info;

       bool haveInfo = true;

       status_t rc = mModule->getCameraInfo(i, &info);

       if (rc != NO_ERROR) {

           ALOGE("%s: Received error loading camera info for device %d, costand"

                    " conflicting devicesfields set to defaults for this device.",

                    __FUNCTION__, i);

           haveInfo = false;

       }

 

       // Check for backwards-compatibility support

       if (haveInfo) {

           if (checkCameraCapabilities(i, info, &latestStrangeCameraId) != OK){

                delete mModule;

                mModule = nullptr;

                return;

           }

       }

 

       // Defaults to use for cost and conflicting devices

       int cost = 100;

       char** conflicting_devices = nullptr;

       size_t conflicting_devices_length = 0;

 

       // If using post-2.4 module version, query the cost + conflictingdevices from the HAL

       if (mModule->getModuleApiVersion() >=CAMERA_MODULE_API_VERSION_2_4 && haveInfo) {

            cost = info.resource_cost;

           conflicting_devices = info.conflicting_devices;

           conflicting_devices_length = info.conflicting_devices_length;

       }

 

       std::set conflicting;

       for (size_t i = 0; i < conflicting_devices_length; i++) {

           conflicting.emplace(String8(conflicting_devices[i]));

       }

 

       // Initialize state for each camera device

       {

           Mutex::Autolock lock(mCameraStatesLock);

           mCameraStates.emplace(cameraId,std::make_shared(cameraId, cost,

                    conflicting));

       }

 

       if (mFlashlight->hasFlashUnit(cameraId)) {

           mTorchStatusMap.add(cameraId,

                   ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF);

       }

    }

 

   if (mModule->getModuleApiVersion() >=CAMERA_MODULE_API_VERSION_2_1) {

       mModule->setCallbacks(this);

    }

 

   VendorTagDescriptor::clearGlobalVendorTagDescriptor();

 

   if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2){

       setUpVendorTags();

    }

 

   CameraDeviceFactory::registerService(this);

 

   CameraService::pingCameraServiceProxy();

}

 

/*hw_get_module是根据CAMERA_HARDWARE_MODULE_ID加载相应的MODELE。具体的加载过程有一篇文章有专门的描述,这里就不深入了。

*/

 

STEP 2:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\module_hal\module\module.h

 

static

camera_module

get_camera_module()

{

   camera_module module = {

       common:{

            tag                    : HARDWARE_MODULE_TAG,

            #if (PLATFORM_SDK_VERSION >= 21)

                #if NEED_MODULE_API_VERSION_2_3

                #warning"NEED_MODULE_API_VERSION_2_3 is: 1, useCAMERA_MODULE_API_VERSION_2_3"

                    module_api_version     : CAMERA_MODULE_API_VERSION_2_3,

                #else

                #warning"NEED_MODULE_API_VERSION_2_3 is: 0, use defaultCAMERA_MODULE_API_VERSION_2_4"

                    module_api_version     : CAMERA_MODULE_API_VERSION_2_4,

                #endif

            #else

                    module_api_version     : CAMERA_DEVICE_API_VERSION_1_0,

            #endif

            hal_api_version        :HARDWARE_HAL_API_VERSION,

            id                     : CAMERA_HARDWARE_MODULE_ID,

            name                   :"MediaTek Camera Module",

            author                 :"MediaTek",

            methods                :get_module_methods(),

            dso                    : NULL,

            reserved               : {0},

       },

       get_number_of_cameras       :get_number_of_cameras,

       get_camera_info             :get_camera_info,

       set_callbacks               :set_callbacks,

       get_vendor_tag_ops          :get_vendor_tag_ops,

       #if (PLATFORM_SDK_VERSION >= 21)

       open_legacy                 :open_legacy,

       #endif

       set_torch_mode              :set_torch_mode,

       init                        :NULL,

       reserved                    : {0},

    };

   return  module;

};

 

Step 3:

\frameworks\av\services\camera\libcameraservice\common\CameraModule.cpp

 

//进入CameraModule的构造函数。

 

CameraModule::CameraModule(camera_module_t*module) {

   if (module == NULL) {

       ALOGE("%s: camera hardware module must not be null",__FUNCTION__);

       assert(0);

    }

   mModule = module;

   mCameraInfoMap.setCapacity(getNumberOfCameras());

}

 

Step 4:

 

int CameraModule::getNumberOfCameras() {

   return mModule->get_number_of_cameras();

}

//返回到module.h中对于的get_number_of_cameras函数;

Step 5:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\module_hal\module\module.h

 

static

int

get_number_of_cameras(void)

{

   return NSCam::getCamDeviceManager()->getNumberOfDevices();

}

/*

getCamDeviceManager类中没有实现getNumberOfDevices,具体是实现是在其父类CamDeviceManagerBase中完成的。

*/

 

STEP 6:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\module_hal\devicemgr\CamDeviceManagerBase.cpp

 

int32_t

CamDeviceManagerBase::

getNumberOfDevices()

{

   RWLock::AutoWLock _l(mRWLock);

         MY_LOGD("larrytest--->getNumberOfDevices#devices:%d",mi4DeviceNum);

 

   if  ( 0 != mi4DeviceNum )

    {

       MY_LOGD("#devices:%d", mi4DeviceNum);

    }

   else

    {

       Utils::CamProfile _profile(__FUNCTION__,"CamDeviceManagerBase");

       mi4DeviceNum = enumDeviceLocked();

/*

第一次进来mi4DeviceNum0,进入enumDeviceLocked。这个是很关键的函数,干了很多事实。

*/

       _profile.print("");

    }

   //

   return  mi4DeviceNum;

}

 

Step 7:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\devicemgr\CamDeviceManagerImp.cpp

 

int32_t

CamDeviceManagerImp::

enumDeviceLocked()

{

   Utils::CamProfile _profile(__FUNCTION__,"CamDeviceManagerImp");

   //

   status_t status = OK;

   int32_t i4DeviceNum = 0;

   //

#if '1'==MTKCAM_HAVE_METADATA

       NSMetadataProviderManager::clear();

#endif

   mEnumMap.clear();

 

//------------------------------------------------------------------------------

#if '1'==MTKCAM_HAVE_SENSOR_HAL

 

   mEnumMap.clear();

   DevMetaInfo::clear();

   //

   int32_t isFakeOrientation = 0;

   int32_t i4DevSetupOrientation = 0;

   camera_info camInfo;

   camInfo.device_version = CAMERA_DEVICE_API_VERSION_1_0;

   camInfo.static_camera_characteristics = NULL;

   //

SensorHal* pSensorHal = SensorHal::createInstance();

/*

创建是的是其之类:SensorHalImp

SensorHal* SensorHal::createInstance()

{

    returnSensorHalImp::getInstance();

}

*/

   if  ( ! pSensorHal )

    {

       MY_LOGE("pSensorHal == NULL");

       return 0;

    }

   //

    int32_t const iSensorsList = pSensorHal->searchSensor();

    //所以也就是SensorHalImpsearchSensor

   //

   if  ( (iSensorsList &SENSOR_DEV_MAIN_3D) == SENSOR_DEV_MAIN_3D )

    {

       MY_LOGI("Stereo 3D Camera found");

    }

   //

   if  ( (iSensorsList &SENSOR_DEV_MAIN) == SENSOR_DEV_MAIN )

    {

       int32_t const deviceId = i4DeviceNum;

#if '1'==MTKCAM_HAVE_METADATA

       sp pMetadataProvider =IMetadataProvider::create(deviceId);

       NSMetadataProviderManager::add(deviceId, pMetadataProvider.get());

#endif

       //

       halSensorDev_e const eHalSensorDev = SENSOR_DEV_MAIN;

       pSensorHal->sendCommand(eHalSensorDev,SENSOR_CMD_GET_FAKE_ORIENTATION, (int)&isFakeOrientation);

       pSensorHal->sendCommand(eHalSensorDev,SENSOR_CMD_GET_SENSOR_ORIENTATION_ANGLE, (int)&i4DevSetupOrientation);

        pSensorHal->sendCommand(eHalSensorDev,SENSOR_CMD_GET_SENSOR_FACING_DIRECTION, (int)&camInfo.facing);

       camInfo.orientation = i4DevSetupOrientation;

       if  ( isFakeOrientation )

       {

           camInfo.orientation = (0==camInfo.facing) ? 90 : 270;

           MY_LOGW("Fake orientation:%d instead of %d, facing=%dHalSensorDev=%#x", camInfo.orientation, i4DevSetupOrientation,camInfo.facing, eHalSensorDev);

       }

       DevMetaInfo::add(deviceId, camInfo, i4DevSetupOrientation,eDevId_ImgSensor, eHalSensorDev);

       //

       sp pInfo = new EnumInfo;

       pInfo->uDeviceVersion       =CAMERA_DEVICE_API_VERSION_1_0;

       pInfo->pMetadata            =NULL;

       pInfo->iFacing              =camInfo.facing;

       pInfo->iWantedOrientation   =camInfo.orientation;

       pInfo->iSetupOrientation    =i4DevSetupOrientation;

       #if 0

       #if HAS_FLASHLIGHT

       #warning "HAS_FLASHLIGHT: 1"

           // todo: we set it to 1 for  maincamera, should use metadata for future

           pInfo->iHasFlashLight       =1;       

       #else

       #warning "HAS_FLASHLIGHT: 0"

           #ifdef DUMMY_FLASHLIGHT

                pInfo->iHasFlashLight       = 0;

           #else

                pInfo->iHasFlashLight       = 0;

           #endif

       #endif

       #else

           #if '1'==MTKCAM_HAVE_METADATA

                pInfo->pMetadata            =pMetadataProvider->getStaticCharacteristics();

                pInfo->iHasFlashLight       = pMetadataProvider->getDeviceHasFlashLight();

           #else

                pInfo->pMetadata            = NULL;

                pInfo->iHasFlashLight       = 0;

           #endif

       #endif

       MY_LOGD("pInfo->iHasFlashLight:%d",pInfo->iHasFlashLight);

        mEnumMap.add(deviceId, pInfo);

       //

       i4DeviceNum++;

    }

   //

   if  ( (iSensorsList &SENSOR_DEV_SUB) == SENSOR_DEV_SUB )

    ……

   //

   if  ( pSensorHal )

    {

       pSensorHal->destroyInstance();

       pSensorHal = NULL;

    }

   //

   MY_LOGI("iSensorsList=0x%08X, i4DeviceNum=%d", iSensorsList,i4DeviceNum);

   for (size_t i = 0; i < mEnumMap.size(); i++)

    {

       int32_t const deviceId = mEnumMap.keyAt(i);

       sp pInfo = mEnumMap.valueAt(i);

       uint32_t const uDeviceVersion   =pInfo->uDeviceVersion;

       camera_metadata const*pMetadata = pInfo->pMetadata;

       int32_t const iFacing           =pInfo->iFacing;

       int32_t const iWantedOrientation= pInfo->iWantedOrientation;

       int32_t const iSetupOrientation = pInfo->iSetupOrientation;

       MY_LOGI(

           "[0x%02x] orientation(wanted/setup)=(%d/%d) facing:%d metadata:%pDeviceVersion:0x%x",

           deviceId, iWantedOrientation, iSetupOrientation,

           iFacing, pMetadata, uDeviceVersion

       );

    }

 

…..

   _profile.print("");

   return  i4DeviceNum;

}

 

Step 8:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\core\drv\imgsensor\sensor_hal.cpp

 

MINT32 SensorHalImp::searchSensor()

{

   MINT32 sensorDevs = 0;

   MINT32 ret;

   MINT32 clkCnt = 1;

   #ifndef USING_MTK_LDVT

   //CPTLog(Event_Sensor_search, CPTFlagStart);

   #endif

 

   ret = pSeninfDrv->init();

   if (ret < 0) {

       LOG_ERR("pSeninfDrv->init() fail\n");

       return 0;

    }

 

   //ret = pSeninfDrv->autoDeskewCalibration(); //mipi calibration

 

   

   memset(&sensorInfo[0], 0, sizeof(ACDK_SENSOR_INFO_STRUCT));

   memset(&sensorInfo[1], 0, sizeof(ACDK_SENSOR_INFO_STRUCT));   

   memset(&sensorCfg[0], 0, sizeof(ACDK_SENSOR_CONFIG_STRUCT));

   memset(&sensorCfg[1], 0, sizeof(ACDK_SENSOR_CONFIG_STRUCT));   

   

   // Before searching sensor, need to turn on clock of TG

   // Config TG, always use Camera PLL, 1: 48MHz, clkCnt is 1,  48MHz /2 = 24MHz

 

   //ToDo: select  PLL group    

   ret = pSeninfDrv->setTg1PhaseCounter(

       1, CAM_PLL_48_GROUP, /*sensorInfo.SensorMasterClockSwitch,*/

       clkCnt, sensorInfo[0].SensorClockPolarity ? 0 : 1,

       1, 0, 0);       

   if (ret < 0) {

       LOG_ERR("setTg1PhaseCounter fail\n");

       return 0;

    }

 

       

    

   // Search sensor

    mSearchSensorDev = SensorDrv::searchSensor(NULL);

   //

   //get sensor info

   querySensorInfo();

 

 

   ret = pSeninfDrv->uninit();

   if (ret < 0) {

       LOG_ERR("pSeninfDrv->uninit() fail\n");

    }

   LOG_MSG("[searchSensor] sensorDevs =0x%x\n",mSearchSensorDev);

 

   #ifndef USING_MTK_LDVT

   //CPTLog(Event_Sensor_search, CPTFlagEnd);

   #endif

   return mSearchSensorDev;

}

 

Step 9:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\core\drv\imgsensor\

sensor_drv.cpp

 

MINT32

SensorDrv::searchSensor(pfExIdChkpExIdChkCbf)

{

   return ImgSensorDrv::getInstance()->impSearchSensor(pExIdChkCbf);

}

 

Step 10:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\core\drv\imgsensor\

imgsensor_drv.cpp

 

MINT32

ImgSensorDrv::impSearchSensor(pfExIdChkpExIdChkCbf)

{

   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_subSensorIdx) {

           sensorDevs |= SENSOR_SUB;

       }

 

       #ifdef  ATVCHIP_MTK_ENABLE

 

           sensorDevs |= SENSOR_ATV;

 

       #endif

 

 

       return sensorDevs;

    }

 

    GetSensorInitFuncList(&m_pstSensorInitFunc);

/*

获取到\vendor\mediatek\proprietary\custom\mt8127\hal\imgsensor_src\sensorlist.cpp中定义的sensor. 数据格式为:

MSDK_SENSOR_INIT_FUNCTION_STRUCTSensorList[] =

{

#ifdefined(SP2508_RAW)

    RAW_INFO(SP2508_SENSOR_ID,SENSOR_DRVNAME_SP2508_RAW, NULL),

#endif

#if defined(SP2509_RAW)

    RAW_INFO(SP2509_SENSOR_ID,SENSOR_DRVNAME_SP2509_RAW, NULL),

#endif

。。。。。。

 

UINT32GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)

{

    if (NULL == ppSensorList) {

        ALOGE("ERROR: NULLpSensorList\n");

        return MHAL_UNKNOWN_ERROR;

    }

    *ppSensorList = &SensorList[0];

         return MHAL_NO_ERROR;

} //GetSensorInitFuncList()

*/

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

/*

#define CAMERA_HW_DEVNAME                       "kd_camera_hw"

kd_camera_hw这个设备是kernel层开机创建的camera设备文件。具体的创建过程我们将再另外一篇文章中介绍。

*/

   if (m_fdSensor < 0) {

        LOG_ERR("[impSearchSensor]: error opening %s: %s \n", cBuf,strerror(errno));

       return sensorDevs;

    }

   LOG_MSG("[impSearchSensor] m_fdSensor = %d  \n", m_fdSensor);

 

   // search main/main_2/sub 3 sockets

  #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

       LOG_MSG("impSearchSensor search to main\n");

  #endif

       //skip atv case

       if ( 0x04 == SensorEnum ) continue;

       //

       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 <

           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]);

/*

IOCTL通过设备kd_camera_hw与驱动进行通信。具体的通信内容在KERNEL中有说明。下面的ioctl(m_fdSensor,KDIMGSENSORIOC_T_CHECK_IS_ALIVE);也是在做这个事情,确认sensorlist列出来的sensor是否有效。

*/

                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 EEPROMmaybe

                //may need to keep power here

                if (NULL != pExIdChkCbf) {

                    err2 = pExIdChkCbf();

                    if (err2 < 0) {

                        LOG_ERR("Error:pExIdChkCbf()\n");

                    }

                }

 

                //power off sensor

                close();

 

                if (err < 0 || err2 < 0){

                    LOG_MSG("sensor IDmismatch\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 sensorm_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 sensorfound:[%d]/[0x%x]/[%d]/[%d]\n",i,id[KDIMGSENSOR_INVOKE_DRIVER_0],sensorType,socketPos);

                //break;

           }

           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 sensorm_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 sensorfound:[%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!!!

   ::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_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]\n",sensorDevs,

   m_mainSensorId,m_mainSensorIdx,m_subSensorId,m_subSensorIdx);

 

   return sensorDevs;

}//

 

到这里,开机的准备工作基本完成了,HAL层与KERNELIOCRL下面继续看一下:

KERNEL层的驱动是以模块的形式在开机的过程中加载的。我们就具体看看该模块的驱动就可以了。

Step1:

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\kd_sensorlist.c

//模块入口

module_init(CAMERA_HW_i2C_init);

module_exit(CAMERA_HW_i2C_exit);

 

step2:

 

static int __init CAMERA_HW_i2C_init(void)

{

   struct proc_dir_entry *prEntry;

 

         //i2c_register_board_info(CAMERA_I2C_BUSNUM,&kd_camera_dev, 1);

   i2c_register_board_info(SUPPORT_I2C_BUS_NUM1, &i2c_devs1, 1);

 

    if(platform_driver_register(&g_stCAMERA_HW_Driver)){//注册一个platform设备

       PK_ERR("failed to register CAMERA_HW driver\n");

       return -ENODEV;

    }

 

   //Register proc file for main sensor register debug

   prEntry = proc_create("driver/camsensor", 0, NULL,&g_stCAMERA_camsensor_fops);

         if(!prEntry) {

                   PK_ERR("add/proc/driver/camsensor entry fail\n");

         }

 

   atomic_set(&g_CamHWOpend, 0);

   atomic_set(&g_CamDrvOpenCnt, 0);

   atomic_set(&g_CamHWOpening, 0);

   return 0;

}

 

STEP 3:

 

static struct platform_driverg_stCAMERA_HW_Driver = {

    .probe                = CAMERA_HW_probe,

   .remove       = CAMERA_HW_remove,

   .suspend  = CAMERA_HW_suspend,

   .resume       = CAMERA_HW_resume,

   .driver                = {

       .name       ="image_sensor",

       .owner     = THIS_MODULE,

#ifdef CONFIG_OF

            .of_match_table = CAMERA_HW_of_ids,

#endif

    }

};

 

static const struct file_operationsg_stCAMERA_camsensor_fops = {

         .owner= THIS_MODULE,

         .read= CAMERA_HW_DumpReg_To_Proc,

         .write= CAMERA_HW_Reg_Debug

};

 

Step 4:

 

static int CAMERA_HW_probe(structplatform_device *pdev)

{

#ifdef MTKCAM_USING_PWRREG  /* Camera Power Regulator Framework base onDevice Tree */

 

         intret = 0;

         ret= cam_power_init(pdev, 0);

 

         if(ret < 0) {

                   if(ret == (-EPROBE_DEFER))

                            PK_ERR("CameraHW driver is probed earlier than PMIC, let's deferring probe");

                   returnret;

         }

 

#endif

 

#ifndef      CONFIG_MTK_GPIO

         mtkcam_gpio_init(pdev);

#endif

 

    returni2c_add_driver(&CAMERA_HW_i2c_driver);//注册一个I2C的驱动

}

 

Step 5:

 

struct i2c_driver CAMERA_HW_i2c_driver = {

         .probe= CAMERA_HW_i2c_probe,

         .remove= CAMERA_HW_i2c_remove,

         .driver= {

                      .name = CAMERA_HW_DRVNAME1,

                      .owner = THIS_MODULE,

 

#ifdef CONFIG_OF

                      .of_match_table = CAMERA_HW_i2c_of_ids,

#endif

                      },

         .id_table= CAMERA_HW_i2c_id,

};

 

STEP 6:

 

static int CAMERA_HW_i2c_probe(structi2c_client *client, const struct i2c_device_id *id)

{

   int i4RetValue = 0;

   PK_DBG("[CAMERA_HW] Attach I2C \n");

 

   //get sensor i2c client

   spin_lock(&kdsensor_drv_lock);

   g_pstI2Cclient = client;

   //set I2C clock rate

   /*g_pstI2Cclient->timing = 200;*/

   spin_unlock(&kdsensor_drv_lock);

 

   //Register char driver

    i4RetValue =RegisterCAMERA_HWCharDrv();

 

   if(i4RetValue){

       PK_ERR("[CAMERA_HW] register char device failed!\n");

       return i4RetValue;

    }

 

   //spin_lock_init(&g_CamHWLock);

 

   PK_DBG("[CAMERA_HW] Attached!! \n");

   return 0;

}

 

STEP 7:

 

inline static intRegisterCAMERA_HWCharDrv(void)

{

   struct device* sensor_device = NULL;

 

#if CAMERA_HW_DYNAMIC_ALLOCATE_DEVNO

if( alloc_chrdev_region(&g_CAMERA_HWdevno, 0,1,CAMERA_HW_DRVNAME1) )

/*

#define CAMERA_HW_DRVNAME1  "kd_camera_hw"

这个就是HAL通过IOCTL的设备节点。

*/

    {

       PK_DBG("[CAMERA SENSOR] Allocate device no failed\n");

 

       return -EAGAIN;

    }

#else

   if( register_chrdev_region( g_CAMERA_HWdevno , 1 , CAMERA_HW_DRVNAME1) )

    {

       PK_DBG("[CAMERA SENSOR] Register device no failed\n");

 

       return -EAGAIN;

    }

#endif

 

   //Allocate driver

   g_pCAMERA_HW_CharDrv = cdev_alloc();

 

   if(NULL == g_pCAMERA_HW_CharDrv)

    {

       unregister_chrdev_region(g_CAMERA_HWdevno, 1);

 

       PK_DBG("[CAMERA SENSOR] Allocate mem for kobject failed\n");

 

       return -ENOMEM;

    }

 

   //Attatch file operation.

    cdev_init(g_pCAMERA_HW_CharDrv, &g_stCAMERA_HW_fops);

//主要的IOCTL处理就在这个fops里面。

   g_pCAMERA_HW_CharDrv->owner = THIS_MODULE;

 

   //Add to system

   if(cdev_add(g_pCAMERA_HW_CharDrv, g_CAMERA_HWdevno, 1))

    {

       PK_DBG("[mt6516_IDP] Attatch file operation failed\n");

 

       unregister_chrdev_region(g_CAMERA_HWdevno, 1);

 

       return -EAGAIN;

    }

 

   sensor_class = class_create(THIS_MODULE, "sensordrv");

   if (IS_ERR(sensor_class)) {

       int ret = PTR_ERR(sensor_class);

       PK_DBG("Unable to create class, err = %d\n", ret);

       return ret;

    }

   sensor_device = device_create(sensor_class, NULL, g_CAMERA_HWdevno,NULL, CAMERA_HW_DRVNAME1);

 

   return 0;

}

 

STEP 8:

 

static const struct file_operationsg_stCAMERA_HW_fops =

{

   .owner = THIS_MODULE,

   .open = CAMERA_HW_Open,

    .release= CAMERA_HW_Release,

   .unlocked_ioctl = CAMERA_HW_Ioctl

 

};

 

STEP 9:

/*

我们上面开机注册过程用用多的两个comment就是在这里实现的:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\core\drv\imgsensor\

imgsensor_drv.cpp

 

KDIMGSENSORIOC_X_SET_DRIVERKDIMGSENSORIOC_T_CHECK_IS_ALIVE

*/

static long CAMERA_HW_Ioctl(

   struct file * a_pstFile,

   unsigned int a_u4Command,

   unsigned long a_u4Param

)

{

   int i4RetValue = 0;

   void * pBuff = NULL;

   u32 *pIdx = NULL;

 

   mutex_lock(&kdCam_Mutex);

 

    if(_IOC_NONE == _IOC_DIR(a_u4Command)) {

    }

   else {

       pBuff = kmalloc(_IOC_SIZE(a_u4Command),GFP_KERNEL);

 

       if(NULL == pBuff) {

           PK_DBG("[CAMERA SENSOR] ioctl allocate mem failed\n");

           i4RetValue = -ENOMEM;

           goto CAMERA_HW_Ioctl_EXIT;

       }

 

       if(_IOC_WRITE & _IOC_DIR(a_u4Command)){

           if(copy_from_user(pBuff , (void *) a_u4Param, _IOC_SIZE(a_u4Command))) {

                kfree(pBuff);

                PK_DBG("[CAMERA SENSOR]ioctl copy from user failed\n");

                i4RetValue =  -EFAULT;

                goto CAMERA_HW_Ioctl_EXIT;

           }

       }

    }

 

   pIdx = (u32*)pBuff;

   switch(a_u4Command) {

#if 0

       case KDIMGSENSORIOC_X_POWER_ON:

           i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx,true, CAMERA_HW_DRVNAME);

           break;

       case KDIMGSENSORIOC_X_POWER_OFF:

           i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx,false, CAMERA_HW_DRVNAME);

            break;

#endif

       caseKDIMGSENSORIOC_X_SET_DRIVER:

           i4RetValue = kdSetDriver((unsigned int*)pBuff);

           break;

       case KDIMGSENSORIOC_T_OPEN:

           i4RetValue = adopt_CAMERA_HW_Open();

           break;

       case KDIMGSENSORIOC_X_GETINFO:

           i4RetValue = adopt_CAMERA_HW_GetInfo(pBuff);

           break;

       case KDIMGSENSORIOC_X_GETRESOLUTION:

           i4RetValue = adopt_CAMERA_HW_GetResolution(pBuff);

           break;

       case KDIMGSENSORIOC_X_FEATURECONCTROL:

           i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);

           break;

       case KDIMGSENSORIOC_X_CONTROL:

           i4RetValue = adopt_CAMERA_HW_Control(pBuff);

           break;

       case KDIMGSENSORIOC_T_CLOSE:

           i4RetValue = adopt_CAMERA_HW_Close();

           break;

       case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:

           i4RetValue = adopt_CAMERA_HW_CheckIsAlive();

           break;

       case KDIMGSENSORIOC_X_GET_SOCKET_POS:

           i4RetValue = kdGetSocketPostion((unsigned int*)pBuff);

           break;

       case KDIMGSENSORIOC_X_SET_I2CBUS:

           //i4RetValue = kdSetI2CBusNum(*pIdx);

           break;

       case KDIMGSENSORIOC_X_RELEASE_I2C_TRIGGER_LOCK:

           //i4RetValue = kdReleaseI2CTriggerLock();

           break;

           

                   caseKDIMGSENSORIOC_X_SET_SHUTTER_GAIN_WAIT_DONE:

                            i4RetValue= kdSensorSetExpGainWaitDone((int*)pBuff);                        

                            break;                        

                      

             default :

                       PK_DBG("No such command\n");

                       i4RetValue = -EPERM;

                       break;

 

    }

 

   if(_IOC_READ & _IOC_DIR(a_u4Command)) {

       if(copy_to_user((void __user *) a_u4Param , pBuff ,_IOC_SIZE(a_u4Command))) {

           kfree(pBuff);

           PK_DBG("[CAMERA SENSOR] ioctl copy to user failed\n");

           i4RetValue =  -EFAULT;

           goto CAMERA_HW_Ioctl_EXIT;

       }

    }

 

   kfree(pBuff);

CAMERA_HW_Ioctl_EXIT:

   mutex_unlock(&kdCam_Mutex);

   return i4RetValue;

}

 

下面我们分别进入看看这两个命令的具体实现:

 

Step 10-1-1://分为两段分开跟进。

 

int kdSetDriver(unsigned int* pDrvIndex)

{

   ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;

   u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0,0};

   u32 i;

 

   PK_XLOG_INFO("pDrvIndex:0x%08x/0x%08x\n",pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0],pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_1]);

   //set driver for MAIN or SUB sensor

 

if (0 != kdGetSensorInitFuncList(&pSensorList))

/*获取定义的sensor,具体的定义在:

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\kd_sensorlist.h

ACDK_KD_SENSOR_INIT_FUNCTION_STRUCTkdSensorList[MAX_NUM_OF_SUPPORT_SENSOR+1] =

{

#if defined(OV16825_MIPI_RAW)

                   {OV16825MIPI_SENSOR_ID,SENSOR_DRVNAME_OV16825_MIPI_RAW, OV16825MIPISensorInit},

#endif

#if defined(IMX135_MIPI_RAW)

                   {IMX135_SENSOR_ID,SENSOR_DRVNAME_IMX135_MIPI_RAW, IMX135_MIPI_RAW_SensorInit},

#endif

#if defined(SP2508_RAW)

   {SP2508_SENSOR_ID, SENSOR_DRVNAME_SP2508_RAW, SP2508_RAW_SensorInit},

#endif

……

*/

    {

       PK_ERR("ERROR:kdGetSensorInitFuncList()\n");

       return -EIO;

    }

 

   for ( i = KDIMGSENSOR_INVOKE_DRIVER_0; 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; }

 

 

                   //ToDo:remove print information

                   PK_XLOG_INFO("[kdSetDriver]i,g_invokeSocketIdx[%d] = %d :\n",i ,drvIdx[i]);

                   PK_XLOG_INFO("[kdSetDriver]i,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]);

/*

对应到具体的驱动了,具体的驱动一般是CAMERA的厂家直接提供的,如果有疑问可以直接打电话给FAE,如果没有支持,估计调试起来比较麻烦。

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\sp2508_raw\sp2508raw_Sensor.c

*/

           if (NULL == g_pInvokeSensorFunc[i]) {

                PK_ERR("ERROR:NULLg_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_XLOG_INFO("[kdSetDriver]:[%d][%d][%d][%s][%d]\n",i,g_bEnableDriver[i],g_invokeSocketIdx[i],g_invokeSensorNameStr[i],sizeof(pSensorList[drvIdx[i]].drvname));

       }

    }

   return 0;

}

 

 

Step 10-1-2:

 

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\sp2508_raw\sp2508raw_Sensor.c

UINT32SP2508_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc)

{

   /* To Do : Check Sensor status here */

   if (pfFunc!=NULL)

       *pfFunc=&sensor_func;

   return ERROR_NONE;

}  /* SP2508_MIPI_RAW_SensorInit  */

 

/*

这里只是检测kd_sensorlist.h里面是否有定义该驱动,如果有,需要获取该驱动的名字,比如:SENSOR_DRVNAME_SP2508_RAW

kd_sensorlist.h定义驱动ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT结构体:

typedef struct {

         MUINT32 SensorId;

         MUINT8 drvname[32];

         MUINT32(*SensorInit)(PSENSOR_FUNCTION_STRUCT*pfFunc);

}ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT, *PACDK_KD_SENSOR_INIT_FUNCTION_STRUCT;

*/

 

下面在看看另外一个命令:KDIMGSENSORIOC_T_CHECK_IS_ALIVE

 

Step 10-2-1:

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\kd_sensorlist.c

       case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:

           i4RetValue = adopt_CAMERA_HW_CheckIsAlive();

           break;

 

step 10-2-2:

 

inline static int adopt_CAMERA_HW_CheckIsAlive(void)

{

   UINT32 err = 0;

   UINT32 err1 = 0;

         UINT32i = 0;

   MUINT32 sensorID = 0;

   MUINT32 retLen = 0;

 

 

   KD_IMGSENSOR_PROFILE_INIT();

   //power on sensor

kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM*)g_invokeSocketIdx,g_invokeSensorNameStr,true, CAMERA_HW_DRVNAME1);

/*

kdModulePowerOn是给具体的驱动上电,就是g_invokeSocketIdx指定的这颗,g_invokeSocketIdx在上面的kdSetDriver中赋值给它的。

点进入后,调用的就是\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\camera_hw\ kd_camera_hw.c中的kdCISModulePowerOn,具体过程不展开。就是通过系统提供的一些接口,将CAMERACAMIO,AVDD,reset等通过GPIO或者是VGP等拉高上电,具体的上电时序需要参数sensor的上电时序来进行。

 

 

int kdCISModulePowerOn(CAMERA_DUAL_CAMERA_SENSOR_ENUMSensorIdx, char *currSensorName, bool On,

                          char *mode_name)

{

 

         u32pinSetIdx = 0;

 

#define IDX_PS_CMRST 0

#define IDX_PS_CMPDN 4

#define IDX_PS_MODE 1

#define IDX_PS_ON  2

#define IDX_PS_OFF 3

 

#define VOL_2800 2800000

#define VOL_1800 1800000

#define VOL_1500 1500000

#define VOL_1200 1200000

#define VOL_1000 1000000

 

         u32pinSet[3][8] = {

 

                   {CAMERA_CMRST_PIN,

                    CAMERA_CMRST_PIN_M_GPIO, /* mode */

                    GPIO_OUT_ONE,   /*ON state */

                    GPIO_OUT_ZERO, /*OFF state */

                    CAMERA_CMPDN_PIN,

                    CAMERA_CMPDN_PIN_M_GPIO,

                    GPIO_OUT_ZERO, //GPIO_OUT_ONE,

                    GPIO_OUT_ONE, //GPIO_OUT_ZERO,

                    },

                   {CAMERA_CMRST1_PIN,

                    CAMERA_CMRST1_PIN_M_GPIO,

                    GPIO_OUT_ONE,

                    GPIO_OUT_ZERO,

                    CAMERA_CMPDN1_PIN,

                    CAMERA_CMPDN1_PIN_M_GPIO,

                    GPIO_OUT_ZERO, //GPIO_OUT_ONE,

                    GPIO_OUT_ONE, //GPIO_OUT_ZERO,

                    },

                   {GPIO_CAMERA_INVALID,

                    GPIO_CAMERA_INVALID,     /* mode */

                    GPIO_OUT_ONE,   /*ON state */

                    GPIO_OUT_ZERO, /*OFF state */

                    GPIO_CAMERA_INVALID,

                    GPIO_CAMERA_INVALID,

                    GPIO_OUT_ONE,

                    GPIO_OUT_ZERO,

                    }

         };

 

 

 

         if(DUAL_CAMERA_MAIN_SENSOR == SensorIdx)

                   pinSetIdx= 0;

          else if (DUAL_CAMERA_SUB_SENSOR == SensorIdx)

                   pinSetIdx= 1;

          else if (DUAL_CAMERA_MAIN_2_SENSOR ==SensorIdx)

                   pinSetIdx= 2;

 

         if (On) {

 

                   ISP_MCLK1_EN(1);

*/

   //wait for power stable

   mDELAY(10);

   KD_IMGSENSOR_PROFILE("kdModulePowerOn");

 

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

/*

g_pSensorFunckd_MultiSensorFunc的指针,所以我们下面直接看kd_MultiSensorFunc就好了。

staticMULTI_SENSOR_FUNCTION_STRUCT *g_pSensorFunc = &kd_MultiSensorFunc;

参数SENSOR_FEATURE_CHECK_SENSOR_ID就是去获取SENSORID,具体后面看如何获取的。

*/

                           if (sensorID == 0) {    //not implement this feature ID

                               PK_DBG(" Not implement!!, useold open function to check\n");

                               err = ERROR_SENSOR_CONNECT_FAIL;

                           }

                           else if (sensorID == 0xFFFFFFFF) {    //fail to open the sensor

                               PK_DBG(" No SensorFound");

                               err = ERROR_SENSOR_CONNECT_FAIL;

                           }

                           else {

 

                               PK_DBG(" Sensor found ID =0x%x\n", sensorID);

                               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");

 

   return err?-EIO:err;

}        /*adopt_CAMERA_HW_Open() */

 

Step 10-2-3:

 

MULTI_SENSOR_FUNCTION_STRUCT  kd_MultiSensorFunc =

{

   kd_MultiSensorOpen,

   kd_MultiSensorGetInfo,

   kd_MultiSensorGetResolution,

   kd_MultiSensorFeatureControl,

   kd_MultiSensorControl,

   kd_MultiSensorClose

};

 

Step :10-2-4:

 

//

MUINT32

kd_MultiSensorFeatureControl (

CAMERA_DUAL_CAMERA_SENSOR_ENUMInvokeCamera,

MSDK_SENSOR_FEATURE_ENUM FeatureId,

MUINT8 *pFeaturePara,

MUINT32 *pFeatureParaLen)

{

   MUINT32 ret = ERROR_NONE;

   u32 i = 0;

   KD_MULTI_FUNCTION_ENTRY();

   for ( i = KDIMGSENSOR_INVOKE_DRIVER_0 ; i

       if ( g_bEnableDriver[i] && g_pInvokeSensorFunc[i] ) {

 

                            if(InvokeCamera==g_invokeSocketIdx[i]){

 

                     //

                     //set i2c slave ID

                    //KD_SET_I2C_SLAVE_ID(i,g_invokeSocketIdx[i],IMGSENSOR_SET_I2C_ID_STATE);

                     //

                     ret = g_pInvokeSensorFunc[i]->SensorFeatureControl(FeatureId,pFeaturePara,pFeatureParaLen);

/*

g_pInvokeSensorFunc也是在前面一个命令kdSetDriver中获取到的,就是具体的驱动。还是以sp2505为例,这里就是SP2508_RAW_SensorInit

#ifdefined(SP2508_RAW)

    {SP2508_SENSOR_ID,SENSOR_DRVNAME_SP2508_RAW, SP2508_RAW_SensorInit},

#endif

 

staticSENSOR_FUNCTION_STRUCT sensor_func = {

    open,

    get_info,

    get_resolution,

    feature_control,

    control,

    close

};

 

UINT32SP2508_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc)

{

    /* To Do : Check Sensor status here */

    if (pfFunc!=NULL)

        *pfFunc=&sensor_func;

    return ERROR_NONE;

}   /* SP2508_MIPI_RAW_SensorInit  */

 

*/

                     if ( ERROR_NONE != ret ) {

                         PK_ERR("[%s]\n",__FUNCTION__);

                         return ret;

                     }

                            }

       }

    }

   KD_MULTI_FUNCTION_EXIT();

   return ERROR_NONE;

}

 

Step 10-2-5:

\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt8127\sp2508_raw\sp2508raw_Sensor.c

 

static kal_uint32feature_control(MSDK_SENSOR_FEATURE_ENUM feature_id,

                             UINT8*feature_para,UINT32 *feature_para_len)

{

   UINT16 *feature_return_para_16=(UINT16 *) feature_para;

   UINT16 *feature_data_16=(UINT16 *) feature_para;

   UINT32 *feature_return_para_32=(UINT32 *) feature_para;

   UINT32 *feature_data_32=(UINT32 *) feature_para;

   unsigned long long *feature_data=(unsigned long long *) feature_para;

   unsigned long long *feature_return_para=(unsigned long long *)feature_para;

   

   SENSOR_WINSIZE_INFO_STRUCT *wininfo;   

   MSDK_SENSOR_REG_INFO_STRUCT *sensor_reg_data=(MSDK_SENSOR_REG_INFO_STRUCT*) feature_para;

 

   LOG_INF("feature_id = %d\n", feature_id);

   switch (feature_id) {

       case SENSOR_FEATURE_GET_PERIOD:

           *feature_return_para_16++ = imgsensor.line_length;

           *feature_return_para_16 = imgsensor.frame_length;

           *feature_para_len=4;

           break;

                   caseSENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ:      

                            LOG_INF("feature_Controlimgsensor.pclk = %d,imgsensor.current_fps = %d\n",imgsensor.pclk,imgsensor.current_fps);

                            *feature_return_para_32= imgsensor.pclk;

           *feature_para_len=4;

           break;        

       case SENSOR_FEATURE_SET_ESHUTTER:

           set_shutter(*feature_data);

           break;

       case SENSOR_FEATURE_SET_NIGHTMODE:

           night_mode((BOOL) *feature_data);

           break;

       case SENSOR_FEATURE_SET_GAIN:      

           set_gain((UINT16) *feature_data);

           break;

       case SENSOR_FEATURE_SET_FLASHLIGHT:

           break;

       case SENSOR_FEATURE_SET_ISP_MASTER_CLOCK_FREQ:

           break;

       case SENSOR_FEATURE_SET_REGISTER:

           write_cmos_sensor(sensor_reg_data->RegAddr,sensor_reg_data->RegData);

           break;

       case SENSOR_FEATURE_GET_REGISTER:

           sensor_reg_data->RegData =read_cmos_sensor(sensor_reg_data->RegAddr);

           break;

       case SENSOR_FEATURE_GET_LENS_DRIVER_ID:

           // get the lens driver ID from EEPROM or just returnLENS_DRIVER_ID_DO_NOT_CARE

           // if EEPROM does not exist in camera module.

           *feature_return_para_32=LENS_DRIVER_ID_DO_NOT_CARE;

           *feature_para_len=4;

           break;

       case SENSOR_FEATURE_SET_VIDEO_MODE:

           set_video_mode(*feature_data);

           break;

       caseSENSOR_FEATURE_CHECK_SENSOR_ID:

           get_imgsensor_id(feature_return_para_32);

            break;

       case SENSOR_FEATURE_SET_AUTO_FLICKER_MODE:

           set_auto_flicker_mode((BOOL)*feature_data_16,*(feature_data_16+1));

            break;

       case SENSOR_FEATURE_SET_MAX_FRAME_RATE_BY_SCENARIO:

           set_max_framerate_by_scenario((MSDK_SCENARIO_ID_ENUM)*feature_data,*(feature_data+1));

           break;

       case SENSOR_FEATURE_GET_DEFAULT_FRAME_RATE_BY_SCENARIO:

           //get_default_framerate_by_scenario((MSDK_SCENARIO_ID_ENUM)*feature_data_32,(MUINT32 *)(*(feature_data_32+1)));

           get_default_framerate_by_scenario((MSDK_SCENARIO_ID_ENUM)*(feature_data),(MUINT32 *)(uintptr_t)(*(feature_data+1)));

           break;

       case SENSOR_FEATURE_SET_TEST_PATTERN:

           set_test_pattern_mode((BOOL)*feature_data);

           break;

       case SENSOR_FEATURE_GET_TEST_PATTERN_CHECKSUM_VALUE: //for factory modeauto testing            

           *feature_return_para_32 =imgsensor_info.checksum_value;

           *feature_para_len=4;                            

           break;             

       case SENSOR_FEATURE_SET_FRAMERATE:

           LOG_INF("current fps :%d\n", (UINT32)*feature_data);

           spin_lock(&imgsensor_drv_lock);

           imgsensor.current_fps = *feature_data;

           spin_unlock(&imgsensor_drv_lock);      

           break;

                      case SENSOR_FEATURE_SET_HDR:

                                  LOG_INF("ihdr enable :%d\n",(BOOL)*feature_data);

                                  spin_lock(&imgsensor_drv_lock);

                                  imgsensor.ihdr_en = (BOOL)*feature_data;

                                  spin_unlock(&imgsensor_drv_lock);           

                                  break;

       case SENSOR_FEATURE_GET_CROP_INFO:

           LOG_INF("SENSOR_FEATURE_GET_CROP_INFO scenarioId:%d\n",(UINT32)*feature_data);

           //wininfo = (SENSOR_WINSIZE_INFO_STRUCT *)(*(feature_data_32+1));

           wininfo = (SENSOR_WINSIZE_INFO_STRUCT *)(uintptr_t)(*(feature_data+1));

            switch (*feature_data_32) {

                caseMSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:

                    memcpy((void*)wininfo,(void*)&imgsensor_winsize_info[1],sizeof(SENSOR_WINSIZE_INFO_STRUCT));

                    break;   

                case MSDK_SCENARIO_ID_VIDEO_PREVIEW:

                    memcpy((void*)wininfo,(void*)&imgsensor_winsize_info[2],sizeof(SENSOR_WINSIZE_INFO_STRUCT));

                    break;

                caseMSDK_SCENARIO_ID_HIGH_SPEED_VIDEO:

                    memcpy((void *)wininfo,(void*)&imgsensor_winsize_info[3],sizeof(SENSOR_WINSIZE_INFO_STRUCT));

                    break;

                caseMSDK_SCENARIO_ID_SLIM_VIDEO:

                    memcpy((void*)wininfo,(void *)&imgsensor_winsize_info[4],sizeof(SENSOR_WINSIZE_INFO_STRUCT));

                    break;

                caseMSDK_SCENARIO_ID_CAMERA_PREVIEW:

                default:

                    memcpy((void*)wininfo,(void*)&imgsensor_winsize_info[0],sizeof(SENSOR_WINSIZE_INFO_STRUCT));

                    break;

                            }

                       case SENSOR_FEATURE_SET_IHDR_SHUTTER_GAIN:

                                  LOG_INF("SENSOR_SET_SENSOR_IHDRLE=%d, SE=%d,Gain=%d\n",(UINT16)*feature_data,(UINT16)*(feature_data+1),(UINT16)*(feature_data+2));

                                 ihdr_write_shutter_gain((UINT16)*feature_data,(UINT16)*(feature_data+1),(UINT16)*(feature_data+2));        

                                  break;

                      default:

                            break;

         }

 

   return ERROR_NONE;

}  /*  feature_control()  */

 

 

Step 10-2-6:

 

static kal_uint32 get_imgsensor_id(UINT32*sensor_id)

{

   kal_uint8 i = 0;

   kal_uint8 retry = 2;

   //kal_uint32 p1,p2;

   //sensor have two i2c address 0x6c 0x6d & 0x21 0x20, we shoulddetect the module used i2c address

   while (imgsensor_info.i2c_addr_table[i] != 0xff) {

       spin_lock(&imgsensor_drv_lock);

       imgsensor.i2c_write_id = imgsensor_info.i2c_addr_table[i];

       spin_unlock(&imgsensor_drv_lock);

       do {

           *sensor_id = return_sensor_id();

                                  //*sensor_id = 0x2508;

                                  //p1 = read_cmos_sensor(0x02) << 8;

                                  //p2 = read_cmos_sensor(0x03);

                                  //LOG_INF("preview setting 0x0100 =%d,0x03 = %d\n",p1,p2);

                                 

           if (*sensor_id == imgsensor_info.sensor_id) {              

                LOG_INF("i2c write id:0x%x, sensor id: 0x%x\n", imgsensor.i2c_write_id,*sensor_id);     

                return ERROR_NONE;

           }  

           LOG_INF("Read sensor id fail:0x%x, id: 0x%x\n",imgsensor.i2c_write_id,*sensor_id);

           retry--;

       } while(retry > 0);

       i++;

       retry = 2;

    }

   if (*sensor_id != imgsensor_info.sensor_id) {

       // if Sensor ID is not correct, Must set *sensor_id to 0xFFFFFFFF

       *sensor_id = 0xFFFFFFFF;

       return ERROR_SENSOR_CONNECT_FAIL;

    }

   return ERROR_NONE;

}

 

Step 10-2-7:

 

static kal_uint32 return_sensor_id(void)

   write_cmos_sensor(0xfd, 0x00);

           return ((read_cmos_sensor(0x02)<< 8) | read_cmos_sensor(0x03));

/*

最后通过I2C读取相应寄存器的值,开对比与所定义的ID是否一致,如果是,则表示这颗SENSOR是存在的,后面系统会初始化相关的资源给它,如果fail,就认为这个sensor不存在。可能是真的不存在,也可能是硬件或者软件的定义有问题,驱动里面主要debug的就是这个东西。

*/

}

 

到这里开机的过程基本分析完了,总结下,开机主要启动的cameraservice,还有就是确定定义的sensor是否真实存在。存在就分配相关资源。具体的自己分配,数据流向待学习。

你可能感兴趣的:(CAMERA学习)