下面分析下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,并且获取SENSOR的INFO。
*/
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
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
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();
/*
第一次进来mi4DeviceNum为0,进入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();
//所以也就是SensorHalImp的searchSensor
//
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
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->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
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层与KERNEL的IOCRL下面继续看一下: 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_DRIVER和KDIMGSENSORIOC_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,具体过程不展开。就是通过系统提供的一些接口,将CAMERA的CAMIO,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_pSensorFunc为kd_MultiSensorFunc的指针,所以我们下面直接看kd_MultiSensorFunc就好了。 staticMULTI_SENSOR_FUNCTION_STRUCT *g_pSensorFunc = &kd_MultiSensorFunc; 参数SENSOR_FEATURE_CHECK_SENSOR_ID就是去获取SENSOR的ID,具体后面看如何获取的。 */ 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是否真实存在。存在就分配相关资源。具体的自己分配,数据流向待学习。