Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor

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》

《Android Q 之MTK代码分析(三)--Camera Hal3 Open/Close》

《Android Q 之MTK代码分析(四)--Camera Hal3 configureStreams》

《Android Q 之MTK代码分析(五)--Camera Hal3 process_capture_request》

《Android Q 之MTK代码分析(六)--Camera Hal3 process_capture_result》

 

备忘

文末支持一波,感谢鞠躬

0、前文回顾

     前文简单了解下CameraService、CameraHalService、CameraProvider服务(加载其rc文件,注册在CameraHalService服务上)的启动。《interface》 IVirtualDevice,给camera service暴露接口去操作camera,给Camera Device Manager 暴露接口去交互。在这之后会立即启动searchSesnor流程

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第1张图片

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第2张图片

(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("internal/0" /*"internal" for binderized mode*/);
#endif
    }

    {
#if MTKCAM_LOMO_SUPPORT
        using vendor::mediatek::hardware::camera::lomoeffect::V1_0::ILomoEffect;
        registerPassthroughServiceImplementation("internal/0" /*"internal" for binderized mode*/);
#endif
    }

    {
        using vendor::mediatek::hardware::camera::ccap::V1_0::ICCAPControl;
        registerPassthroughServiceImplementation("internal/0" /*"internal" for binderized mode*/);
    }

    {
#if MTKCAM_MMSDK_SUPPORT
        using vendor::mediatek::hardware::camera::callbackclient::V1_1::IMtkCallbackClient;
        registerPassthroughServiceImplementation("internal/0" /*"internal" for binderized mode*/);
#endif
    }

    {
        using ::vendor::mediatek::hardware::camera::frhandler::V1_0::IFRHandler;
        registerPassthroughServiceImplementation("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
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
    Func registerServiceCb, const std::string& name = "default") {
    sp 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
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
    const std::string& name = "default") {
    return details::registerPassthroughServiceImplementation(
        [](const sp& 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 getService(
                  const std::string &serviceName) = 0;

system/libhidl/transport/include/hidl/HidlTransportSupport.h

namespace android {
namespace hardware {

......

namespace details {

template           typename = std::enable_if_t::value>,
          typename = std::enable_if_t::value>>
sp getServiceInternal(const std::string& instance, bool retry, bool getStub) {
    using ::android::hidl::base::V1_0::IBase;

    sp base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);

    if (base == nullptr) {
        return nullptr;
    }

    if (base->isRemote()) {
        // getRawServiceInternal guarantees we get the proper class
        return sp(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                                                  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> get(const hidl_string& fqName,
                          const hidl_string& name) override {
        sp 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 getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}
sp getPassthroughServiceManager1_1() {
    static sp 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;

    sp 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 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_MANIFEST

    for (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> 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 base = ret;
        if (base != nullptr) {
            Return 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 pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            sp 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/" or "legacy/".
    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检测上电,以及在previewcapture初始化3A等等功能设定时的寄存器配置;
    isp driver,通过DMA将sensor数据流上传;

HAL层部分主要有三部分组成:

    imageio,主要负责数据buffer上传的pipe;
    drv,包含imgsensorisp的hal层控制;
    feature io,包含各种3A等性能配置;

 

2、Search Sensor

下图有search sensor的流程

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第3张图片

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第4张图片

(1)、开始SearchSensor

       压轴戏

(2)、创建IMetadataProvider对象

(3)、创建VirtualCameraDevice对象

(4)、创建CameraDevice3实例

(5)、创建CameraDevice3Session实例

vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/entry/hidl/device/3.x/HidlCameraDeviceSession.cpp

auto
HidlCameraDeviceSession::
create(
    const ::android::sp& session
)-> HidlCameraDeviceSession*
{
    auto pInstance = new HidlCameraDeviceSession(session);

    if  ( ! pInstance ) {
        delete pInstance;
        return nullptr;
    }

    return pInstance;
}

HidlCameraDeviceSession::
HidlCameraDeviceSession(const ::android::sp& session)
    : ICameraDeviceSession()
    , mSession(session)
    , mCameraDeviceCallback(nullptr)
    , mLogPrefix(std::to_string(session->getInstanceId())+"-hidl-session")
    , mBufferHandleCacheMgr()
    , mRequestMetadataQueue()
    , mResultMetadataQueue()
{
    MY_LOGI("ctor");

    mConvertTimeDebug = property_get_int32("vendor.debug.camera.log.convertTime", 0);
    mAutoTestDebug = property_get_bool("vendor.autotesttool.enable", 0);

    if ( CC_UNLIKELY(mSession==nullptr) ) {
        MY_LOGE("session does not exist");
    }
    ::memset(&mLinkToDeathDebugInfo, 0, sizeof(mLinkToDeathDebugInfo));
}

(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 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 pPhysDevice = new PhysEnumDevice;
        sp 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 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 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;
#endif

    MY_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

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第5张图片

最后找到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的代码

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第6张图片

3、log

//camera device manager enumerate device when initialize:

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:29.102251  4145  4145 I mtkcam-devicemgr: pHalDeviceList:0xb400007331528f20 searchDevices:6 queryNumberOfDevices:6

08-26 11:30:33.474766  4145  4145 I mtkcam-devicemgr: [logLocked] Physical Devices: # 5

08-26 11:30:33.475023  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.475221  4145  4145 I mtkcam-devicemgr: [logLocked]   [00] -> orientation(wanted/setup)=( 90/90 ) BACK  hasFlashUnit:1 SENSOR_DRVNAME_OV13B10_QTECH_MIPI_RAW [PhysEnumDevice:0xb400007311545730]
08-26 11:30:33.475438  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.475628  4145  4145 I mtkcam-devicemgr: [logLocked]   [01] -> orientation(wanted/setup)=(270/270) FRONT hasFlashUnit:0 SENSOR_DRVNAME_OV8856_QTECH_FRONT_MIPI_RAW [PhysEnumDevice:0xb400007311542c10]
08-26 11:30:33.475828  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.476022  4145  4145 I mtkcam-devicemgr: [logLocked]   [02] -> orientation(wanted/setup)=(270/90 ) BACK  hasFlashUnit:1 SENSOR_DRVNAME_OV8856_QTECH_ULTRA_MIPI_RAW [PhysEnumDevice:0xb40000731153ee90]
08-26 11:30:33.476218  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.476482  4145  4145 I mtkcam-devicemgr: [logLocked]   [03] -> orientation(wanted/setup)=(270/90 ) BACK  hasFlashUnit:1 SENSOR_DRVNAME_OV2180_QTECH_MIPI_RAW [PhysEnumDevice:0xb400007311547dd0]
08-26 11:30:33.476688  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.476907  4145  4145 I mtkcam-devicemgr: [logLocked]   [04] -> orientation(wanted/setup)=(270/90 ) BACK  hasFlashUnit:1 SENSOR_DRVNAME_GC5035_QTECH_MIPI_RAW [PhysEnumDevice:0xb400007311547d10]
08-26 11:30:33.477061  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.477254  4145  4145 I mtkcam-devicemgr: [logLocked] Virtual Devices: # 6
08-26 11:30:33.477458  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.477671  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/0] -> 00 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f1561b90 IVirtualDevice:0xb400007351526698]
08-26 11:30:33.477885  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.478105  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/1] -> 01 torchModeStatus:NOT_AVAILABLE hasFlashUnit:0 [VirtEnumDevice:0xb4000072f1568950 IVirtualDevice:0xb400007351527958]
08-26 11:30:33.478320  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.478508  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/20] -> 03 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f1572ad0 IVirtualDevice:0xb400007351526f98]
08-26 11:30:33.478709  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.478912  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/21] -> 02 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f1568710 IVirtualDevice:0xb400007351527358]
08-26 11:30:33.479104  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.479299  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/22] -> 04 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f156ea10 IVirtualDevice:0xb400007351525318]
08-26 11:30:33.479494  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.479688  4145  4145 I mtkcam-devicemgr: [logLocked]   [[email protected]/internal/61] -> 05 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f15686d0 IVirtualDevice:0xb400007351525858]
08-26 11:30:33.479883  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.480153  4145  4145 I mtkcam-devicemgr: [logLocked] Open Devices: # 0 (multi-opened maximum: # 1)
08-26 11:30:33.480404  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.480615  4145  4145 I mtkcam-devicemgr: [initialize] -

08-26 11:30:33.480153  4145  4145 I mtkcam-devicemgr: [logLocked] Open Devices: # 0 (multi-opened maximum: # 1)
08-26 11:30:33.480404  4145  4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.480615  4145  4145 I mtkcam-devicemgr: [initialize] -

//camera provider hal:

08-26 11:30:33.480838  4145  4145 I mtkcam-camprovider: [createICameraProvider_V2_6] + internal/0
08-26 11:30:33.481076  4145  4145 I mtkcam-camprovider: [initialize] +
08-26 11:30:33.482122  4145  4145 I mtkcam-camprovider: [initialize] -
08-26 11:30:33.482340  4145  4145 I mtkcam-camprovider: [createICameraProvider_V2_6] - internal/0 provider:0xb4000073415248f0 manager:0x7235aa5908

 

search sensor的过程中,找到一个sensor,获取这个sensor的信息,然后fill in metadata。最后更新一些数据(效果参数、闪光灯、StaticInfo)。

4、结语

  代码熟练度还不够溜,MTK Code细节不够火候,还需继续深入。我会不定期分享,以便查漏补缺,相互学习。奥里给!!!

5、恰饭

如果您觉得有用,感谢老铁请支持一波

Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor_第7张图片

你可能感兴趣的:(MTK,Cam,Hal3,android,c++)