Android Q 之MTK代码分析(一)--Camera Hal3 Service:https://blog.csdn.net/weixin_38328785/article/details/106720202
https://www.cnblogs.com/reality-soul/p/4668532.html
《Android Q 之MTK代码分析(一)--Camera Hal3 Service》
《Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor》
备忘:
文末支持一波,感谢鞠躬
0、前文回顾
前文简单了解下CameraService、CameraHalService、CameraProvider服务(加载其rc文件,注册在CameraHalService服务上)的启动。《interface》 IVirtualDevice,给camera service暴露接口去操作camera,给Camera Device Manager 暴露接口去交互。在这之后会立即启动searchSesnor流程
(1)、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp
Camerahalservice服务main函数,通过registerPassthroughServiceImplementation来注册CameraProvider,之后可以通过getservice()来获取CameraProvider实例对象
int main()
{
ALOGI("Camera HAL Server is starting..., ADV_CAM_SUPPORT(%d)", MTKCAM_ADV_CAM_SUPPORT);signal(SIGPIPE, SIG_IGN);
// The camera HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
configureRpcThreadpool(16, true /*callerWillJoin*/);// AOSP ICameraProvider HAL Interface
{
using android::hardware::camera::provider::V2_4::ICameraProvider;
registerPassthroughServiceImplementation<ICameraProvider>("internal/0" /*"internal" for binderized mode*/);
}
//
// MTK IAdvCamControl HAL Interface
{
#if MTKCAM_ADV_CAM_SUPPORT
using vendor::mediatek::hardware::camera::advcam::V1_0::IAdvCamControl;
registerPassthroughServiceImplementation<IAdvCamControl>("internal/0" /*"internal" for binderized mode*/);
#endif
}{
#if MTKCAM_LOMO_SUPPORT
using vendor::mediatek::hardware::camera::lomoeffect::V1_0::ILomoEffect;
registerPassthroughServiceImplementation<ILomoEffect>("internal/0" /*"internal" for binderized mode*/);
#endif
}{
using vendor::mediatek::hardware::camera::ccap::V1_0::ICCAPControl;
registerPassthroughServiceImplementation<ICCAPControl>("internal/0" /*"internal" for binderized mode*/);
}{
#if MTKCAM_MMSDK_SUPPORT
using vendor::mediatek::hardware::camera::callbackclient::V1_1::IMtkCallbackClient;
registerPassthroughServiceImplementation<IMtkCallbackClient>("internal/0" /*"internal" for binderized mode*/);
#endif
}{
using ::vendor::mediatek::hardware::camera::frhandler::V1_0::IFRHandler;
registerPassthroughServiceImplementation<IFRHandler>("internal/0" /*"internal" for binderized mode*/);
}joinRpcThreadpool();
return 0;
}
(2)、getService(name)获得provider实例,然后registerAsService(name),最后registerServiceCb(service,name)注册provider服务回调函数,以便后面调用。
system/libhidl/transport/include/hidl/LegacySupport.h
namespace android {
namespace hardware {
namespace details {
template <class Interface, typename Func>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
Func registerServiceCb, const std::string& name = "default") {
sp<Interface> service = Interface::getService(name, true /* getStub */); //CameraProvider 实例化对象if (service == nullptr) {
ALOGE("Could not get passthrough implementation for %s/%s.",
Interface::descriptor, name.c_str());
return EXIT_FAILURE;
}LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
Interface::descriptor, name.c_str());status_t status = registerServiceCb(service, name);
if (status == OK) {
ALOGI("Registration complete for %s/%s.",
Interface::descriptor, name.c_str());
} else {
ALOGE("Could not register service %s/%s (%d).",
Interface::descriptor, name.c_str(), status);
}return status;
}
} // namespace details/**
* Registers passthrough service implementation.
*/template <class Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
const std::string& name = "default") {
return details::registerPassthroughServiceImplementation<Interface>(
[](const sp<Interface>& service, const std::string& name) {
return service->registerAsService(name); //将 CameraProvider 注册为一个服务,
其他进程需要使用 camera 的 hal 层时通过 binder 得到 CameraProvider 代理类即可操作camera hal 层
},
name);
}......
} // namespace hardware
} // namespace android
frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService( const std::string &serviceName) = 0;
system/libhidl/transport/include/hidl/HidlTransportSupport.h
namespace android {
namespace hardware {......
namespace details {
template <typename BpType, typename IType = typename BpType::Pure,
typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
if (base == nullptr) {
return nullptr;
}if (base->isRemote()) {
// getRawServiceInternal guarantees we get the proper class
return sp<IType>(new BpType(getOrCreateCachedBinder(base.get())));
}return IType::castFrom(base);
}} // namespace details
} // namespace hardware
} // namespace android
(3)、获取PassthroughServiceManager对象pm,pm->get()获取ICameraProvider实例
system/libhidl/transport/ServiceManagement.cpp
namespace android {
namespace hardware {struct PassthroughServiceManager : IServiceManager1_1 {
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
//fqName looks like [email protected]::IFoo
size_t idx = fqName.find("::");if (idx == std::string::npos ||
idx + strlen("::") + 1 >= fqName.size()) {
LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
return;
}std::string packageAndVersion = fqName.substr(0, idx);
std::string ifaceName = fqName.substr(idx + strlen("::"));const std::string prefix = packageAndVersion + "-impl";
const std::string sym = "HIDL_FETCH_" + ifaceName;......
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
IBase* (*generator)(const char* name);
*(void **)(&generator) = dlsym(handle, sym.c_str());
if(!generator) {
const char* error = dlerror();
LOG(ERROR) << "Passthrough lookup opened " << lib
<< " but could not find symbol " << sym << ": "
<< (error == nullptr ? "unknown error" : error);
dlclose(handle);
return true;
}ret = (*generator)(name.c_str());
if (ret == nullptr) {
dlclose(handle);
return true; // this module doesn't provide this instance name
}// Actual fqname might be a subclass.
// This assumption is tested in vts_treble_vintf_test
using ::android::hardware::details::getDescriptor;
std::string actualFqName = getDescriptor(ret.get());
CHECK(actualFqName.size() > 0);
registerReference(actualFqName, name);
return false;
});return ret;
}}
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}namespace details {
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
using ::android::hidl::manager::V1_0::IServiceManager;
sp<Waiter> waiter;sp<IServiceManager1_1> sm;
Transport transport = Transport::EMPTY;
if (kIsRecovery) {
transport = Transport::PASSTHROUGH;
} else {
sm = defaultServiceManager1_1();
if (sm == nullptr) {
ALOGE("getService: defaultServiceManager() is null");
return nullptr;
}Return<Transport> transportRet = sm->getTransport(descriptor, instance);
if (!transportRet.isOk()) {
ALOGE("getService: defaultServiceManager()->getTransport returns %s",
transportRet.description().c_str());
return nullptr;
}
transport = transportRet;
}const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);#ifdef ENFORCE_VINTF_MANIFEST
#ifdef LIBHIDL_TARGET_DEBUGGABLE
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
#else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
const bool trebleTestingOverride = false;
const bool vintfLegacy = false;
#endif // LIBHIDL_TARGET_DEBUGGABLE#else // not ENFORCE_VINTF_MANIFEST
const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
const bool trebleTestingOverride = env && !strcmp(env, "true");
const bool vintfLegacy = (transport == Transport::EMPTY);
#endif // ENFORCE_VINTF_MANIFESTfor (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
if (waiter == nullptr && tries > 0) {
waiter = new Waiter(descriptor, instance, sm);
}
if (waiter != nullptr) {
waiter->reset(); // don't reorder this -- see comments on reset()
}
Return<sp<IBase>> ret = sm->get(descriptor, instance);
if (!ret.isOk()) {
ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
ret.description().c_str(), descriptor.c_str(), instance.c_str());
break;
}
sp<IBase> base = ret;
if (base != nullptr) {
Return<bool> canCastRet =
details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);if (canCastRet.isOk() && canCastRet) {
if (waiter != nullptr) {
waiter->done();
}
return base; // still needs to be wrapped by Bp class.
}if (!handleCastError(canCastRet, descriptor, instance)) break;
}// In case of legacy or we were not asked to retry, don't.
if (vintfLegacy || !retry) break;if (waiter != nullptr) {
ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
waiter->wait(true /* timeout */);
}
}if (waiter != nullptr) {
waiter->done();
}if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); //获取ICameraProvider实例
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}return nullptr;
}} // namespace details
} // namespace hardware
} // namespace android
(4)、HIDL_FETCH_ICameraProvider为AOSP所定义的接口
(5)、创建CameraDeviceManager对象
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/instance.cpp
extern "C"
NSCam::ICameraDeviceManager*
getCameraDeviceManager()
{
static NSCam::CameraDeviceManagerImpl singleton(getProviderType().c_str());
static bool init = singleton.initialize();
if ( ! init ) {
MY_LOGE("CameraDeviceManagerImpl::initialize fail %p", &singleton);
return nullptr;
}
return &singleton;
}
(6)、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp
auto
CameraDeviceManagerBase::
initialize() -> bool
{
CAM_TRACE_NAME(LOG_TAG ":initialize");// global vendor tags should be setup before enumerating devices...
auto pVendorTagDesc = NSCam::getVendorTagDescriptor();
if ( ! pVendorTagDesc ) {
MY_LOGE("bad pVendorTagDesc");
return false;
}// loading libraries in charge of creating devices.
auto loadDeviceFactory = [](char const* libname, char const* symbol) {
VirtEnumDeviceFactory item;
item.mLibHandle = ::dlopen(libname, RTLD_NOW);
if (item.mLibHandle == nullptr) {
char const *err_str = ::dlerror();
CAM_ULOGME("[loadDeviceFactory] dlopen: %s error=%s", libname, (err_str ? err_str : "unknown"));
return item;
}
*(void **)(&item.mCreateVirtualCameraDevice) = ::dlsym(item.mLibHandle, symbol);
if ( item.mCreateVirtualCameraDevice == nullptr ) {
char const *err_str = ::dlerror();
CAM_ULOGME("[loadDeviceFactory] dlsym: %s error=%s", symbol, (err_str ? err_str : "unknown"));
::dlclose(item.mLibHandle);
item.mLibHandle = nullptr;
return item;
}
return item;
};
mVirtEnumDeviceFactoryMap[3] = loadDeviceFactory("libmtkcam_device3.so", "createVirtualCameraDevice");// enumerating devices...
status_t status = OK;
MY_LOGI("+");
RWLock::AutoWLock _l(mDataRWLock);
{
status = enumerateDevicesLocked(); //从这块开始枚举相机设备
}
MY_LOGI("-");
return (OK==status);
}
7、创建CameraProvider对象
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/instance.cpp
extern "C"
ICameraProvider*
HIDL_FETCH_ICameraProvider(const char* name)
{
// name must be either "internal/<id>" or "legacy/<id>".
std::string const strProviderName(name);
size_t const pos = strProviderName.find('/');
if ( 0 == pos || std::string::npos == pos ) {
MY_LOGE("provider name (%s) with bad \'/\' at position %zu", name, pos);
return nullptr;
}
//
if ( 0 != strProviderName.compare(0, pos, getProviderType()) ) {
MY_LOGW("provider name (%s) with mismatched type(%s) and \'/\' at position %zu",
name, getProviderType().c_str(), pos);
return nullptr;
}
//
return createICameraProvider_V2_4(name, getCameraDeviceManager());
}
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/provider/2.4/CameraProviderImpl.cpp
extern "C"
ICameraProvider*
createICameraProvider_V2_4(const char* providerName, NSCam::ICameraDeviceManager* manager)
{
MY_LOGI("+ %s", providerName);
//
if ( ! manager ) {
MY_LOGE("bad camera device manager");
return nullptr;
}
//
auto provider = new CameraProviderImpl(providerName, manager); //创建cameraprovider对象
if ( ! provider ) {
MY_LOGE("cannot allocate camera provider %s", providerName);
return nullptr;
}
//
if ( ! provider->initialize() ) {
MY_LOGE("camera provider %s initialize failed", providerName);
delete provider;
provider = nullptr;
}
//
MY_LOGI("- %s provider:%p manager:%p", providerName, provider, manager);
return provider;
}
1、camera 架构分析
Camera的框架分为Kernel部分和hal部分,其中kernel部分主要有两块:
image sensor driver,负责具体型号的sensor的id检测,上电,以及在preview、capture、初始化、3A等等功能设定时的寄存器配置;
isp driver,通过DMA将sensor数据流上传;
HAL层部分主要有三部分组成:
imageio,主要负责数据buffer上传的pipe;
drv,包含imgsensor和isp的hal层控制;
feature io,包含各种3A等性能配置;
2、Search Sensor
下图有search sensor的流程
(1)、开始SearchSensor
(2)、创建IMetadataProvider对象
(3)、创建VirtualCameraDevice对象
(4)、创建CameraDevice3实例
(5)、创建CameraDevice3Session实例
(6)、添加Virtual 设备 表和物理设备表
和上面前文回顾中第六个接上继续分析,
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/CameraDeviceManagerBase.cpp
auto
CameraDeviceManagerBase::
initialize() -> bool
{
CAM_TRACE_NAME(LOG_TAG ":initialize");// global vendor tags should be setup before enumerating devices...
auto pVendorTagDesc = NSCam::getVendorTagDescriptor();
if ( ! pVendorTagDesc ) {
MY_LOGE("bad pVendorTagDesc");
return false;
}// loading libraries in charge of creating devices.
auto loadDeviceFactory = [](char const* libname, char const* symbol) {
VirtEnumDeviceFactory item;
item.mLibHandle = ::dlopen(libname, RTLD_NOW);
if (item.mLibHandle == nullptr) {
char const *err_str = ::dlerror();
CAM_LOGE("[loadDeviceFactory] dlopen: %s error=%s", libname, (err_str ? err_str : "unknown"));
return item;
}
*(void **)(&item.mCreateVirtualCameraDevice) = ::dlsym(item.mLibHandle, symbol);
if ( item.mCreateVirtualCameraDevice == nullptr ) {
char const *err_str = ::dlerror();
CAM_LOGE("[loadDeviceFactory] dlsym: %s error=%s", symbol, (err_str ? err_str : "unknown"));
::dlclose(item.mLibHandle);
item.mLibHandle = nullptr;
return item;
}
return item;
};
mVirtEnumDeviceFactoryMap[1] = loadDeviceFactory("libmtkcam_device1.so", "createVirtualCameraDevice");
mVirtEnumDeviceFactoryMap[3] = loadDeviceFactory("libmtkcam_device3.so", "createVirtualCameraDevice");// enumerating devices...
status_t status = OK;
MY_LOGI("+");
RWLock::AutoWLock _l(mDataRWLock);
{
status = enumerateDevicesLocked();
}
MY_LOGI("-");
return (OK==status);
}
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/depend/CameraDeviceManagerImpl.cpp
/******************************************************************************
*
* Invoked by CamDeviceManagerBase::enumerateDevicesLocked()
*
******************************************************************************/
auto
CameraDeviceManagerImpl::
onEnumerateDevicesLocked() -> ::android::status_t
{
NSMetadataProviderManager::clear();
mPhysEnumDeviceMap.clear();
//--------------------------------------------------------------------------
#if '1'==MTKCAM_HAVE_SENSOR_HAL
//IHalSensorList*const pHalSensorList = MAKE_HalSensorList();
//size_t const sensorNum = pHalSensorList->searchSensors();
///
IHalLogicalDeviceList* pHalDeviceList;
pHalDeviceList = MAKE_HalLogicalDeviceList();//IHalLogicalDeviceList::get();
size_t const deviceNum = pHalDeviceList->searchDevices(); //(1)查找匹配的Devices
///
CAM_LOGI("pHalDeviceList:%p logicDeviceCount:%zu physicSensorCount:%d",
pHalDeviceList,
deviceNum,
pHalDeviceList->queryNumberOfSensors());mVirtEnumDeviceMap.setCapacity(deviceNum*2);
for (size_t instanceId = 0; instanceId < deviceNum; instanceId++)
{
//
sp<IMetadataProvider> pMetadataProvider;
pMetadataProvider = IMetadataProvider::create(instanceId); //(2) new IMetadataProvider
NSMetadataProviderManager::add(instanceId, pMetadataProvider.get());
MY_LOGD("[0x%02zx] IMetadataProvider:%p sensor:%s", instanceId, pMetadataProvider.get(), pHalDeviceList->queryDriverName(instanceId));
addVirtualDevicesLocked(instanceId, pMetadataProvider);
}size_t const sensorNum = pHalDeviceList->queryNumberOfSensors();
IHalSensorList*const pHalSensorList = MAKE_HalSensorList();
mPhysEnumDeviceMap.setCapacity(sensorNum);
for (size_t sensorId = 0; sensorId < sensorNum; sensorId++)
{
sp<PhysEnumDevice> pPhysDevice = new PhysEnumDevice;
sp<IMetadataProvider> pMetadataProvider = NSMetadataProviderManager::valueFor(sensorId);
pPhysDevice->mMetadataProvider = pMetadataProvider;
pPhysDevice->mSensorName = pHalSensorList->queryDriverName(sensorId);
pPhysDevice->mInstanceId = sensorId;
pPhysDevice->mFacing = pMetadataProvider->getDeviceFacing();
pPhysDevice->mWantedOrientation = pMetadataProvider->getDeviceWantedOrientation();
pPhysDevice->mSetupOrientation = pMetadataProvider->getDeviceSetupOrientation();
pPhysDevice->mHasFlashUnit = pMetadataProvider->getDeviceHasFlashLight();mPhysEnumDeviceMap.add(sensorId, pPhysDevice);
}
#endif //#if '1'==MTKCAM_HAVE_SENSOR_HAL
//--------------------------------------------------------------------------
//
return OK;
}
vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/LogicalCam/IHalLogicalDeviceList.h
#define MAKE_HalLogicalDeviceList(...) \ MAKE_MTKCAM_MODULE(MTKCAM_MODULE_ID_UTILS_LOGICALDEV, HalLogicalDeviceList_FACTORY_T, __VA_ARGS__)
CameraDeviceManagerImpl.cpp文件中函数pHalDeviceList->searchDevices()将调用HalLogicalDeviceList.cpp文件中HalLogicalDeviceList::searchDevices()函数,该函数再调用的HalLogicalDeviceList::createDeviceMap函数。在createDeviceMap里面有serachSensors的操作
vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/HalLogicalDeviceList.cpp
MINT32
HalLogicalDeviceList::
createDeviceMap()
{
SensorInfo_t vTempInfo;
unsigned int i = 0;// firstly, we create a logical camera device per physical camera
IHalSensorList* const pHalSensorList = MAKE_HalSensorList(); //(1)创建sensor对象
if(CC_UNLIKELY(!pHalSensorList))
{
MY_LOGA("create pHalSensorList fail");
}
size_t const sensorNum = pHalSensorList->searchSensors(); //(2)此函数入口,主要查找匹配的硬件sensor
MY_LOGD("sensorNum : %zu", sensorNum);
#ifdef VENDOR_CAM_ID_FIX
// create virtual device ids map
mpVirtualDeviceIdsMapHelper = new VirtualDeviceIdsMapHelper();
mpVirtualDeviceIdsMapHelper->HQPatch_CameraInfo_setprop();#endif
for(i = 0; i < sensorNum; i++)
{
SensorStaticInfo sensorStaticInfo;
memset(&sensorStaticInfo, 0, sizeof(SensorStaticInfo));
int sendorDevIndex = pHalSensorList->querySensorDevIdx(i);
pHalSensorList->querySensorStaticInfo(sendorDevIndex, &sensorStaticInfo);TempSensorInfo TempInfo;
TempInfo.SensorId = i;
TempInfo.RawType = sensorStaticInfo.rawFmtType;
TempInfo.Facing = sensorStaticInfo.facingDirection;
TempInfo.CaptureModeWidth = sensorStaticInfo.captureWidth;
TempInfo.Name = pHalSensorList->queryDriverName(i);uint32_t remappingSensorId;
if(getVidByDrvName(TempInfo.Name, i, remappingSensorId))
{
TempInfo.RemappingSensorId = (MINT32)remappingSensorId;
}
else
{
TempInfo.RemappingSensorId = i;
}
vTempInfo.push_back(TempInfo);
MY_LOGD("i : %d, facing : %d", i, sensorStaticInfo.facingDirection);sp<CamDeviceInfo> Info = new CamDeviceInfo();
Info->Sensors.push_back(i);
Info->RemappingSensorId.push_back(TempInfo.RemappingSensorId);
Info->DualFeature = 0;
Info->RawType = TempInfo.RawType;
Info->Name = TempInfo.Name;
// add physical sensor static metadata
Info->sensorStaticMetadata = MAKE_HalSensorList()->queryStaticInfo(Info->Sensors[0]);
MY_LOGD("i : %d, remapping: %d, Info Name : %s", i, Info->RemappingSensorId[0], Info->Name.c_str());mDeviceSensorMap.add(i, Info); //把找到的Device Map
}// then we also create logical camera device(s) from the custom file:
// camera_custom_stereo_setting.h if available
{
std::vector<struct LogicalSensorStruct> CustomDevList =
LogicalCamJSONUtil::getLogicalDevices();
MY_LOGD("manual device count = %zu", CustomDevList.size());
for (auto&& logicalDevice : CustomDevList)
{
for (int j = 0; j < logicalDevice.NumofDefinition; j++)
{
addLogicalDevice(vTempInfo, &logicalDevice, j);
}
}
}dumpDebugInfo();
return 0;
}
函数 pHalSensorList->searchSensors()将调用HalSensorList:: enumerateSensor_Locked()函数,该函数再调用ImgSensor_drv.cpp文件中的 pSensorDrv->searchSensor函数。
typedef NSCam::IHalSensorList* (*HalSensorList_FACTORY_T)(); #define MAKE_HalSensorList(...) \ MAKE_MTKCAM_MODULE(MTKCAM_MODULE_ID_DRV_HAL_SENSORLIST, HalSensorList_FACTORY_T, __VA_ARGS__)
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp
MUINT
HalSensorList::
enumerateSensor_Locked()
{
int ret = 0;
NSFeature::SensorInfoBase* pSensorInfo ;SensorDrv *const pSensorDrv = SensorDrv::get();
SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance();
if(!pSeninfDrv) {
MY_LOGE("pSeninfDrv == NULL");
return 0;
}if((ret = pSeninfDrv->init()) < 0) {
MY_LOGE("pSeninfDrv->init() fail");
return 0;
}/*search sensor using 8mA driving current*/
pSeninfDrv->setAllMclkOnOff(ISP_DRIVING_8MA, TRUE);pSensorDrv->init();
MUINT max_index_of_camera = IMGSENSOR_SENSOR_IDX_SUB;
#ifdef MTK_CAM_MAX_NUMBER_OF_CAMERA
max_index_of_camera = MTK_CAM_MAX_NUMBER_OF_CAMERA - 1;
#endifMY_LOGD("impSearchSensor search to %d\n", max_index_of_camera);
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= max_index_of_camera; i++) {
if((ret = pSensorDrv->searchSensor((IMGSENSOR_SENSOR_IDX)i)) == SENSOR_NO_ERROR) {
//query sensorinfo
querySensorDrvInfo((IMGSENSOR_SENSOR_IDX)i);
//fill in metadata
buildSensorMetadata((IMGSENSOR_SENSOR_IDX)i);pSensorInfo = pSensorDrv->getSensorInfo((IMGSENSOR_SENSOR_IDX)i);
addAndInitSensorEnumInfo_Locked(
(IMGSENSOR_SENSOR_IDX)i,
mapToSensorType(pSensorInfo->GetType()),
pSensorInfo->getDrvMacroName());
}
}pSeninfDrv->setAllMclkOnOff(0, FALSE);
ret = pSeninfDrv->uninit();
if(ret < 0) {
MY_LOGE("pSeninfDrv->uninit() fail");
return 0;
}
pSeninfDrv->destroyInstance();
pSensorDrv->uninit();return mEnumSensorList.size();
}
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/imgsensor_drv.cpp
MINT32
ImgSensorDrv::searchSensor(IMGSENSOR_SENSOR_IDX sensorIdx)
{
MSDK_SENSOR_INIT_FUNCTION_STRUCT *pSensorInitFunc;//! If imp sensor search process already done before,
//! only need to return the sensorDevs, not need to
//! search again.
if (m_sensorIdx[sensorIdx] != BAD_SENSOR_INDEX) {
//been processed.
LOG_MSG("[searchSensor] Already processed");return SENSOR_ALREADY_SEARCH;
}GetSensorInitFuncList(&pSensorInitFunc); //--(1)获得Hal层的sensor列表
LOG_MSG("SENSOR search start");
//set sensor driver
MUINT32 featureParaLen = sizeof(MUINT32);
MINT32 idx = 0;featureControl(sensorIdx, SENSOR_FEATURE_SET_DRIVER, (MUINT8 *)&idx, &featureParaLen); //-- (2)调用kernel层的kdSetDriver函数
LOG_MSG("set sensor driver id =%x", idx);if((m_sensorIdx[sensorIdx] = (idx < 0) ? UNKNOWN_SENSOR_INDEX : idx) >= UNKNOWN_SENSOR_INDEX)
return SENSOR_INVALID_DRIVER;NSFeature::SensorInfoBase* pSensorInfo = pSensorInitFunc[idx].pSensorInfo;
if (pSensorInfo)
LOG_MSG("sensorIdx %d found <%#x/%s/%s>", sensorIdx, pSensorInfo->GetID(), pSensorInfo->getDrvName(), pSensorInfo->getDrvMacroName());
else
LOG_ERR("m_pSensorInfo[%d] = NULL check if sensor list sync with kernel & user", sensorIdx);return SENSOR_NO_ERROR;
}
MINT32
ImgSensorDrv::featureControl(
IMGSENSOR_SENSOR_IDX sensorIdx,
ACDK_SENSOR_FEATURE_ENUM FeatureId,
MUINT8 *pFeaturePara,
MUINT32 *pFeatureParaLen
)
{
ACDK_SENSOR_FEATURECONTROL_STRUCT featureCtrl;if (m_fdSensor == -1) {
LOG_ERR("[sendCommand]m_fdSensor fail, sendCommand must be called after init()!");
return SENSOR_UNKNOWN_ERROR;
}if (pFeaturePara == NULL || pFeatureParaLen == NULL) {
return SENSOR_INVALID_PARA;
}featureCtrl.InvokeCamera = sensorIdx;
featureCtrl.FeatureId = FeatureId;
featureCtrl.pFeaturePara = pFeaturePara;
featureCtrl.pFeatureParaLen = pFeatureParaLen;if (ioctl(m_fdSensor, KDIMGSENSORIOC_X_FEATURECONCTROL , &featureCtrl) < 0) { //这块会调用imgsensor.c中的adopt_CAMERA_HW_FeatureControl,调用imgsensor_sensor_open(psensor),会在获取get_sensor_id之前把sensor给open起来
LOG_ERR("[featureControl] Err-ctrlCode (%s)", strerror(errno));
return -errno;
}return SENSOR_NO_ERROR;
}//halSensorFeatureControl
--(1)、获取hal层sensor列表GetSensorInitFuncList(&pSensorInitFunc);
vendor/mediatek/proprietary/custom/mt6768/hal/imgsensor_src/sensorlist.cpp
UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
if (NULL == ppSensorList) {
ALOGE("ERROR: NULL pSensorList\n");
return MHAL_UNKNOWN_ERROR;
}
*ppSensorList = &SensorList[0]; //这里直接调用hal层的sensor列表
return MHAL_NO_ERROR;
} // GetSensorInitFuncList()
MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =
{
/*IMX*/
.../*OV (OmniVision)*/
#if defined(OV16880_MIPI_RAW)
RAW_INFO(OV16880_SENSOR_ID, SENSOR_DRVNAME_OV16880_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(OV16825_MIPI_RAW)
RAW_INFO(OV16825MIPI_SENSOR_ID, SENSOR_DRVNAME_OV16825_MIPI_RAW, NULL),
#endif
#ifdef FACTORY_MODE_ENABLE
#if defined(OV13B10_MIPI_RAW)
RAW_INFO(OV13B10_SENSOR_ID, SENSOR_DRVNAME_OV13B10_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#if defined(OV13B10_SUNNY_MIPI_RAW)
RAW_INFO(OV13B10_SUNNY_SENSOR_ID, SENSOR_DRVNAME_OV13B10_SUNNY_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#else
#if defined(OV13B10_MIPI_RAW)
RAW_INFO(OV13B10_SENSOR_ID, SENSOR_DRVNAME_OV13B10_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(OV13B10_SUNNY_MIPI_RAW)
RAW_INFO(OV13B10_SUNNY_SENSOR_ID, SENSOR_DRVNAME_OV13B10_SUNNY_MIPI_RAW, CAM_CALGetCalData),
#endif
#endif
#if defined(OV13B10_OFILM_MIPI_RAW)
RAW_INFO(OV13B10_OFILM_SENSOR_ID, SENSOR_DRVNAME_OV13B10_OFILM_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(OV13B10_QTECH_MIPI_RAW)
RAW_INFO(OV13B10_QTECH_SENSOR_ID, SENSOR_DRVNAME_OV13B10_QTECH_MIPI_RAW, CAM_CALGetCalData),
#endif
...
#if defined(OV2180_OFILM_MIPI_RAW)
RAW_INFO(OV2180_OFILM_SENSOR_ID, SENSOR_DRVNAME_OV2180_OFILM_MIPI_RAW, NULL),
#endif
#if defined(OV2180_QTECH_MIPI_RAW)
RAW_INFO(OV2180_QTECH_SENSOR_ID, SENSOR_DRVNAME_OV2180_QTECH_MIPI_RAW, NULL),
#endif
/*S5K*/
#ifdef FACTORY_MODE_ENABLE
#if defined(S5KGM1SP_MIPI_RAW)
RAW_INFO(S5KGM1SP_SENSOR_ID, SENSOR_DRVNAME_S5KGM1SP_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#if defined(S5KGM1SP_SUNNY_MIPI_RAW)
RAW_INFO(S5KGM1SP_SUNNY_SENSOR_ID, SENSOR_DRVNAME_S5KGM1SP_SUNNY_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#else
#if defined(S5KGM1SP_MIPI_RAW)
RAW_INFO(S5KGM1SP_SENSOR_ID, SENSOR_DRVNAME_S5KGM1SP_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(S5KGM1SP_SUNNY_MIPI_RAW)
RAW_INFO(S5KGM1SP_SUNNY_SENSOR_ID, SENSOR_DRVNAME_S5KGM1SP_SUNNY_MIPI_RAW, CAM_CALGetCalData),
#endif
...
#ifdef FACTORY_MODE_ENABLE
#if defined(S5K4H7YX_MIPI_RAW)
RAW_INFO(S5K4H7YX_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#if defined(S5K4H7YX_SUNNY_MIPI_RAW)
RAW_INFO(S5K4H7YX_SUNNY_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_SUNNY_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
#else
#if defined(S5K4H7YX_MIPI_RAW)
RAW_INFO(S5K4H7YX_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(S5K4H7YX_SUNNY_MIPI_RAW)
RAW_INFO(S5K4H7YX_SUNNY_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_SUNNY_MIPI_RAW, CAM_CALGetCalData),
#endif
#endif
#if defined(S5K4H7YX_OFILM_FRONT_MIPI_RAW)
RAW_INFO(S5K4H7YX_OFILM_FRONT_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_OFILM_FRONT_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(S5K4H7YX_OFILM_ULTRA_MIPI_RAW)
RAW_INFO(S5K4H7YX_OFILM_ULTRA_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_OFILM_ULTRA_MIPI_RAW, CAM_CALGetCalData),
#endif
#if defined(S5K4H7YX_QTECH_FRONT_MIPI_RAW)
RAW_INFO(S5K4H7YX_QTECH_FRONT_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_QTECH_FRONT_MIPI_RAW, NULL),
#endif
#if defined(S5K4H7YX_QTECH_ULTRA_MIPI_RAW)
RAW_INFO(S5K4H7YX_QTECH_ULTRA_SENSOR_ID, SENSOR_DRVNAME_S5K4H7YX_QTECH_ULTRA_MIPI_RAW, NULL),
#endif
...
#ifdef FACTORY_MODE_ENABLE
#if defined(GC02M1_MIPI_RAW)
RAW_INFO(GC02M1_SENSOR_ID, SENSOR_DRVNAME_GC02M1_MIPI_RAW_FACTORY,NULL),
#endif
#if defined(GC02M1_SUNNY_MIPI_RAW)
RAW_INFO(GC02M1_SUNNY_SENSOR_ID, SENSOR_DRVNAME_GC02M1_SUNNY_MIPI_RAW_FACTORY,NULL),
#endif
#else
#if defined(GC02M1_MIPI_RAW)
RAW_INFO(GC02M1_SENSOR_ID, SENSOR_DRVNAME_GC02M1_MIPI_RAW,CAM_CALGetCalData),
#endif
#if defined(GC02M1_SUNNY_MIPI_RAW)
RAW_INFO(GC02M1_SUNNY_SENSOR_ID, SENSOR_DRVNAME_GC02M1_SUNNY_MIPI_RAW,CAM_CALGetCalData),
#endif
#endif
.../* ADD sensor driver before this line */
{0, 0,{0}, NULL, NULL, NULL}//end of list
};
--(2)、调用kernel层的kdSetDriver函数
kernel-4.14/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor.c
/************************************************************************
* adopt_CAMERA_HW_FeatureControl
************************************************************************/
static inline int adopt_CAMERA_HW_FeatureControl(void *pBuf)
{
struct ACDK_SENSOR_FEATURECONTROL_STRUCT *pFeatureCtrl;
struct IMGSENSOR_SENSOR *psensor;
unsigned int FeatureParaLen = 0;
void *pFeaturePara = NULL;
struct ACDK_KD_SENSOR_SYNC_STRUCT *pSensorSyncInfo = NULL;
signed int ret = 0;pFeatureCtrl = (struct ACDK_SENSOR_FEATURECONTROL_STRUCT *)pBuf;
if (pFeatureCtrl == NULL) {
pr_err(" NULL arg.\n");
return -EFAULT;
}psensor = imgsensor_sensor_get_inst(pFeatureCtrl->InvokeCamera);
if (psensor == NULL) {
pr_err("[%s] NULL psensor.\n", __func__);
return -EFAULT;
}if (pFeatureCtrl->FeatureId == SENSOR_FEATURE_SINGLE_FOCUS_MODE ||
pFeatureCtrl->FeatureId == SENSOR_FEATURE_CANCEL_AF ||
pFeatureCtrl->FeatureId == SENSOR_FEATURE_CONSTANT_AF ||
pFeatureCtrl->FeatureId == SENSOR_FEATURE_INFINITY_AF) {
/* YUV AF_init and AF_constent and AF_single has no params */
} else {
if (pFeatureCtrl->pFeaturePara == NULL ||
pFeatureCtrl->pFeatureParaLen == NULL) {
pr_err(" NULL arg.\n");
return -EFAULT;
}
if (copy_from_user((void *)&FeatureParaLen,
(void *) pFeatureCtrl->pFeatureParaLen,
sizeof(unsigned int))) {pr_err(" ioctl copy from user failed\n");
return -EFAULT;
}
if (FeatureParaLen > FEATURE_CONTROL_MAX_DATA_SIZE)
return -EINVAL;pFeaturePara = kmalloc(FeatureParaLen + 32, GFP_KERNEL);
if (pFeaturePara == NULL)
return -ENOMEM;memset(pFeaturePara, 0x0, FeatureParaLen + 32);
}/* copy from user */
switch (pFeatureCtrl->FeatureId) {
case SENSOR_FEATURE_OPEN:
ret = imgsensor_sensor_open(psensor);
break;
case SENSOR_FEATURE_CLOSE:
ret = imgsensor_sensor_close(psensor);
/* reset the delay frame flag */
break;case SENSOR_FEATURE_SET_DRIVER:
{
MINT32 drv_idx;psensor->inst.sensor_idx = pFeatureCtrl->InvokeCamera;
drv_idx = imgsensor_set_driver(psensor);
memcpy(pFeaturePara, &drv_idx, FeatureParaLen);break;
}}
在这里面做一些设置,sensor的name、status、i2c_dev等
/************************************************************************
* imgsensor_set_driver
************************************************************************/
int imgsensor_set_driver(struct IMGSENSOR_SENSOR *psensor)
{
u32 drv_idx = 0;
int ret = -EIO;
struct IMGSENSOR_SENSOR_INST *psensor_inst = &psensor->inst;
struct IMGSENSOR_INIT_FUNC_LIST *pSensorList = kdSensorList; //把sensor驱动列表放到这块
#define TOSTRING(value) #value
#define STRINGIZE(stringizedName) TOSTRING(stringizedName)char *psensor_list_config = NULL, *psensor_list = NULL;
char *sensor_configs = STRINGIZE(CONFIG_CUSTOM_KERNEL_IMGSENSOR);static int orderedSearchList[MAX_NUM_OF_SUPPORT_SENSOR] = {-1};
static bool get_search_list = true;
int i = 0;
int j = 0;
char *driver_name = NULL;imgsensor_mutex_init(psensor_inst);
imgsensor_i2c_init(&psensor_inst->i2c_cfg,
imgsensor_custom_config[psensor->inst.sensor_idx].i2c_dev);imgsensor_i2c_filter_msg(&psensor_inst->i2c_cfg, true);
if (get_search_list) {
psensor_list = psensor_list_config =
kmalloc(strlen(sensor_configs)-1, GFP_KERNEL);if (psensor_list_config) {
for (j = 0; j < MAX_NUM_OF_SUPPORT_SENSOR; j++)
orderedSearchList[j] = -1;memcpy(psensor_list_config,
sensor_configs+1,
strlen(sensor_configs)-2);*(psensor_list_config+strlen(sensor_configs)-2) = '\0';
pr_info("sensor_list %s\n", psensor_list_config);
driver_name = strsep(&psensor_list_config, " \0");while (driver_name != NULL) {
for (j = 0;
j < MAX_NUM_OF_SUPPORT_SENSOR;
j++) {
if (pSensorList[j].init == NULL)
break;
else if (!strcmp(
driver_name,
pSensorList[j].name)) {
orderedSearchList[i++] = j;
break;
}
}
driver_name =
strsep(&psensor_list_config, " \0");
}
get_search_list = false;
}
kfree(psensor_list);
}/*pr_debug("get_search_list %d,\n %d %d %d %d\n %d %d %d %d\n",
* get_search_list,
* orderedSearchList[0],
* orderedSearchList[1],
* orderedSearchList[2],
* orderedSearchList[3],
* orderedSearchList[4],
* orderedSearchList[5],
* orderedSearchList[6],
* orderedSearchList[7]);
*//*pr_debug(" %d %d %d %d\n %d %d %d %d\n",
* orderedSearchList[8],
* orderedSearchList[9],
* orderedSearchList[10],
* orderedSearchList[11],
* orderedSearchList[12],
* orderedSearchList[13],
* orderedSearchList[14],
* orderedSearchList[15]);
*/for (i = 0; i < MAX_NUM_OF_SUPPORT_SENSOR; i++) {
/*pr_debug("orderedSearchList[%d]=%d\n",
*i, orderedSearchList[i]);
*/
if (orderedSearchList[i] == -1)
continue;
drv_idx = orderedSearchList[i];
if (pSensorList[drv_idx].init) {
pSensorList[drv_idx].init(&psensor->pfunc);
if (psensor->pfunc) {
/* get sensor name */
psensor_inst->psensor_name =
(char *)pSensorList[drv_idx].name;
#ifdef IMGSENSOR_LEGACY_COMPAT
psensor_inst->status.arch =
psensor->pfunc->arch;
#endif
if (!imgsensor_check_is_alive(psensor)) { //---(3)上下电camera并读取sensor的ID,如果匹配则成功
pr_info(
"sys [%s]:[%d][%d][%s]\n",
__func__,
psensor->inst.sensor_idx,
drv_idx,
psensor_inst->psensor_name);
#if defined(MERLIN_MSM_CAMERA_HW_INFO) || defined(LANCELOT_MSM_CAMERA_HW_INFO) \
|| defined(GALAHAD_MSM_CAMERA_HW_INFO) || defined(SHIVA_MSM_CAMERA_HW_INFO)
hq_imgsensor_sensor_hw_register(psensor, psensor_inst);
#endif
ret = drv_idx;
break;
}
} else {
pr_err(
"ERROR:NULL g_pInvokeSensorFunc[%d][%d]\n",
psensor->inst.sensor_idx,
drv_idx);
}
} else {
pr_err("ERROR:NULL sensor list[%d]\n", drv_idx);
}}
imgsensor_i2c_filter_msg(&psensor_inst->i2c_cfg, false);return ret;
}
pSensorList = kdSensorList; -->
kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
#if defined(OV13B10_MIPI_RAW)
{OV13B10_SENSOR_ID,
SENSOR_DRVNAME_OV13B10_MIPI_RAW,
OV13B10_MIPI_RAW_SensorInit},
#endif
}
OV13B10_MIPI_RAW_SensorInit->pfFunc = &sensor_func
---(3)上下电camera并读取sensor的ID,如果匹配则成功
/************************************************************************
* imgsensor_check_is_alive
************************************************************************/
static inline int imgsensor_check_is_alive(struct IMGSENSOR_SENSOR *psensor)
{
struct IMGSENSOR_SENSOR_INST *psensor_inst = &psensor->inst;
UINT32 err = 0;
MUINT32 sensorID = 0;
MUINT32 retLen = sizeof(MUINT32);IMGSENSOR_PROFILE_INIT(&psensor_inst->profile_time);
err = imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_ON); //3.1 sensor上电if (err == IMGSENSOR_RETURN_SUCCESS)
imgsensor_sensor_feature_control( //3.2 获取sensor id
psensor,
SENSOR_FEATURE_CHECK_SENSOR_ID,
(MUINT8 *)&sensorID,
&retLen);if (sensorID == 0 || sensorID == 0xFFFFFFFF) {
pr_info("Fail to get sensor ID %x\n", sensorID);
err = ERROR_SENSOR_CONNECT_FAIL;
} else {
pr_info(" Sensor found ID = 0x%x\n", sensorID);
err = ERROR_NONE;
}if (err != ERROR_NONE)
pr_info("ERROR: No imgsensor alive\n");imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_OFF); //下电IMGSENSOR_PROFILE(&psensor_inst->profile_time, "CheckIsAlive");
return err ? -EIO:err;
}
(3.1)Sensor 上电, imgsensor_hw_power(&pgimgsensor->hw,psensor,psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_ON);
enum IMGSENSOR_RETURN imgsensor_hw_power(
struct IMGSENSOR_HW *phw,
struct IMGSENSOR_SENSOR *psensor,
char *curr_sensor_name,
enum IMGSENSOR_HW_POWER_STATUS pwr_status)
{
enum IMGSENSOR_SENSOR_IDX sensor_idx = psensor->inst.sensor_idx;
char str_index[LENGTH_FOR_SNPRINTF];pr_info(
"sensor_idx %d, power %d curr_sensor_name %s, enable list %s\n",
sensor_idx,
pwr_status,
curr_sensor_name,
phw->enable_sensor_by_index[sensor_idx] == NULL
? "NULL"
: phw->enable_sensor_by_index[sensor_idx]);if (phw->enable_sensor_by_index[sensor_idx] &&
!strstr(phw->enable_sensor_by_index[sensor_idx], curr_sensor_name))
return IMGSENSOR_RETURN_ERROR;
snprintf(str_index, sizeof(str_index), "%d", sensor_idx);
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
platform_power_sequence,
str_index);imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
sensor_power_sequence,
curr_sensor_name);if (!strcmp(curr_sensor_name, "ov2180_ofilm_mipi_raw")) {
if ((pwr_status == 0) && sensor_idx == 3) {
pr_info("ov2180_ofilm_mipi_raw poweroff again.....\n");
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
platform_power_sequence,
str_index);
mdelay(5);
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
sensor_power_sequence,
curr_sensor_name);
mdelay(10);
}
}
return IMGSENSOR_RETURN_SUCCESS;
}
kernel-4.14/drivers/misc/mediatek/imgsensor/src/mt6768/camera_hw/imgsensor_cfg_table.c
/* Legacy design */
struct IMGSENSOR_HW_POWER_SEQ sensor_power_sequence[] = {#if defined(S5K4H7YX_MIPI_RAW)
{
SENSOR_DRVNAME_S5K4H7YX_MIPI_RAW,
{
{SensorMCLK, Vol_High, 2},
{RST, Vol_Low, 1},
{AVDD, Vol_2800, 1},
{DVDD, Vol_1200, 1},
{DOVDD, Vol_1800, 1},
{RST, Vol_High, 0}
},
},
#endif}
static enum IMGSENSOR_RETURN imgsensor_hw_power_sequence(
struct IMGSENSOR_HW *phw,
enum IMGSENSOR_SENSOR_IDX sensor_idx,
enum IMGSENSOR_HW_POWER_STATUS pwr_status,
struct IMGSENSOR_HW_POWER_SEQ *ppower_sequence,
char *pcurr_idx)
{
struct IMGSENSOR_HW_SENSOR_POWER *psensor_pwr =
&phw->sensor_pwr[sensor_idx];struct IMGSENSOR_HW_POWER_SEQ *ppwr_seq = ppower_sequence;
struct IMGSENSOR_HW_POWER_INFO *ppwr_info;
struct IMGSENSOR_HW_DEVICE *pdev;
int pin_cnt = 0;while (ppwr_seq < ppower_sequence + IMGSENSOR_HW_SENSOR_MAX_NUM &&
ppwr_seq->name != NULL) {
if (!strcmp(ppwr_seq->name, PLATFORM_POWER_SEQ_NAME)) {
if (sensor_idx == ppwr_seq->_idx)
break;
} else {
if (!strcmp(ppwr_seq->name, pcurr_idx))
break;
}
ppwr_seq++;
}if (ppwr_seq->name == NULL)
return IMGSENSOR_RETURN_ERROR;ppwr_info = ppwr_seq->pwr_info;
while (ppwr_info->pin != IMGSENSOR_HW_PIN_NONE &&
ppwr_info < ppwr_seq->pwr_info + IMGSENSOR_HW_POWER_INFO_MAX) {if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON &&
ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {
pdev = phw->pdev[psensor_pwr->id[ppwr_info->pin]];
pr_info(
"sensor_idx = %d, pin=%d, pin_state_on=%d, hw_id =%d\n",
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_on,
psensor_pwr->id[ppwr_info->pin]);
if (pdev->set != NULL)
pdev->set(
pdev->pinstance,
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_on);mdelay(ppwr_info->pin_on_delay);
}ppwr_info++;
pin_cnt++;
}if (pwr_status == IMGSENSOR_HW_POWER_STATUS_OFF) {
while (pin_cnt) {
ppwr_info--;
pin_cnt--;if (ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {
pdev =
phw->pdev[psensor_pwr->id[ppwr_info->pin]];
pr_info(
"sensor_idx = %d, pin=%d, pin_state_on=%d, hw_id =%d\n",
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_on,
psensor_pwr->id[ppwr_info->pin]);
mdelay(ppwr_info->pin_on_delay);if (pdev->set != NULL)
pdev->set(
pdev->pinstance,
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_off);
}
}
}/* wait for power stable */
if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON)
mdelay(5);
return IMGSENSOR_RETURN_SUCCESS;
}
(3.2) 获取sensor id
MUINT32
imgsensor_sensor_feature_control(
struct IMGSENSOR_SENSOR *psensor,
MSDK_SENSOR_FEATURE_ENUM FeatureId,
MUINT8 *pFeaturePara,
MUINT32 *pFeatureParaLen)
{
MUINT32 ret = ERROR_NONE;
struct IMGSENSOR_SENSOR_INST *psensor_inst = &psensor->inst;
struct SENSOR_FUNCTION_STRUCT *psensor_func = psensor->pfunc;IMGSENSOR_FUNCTION_ENTRY();
if (psensor_func &&
psensor_func->SensorFeatureControl &&
psensor_inst) {imgsensor_mutex_lock(psensor_inst);
psensor_func->psensor_inst = psensor_inst;
ret = psensor_func->SensorFeatureControl(
FeatureId,
pFeaturePara,
pFeatureParaLen);if (ret != ERROR_NONE)
pr_err("[%s]\n", __func__);imgsensor_mutex_unlock(psensor_inst);
}IMGSENSOR_FUNCTION_EXIT();
return ret;
}
pSensorList = kdSensorList; -->
kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
这里指定传下来具体的sensor
#if defined(OV13B10_MIPI_RAW)
{OV13B10_SENSOR_ID,
SENSOR_DRVNAME_OV13B10_MIPI_RAW,
OV13B10_MIPI_RAW_SensorInit},
#endif
}
OV13B10_MIPI_RAW_SensorInit->pfFunc = &sensor_func
kernel-4.14/drivers/misc/mediatek/imgsensor/src/common/v1/ov13b10_mipi_raw/ov13b10mipiraw_Sensor.c
static struct SENSOR_FUNCTION_STRUCT sensor_func = {
open,
get_info,
get_resolution,
feature_control,
control,
close
};
在前面的传下来的SENSOR_FEATURE_CHECK_SENSOR_ID
最后找到get_imgsensor_id
static kal_uint32 get_imgsensor_id(UINT32 *sensor_id)
{
kal_uint8 i = 0;
kal_uint8 retry = 2;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();
if (*sensor_id == imgsensor_info.sensor_id) {
cam_pr_debug("i2c write id: 0x%x, sensor id: 0x%x\n",
imgsensor.i2c_write_id, *sensor_id);
return ERROR_NONE;
}
cam_pr_debug("Read sensor id fail, write id: 0x%x, id: 0x%x\n",
imgsensor.i2c_write_id, *sensor_id);
retry--;
} while (retry > 0);
i++;
retry = 1;
}
if (*sensor_id != imgsensor_info.sensor_id) {
*sensor_id = 0xFFFFFFFF;
return ERROR_SENSOR_CONNECT_FAIL;
}return ERROR_NONE;
}
static kal_uint32 return_sensor_id(void)
{
return ((read_cmos_sensor(0x300a) << 16) |
(read_cmos_sensor(0x300b) << 8) | read_cmos_sensor(0x300c));
}
到这里简单走读searchSensor的代码
3、log
08-26 11:30:28.510464 4145 4145 I mtkcam-devicemgr: [CameraDeviceManagerBase] "internal" this:0x7235aa5908 persist.vendor.mtkcam.aosp_hal_version:
08-26 11:30:28.684843 4145 4145 I mtkcam-devicemgr: [initialize] +
08-26 11:30:28.685503 4145 4145 I mtkcam-module: [ModuleStore] ctor
08-26 11:30:28.685540 4145 4145 I mtkcam-module: [dump_module] [registered] module_id:0x0x40001 module_factory:0x723ed0e930 register_name:vendor/mediatek/proprietary/hardware/mtkcam/main/core/module/utils/register_utils.cpp
08-26 11:30:28.685551 4145 4145 I mtkcam-module: loading (MODULE_GROUP_ID:4 MODULE_GROUP_COUNT:2 ...
08-26 11:30:28.685652 4145 4145 I mtkcam-module: [load] MtkCam_getModuleFactory_utils(0x721f5f03f0) @ libmtkcam_modulefactory_utils.so
08-26 11:30:28.685697 4145 4145 D MtkCam/Util/LogicalDevice: (4145)[searchDevices] Create logical device map
08-26 11:30:28.686170 4145 4145 I mtkcam-module: [ModuleStore] ctor
08-26 11:30:28.686197 4145 4145 I mtkcam-module: [dump_module] [registered] module_id:0x0x1 module_factory:0x723eec7338 register_name:vendor/mediatek/proprietary/hardware/mtkcam/main/core/module/drv/register_HalSensor.cpp
08-26 11:30:28.686207 4145 4145 I mtkcam-module: [dump_module] [registered] module_id:0x0x2 module_factory:0x723eecfb30 register_name:vendor/mediatek/proprietary/hardware/mtkcam/main/core/module/drv/register_HwSyncDrv.cpp
08-26 11:30:28.686217 4145 4145 I mtkcam-module: [dump_module] [registered] module_id:0x0x3 module_factory:0x7228d7dcd8 register_name:vendor/mediatek/proprietary/hardware/mtkcam/main/core/module/drv/register_iopipe_CamIO_NormalPipe.cpp
08-26 11:30:28.686224 4145 4145 I mtkcam-module: loading (MODULE_GROUP_ID:0 MODULE_GROUP_COUNT:4 ...
08-26 11:30:28.686298 4145 4145 I mtkcam-module: [load] MtkCam_getModuleFactory_drv(0x721f5877f8) @ libmtkcam_modulefactory_drv.so
08-26 11:30:28.686332 4145 4145 D MtkCam/HalSensorList: [searchSensors] searchSensors
08-26 11:30:28.686361 4145 4145 D SeninfDrvImp: [SeninfDrvImp][SeninfDrvImp]
08-26 11:30:28.686378 4145 4145 D SeninfDrvImp: [init][init]: Entry count 0
08-26 11:30:28.687213 4145 4145 D SeninfDrvImp: [init]Efuse Data:0x11ce018c= 0x6b9ce738, 0x11ce0190= 0x6b9c8420, 0x11ce01ac= 0x7380d738, 0x11ce01b0= 0x73800000
08-26 11:30:28.687241 4145 4145 D SeninfDrvImp: [init][init]: Exit count 1
08-26 11:30:28.687258 4145 4145 D SeninfDrvImp: [setMclk][setMclk]pcEn(1), clkPol(0), mMclkUser[0](1), TimestampClk(0), freq(24), mclkIdx 0
08-26 11:30:28.687446 4145 4145 D SeninfDrvImp: [setMclk][setMclk]pcEn(1), clkPol(0), mMclkUser[1](1), TimestampClk(0), freq(24), mclkIdx 1
08-26 11:30:28.687625 4145 4145 D SeninfDrvImp: [setMclk][setMclk]pcEn(1), clkPol(0), mMclkUser[2](1), TimestampClk(0), freq(24), mclkIdx 2
08-26 11:30:28.687800 4145 4145 D SeninfDrvImp: [setMclk][setMclk]pcEn(1), clkPol(0), mMclkUser[3](1), TimestampClk(0), freq(24), mclkIdx 3
08-26 11:30:28.687995 4145 4145 D MtkCam/HalSensorList: [enumerateSensor_Locked] impSearchSensor search to 4
08-26 11:30:28.688013 4145 4145 D ImgSensorDrv: [searchSensor]SENSOR search start
08-26 11:30:28.740489 4145 4145 D ImgSensorDrv: [searchSensor]set sensor driver id =108-26 11:30:28.740519 4145 4145 D ImgSensorDrv: [searchSensor]sensorIdx 0 found <0x560d45/ov13b10_qtech_mipi_raw/SENSOR_DRVNAME_OV13B10_QTECH_MIPI_RAW>
08-26 11:30:28.740564 4145 4145 D ImgSensorDrv: [getInfo2]prv w=0x838,h=0x618
08-26 11:30:28.740572 4145 4145 D ImgSensorDrv: [getInfo2]cap w=0x1070,h=0xc30
08-26 11:30:28.740581 4145 4145 D ImgSensorDrv: [getInfo2]vd w=0x1070,h=0xc30
08-26 11:30:28.740590 4145 4145 D ImgSensorDrv: [getInfo2]pre GrapX=0x0,GrapY=0x008-26 11:30:28.740605 4145 4145 D MtkCam/HalSensorList: [getRawInfo] SensorOutputDataFormat: 0, ImageSensor Type: 0
08-26 11:30:28.740656 4145 4145 D MtkCam/HalSensorList: [buildSensorMetadata] impBuildSensorInfo start!
08-26 11:30:28.740757 4145 4145 D MtkCam/HalSensorList: [buildSensorMetadata] impBuildSensorInfo end!08-26 11:30:28.751473 4145 4145 I MtkCam/HalSensorList: [impBuildStaticInfo_v1] <load custom folder>
08-26 11:30:28.751473 4145 4145 I MtkCam/HalSensorList: STATIC_COMMON: [CAMERA]:1; [CONTROL_AE]:1; [CONTROL_AF]:1; [CONTROL_AWB]:1; [TUNING]:1; [FLASHLIGHT]:1; [SENSOR]:2; [LENS]:0;
08-26 11:30:28.751473 4145 4145 I MtkCam/HalSensorList: STATIC_PLATFORM: [MODULE]:8; [LENS]:8;
08-26 11:30:28.751473 4145 4145 I MtkCam/HalSensorList: STATIC_PROJECT: [MODULE]:0; [LENS]:0;08-26 11:30:28.758605 4145 4145 D MtkCam/HalSensorList: [updateAFData] MTK_LENS_INFO_MINIMUM_FOCUS_DISTANCE: 20.000000, add AF modes & regions
08-26 11:30:28.758626 4145 4145 D MtkCam/HalSensorList: [buildStaticInfo] MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION(0, 0, 4208, 3120)
08-26 11:30:28.758638 4145 4145 D MtkCam/HalSensorList: [buildStaticInfo] MTK_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE(0, 0, 4208, 3120)08-26 11:30:28.760406 4145 4145 I MtkCam/HalSensorList: [impBuildStaticInfo_v1_overwrite] <load custom folder - overwrite>
08-26 11:30:28.760406 4145 4145 I MtkCam/HalSensorList: STATIC_PLATFORM: [MOD_OVERWRITE]:8;
08-26 11:30:28.760406 4145 4145 I MtkCam/HalSensorList: STATIC_PROJECT: [MOD_OVERWRITE]:0;
search sensor的过程中,找到一个sensor,获取这个sensor的信息,然后fill in metadata。最后更新一些数据(效果参数、闪光灯、StaticInfo)。
4、结语
代码熟练度还不够溜,MTK Code细节不够火候,还需继续深入。我会不定期分享,以便查漏补缺,相互学习。奥里给!!!
5、恰饭
如果您觉得有用,感谢老铁请支持一波