camera的流程研究
 
  rn6864m_csi0   probe succeeded  ---- probe 是否成功
  rn6864m        probe succeeded  ---- 
  
  // msm_sensor_i2c_option: sensor_name=rn6864m_csi0,   camera_id=0
  // msm_sensor_i2c_option: sensor_name=rn6864m,        camera_id=1
 
./sys/devices/virtual/cam_i2c_dev/rn6864m
./sys/devices/virtual/cam_i2c_dev/rn6864m_csi0
./sys/class/cam_i2c_dev/rn6864m
./sys/class/cam_i2c_dev/rn6864m_csi0

msm8953-camera-sensor-mtp.dtsi --- 配置信息
msm_sensor_driver.c -------- 
msm_sensor_ctrl_t *s_ctrl
.compatible = "qcom,camera" --- 匹配

msm_sensor_platform_remove
msm_sensor_driver_create_i2c_v4l_subdev  --- i2c设备 
msm_sensor_driver_create_v4l_subdev      ---- v4l2设备

msm_sensor_fill_slave_info_init_params  --- 初始化参数
 
 msm_sensor_get_power_down_settings  --- 关闭camera的参数集
 
 msm_sensor_get_power_up_settings  ---- 上电camera的参数集
 .ioctl = msm_sensor_init_subdev_ioctl,
 .core = &msm_sensor_init_subdev_core_ops,
 
 public.libraries.android.txt  --- 让函数暴露出来
 vendor-->qcom-->proprietary-->common-->config--> device-vendor.mk  MM_CAMERA += libmmcamera_rn6864m
 
 modules-->sensors--> msm8953_camera.xml
 CameraId   整个系统的camera编号
 SensorName  sensor也就是camera的名称,与驱动要匹配
 CSIDCore  --- 连接到哪一路物理上的CSI       qcom,csiphy-sd-index = <0>;  与这个同步 (qcom,csid-sd-index = <1>;)
 
 <CSIDCore>0</CSIDCore>
 
qcom,csiphy-sd-index = <2>;  <CameraId>2</CameraId>  --- 软件上的CSI0 还是 1  
qcom,csid-sd-index = <1>; <CSIDCore>1</CSIDCore>     --- 物理上的CSI0 还是一
.h 中的配置 #define SENSOR_MODEL "rn6864m"  驱动模型的 名称 name

HAL 层的调用 sensor 的调用流程  ---> --->

[   20.209720] rn6864m_csi0 probe succeeded
[   20.212426] msm_sensor_i2c_option: sensor_name=rn6864m_csi0,camera_id=0
[   20.232313] ------------[ cut here ]------------
[   20.235925] WARNING: CPU: 4 PID: 704 at /mnt/data/ailiving/Workfolder/carl/aili/d/d-5/sc60/kernel/msm-3.18/drivers/gpio/gpiolib.c:68 gpio_to_desc+0x2c/0x50()
[   20.262078] Call trace:
[   20.263624] ---[ end trace 6938045f0ff21e83 ]---
[   20.268484] ------------[ cut here ]------------
[   20.272704] WARNING: CPU: 5 PID: 704 at /mnt/data/ailiving/Workfolder/carl/aili/d/d-5/sc60/kernel/msm-3.18/drivers/gpio/gpiolib.c:68 gpio_to_desc+0x2c/0x50()
[   20.286944] Call trace:
[   20.289426] ---[ end trace 6938045f0ff21e84 ]---
[   20.409467] rn6864m probe succeeded

msm8953_64:/dev # ls vi* -l -l
crw-rw---- 1 system camera 81,   2 2000-01-12 08:12 video0
crw-rw---- 1 system camera 81,  17 2000-01-12 08:12 video1
crw-rw---- 1 system camera 81,  19 2000-01-12 08:12 video2
crw-rw---- 1 system camera 81,   0 2000-01-12 08:12 video32
crw-rw---- 1 system camera 81,   1 2000-01-12 08:12 video33
msm8953_64:/dev #

HAL发送命令,根据xml文件中的camera的名字,加载不同的camera驱动
vendor

在SensorDevice构造方法里调用HAL架构的hw_get_module来获得Sensor设备模块,
之后调用sensors_open这个工具函数,打开Sensor设备模块(调用其methods->open函数指针),返回Sensor设备的操作接口(这些接口在HAL层实现),保存在mSensorDevice中,调用Sensor模块的get_sensors_list方法获得传感器列表,然后依次激活这些设备并且添加到mActivationCount设备信息向量中。
Sensor HAL模块代码及打开模块工具函数sensors_open:
@hardware/libhardware/include/hardware/sensors.h
./qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_init.c

主要是从vendor下sensor_init.c中probe到kernel层上电probe检测的流程。
module_sensor_init()                                            //module_sensor.c    |
 //创建mct, camera引擎
        ---> s_module = mct_module_create(name) 
 //初始化sensor module control structure               
        ---> module_sensor_ctrl_t        *module_ctrl
//probe sensor
        ---> sensor_init_probe(module_ctrl)      
//其他的subdev,比如actuator, eeprom, flash, cis, ois
        --->module_sensor_find_other_subdev(module_ctrl);
//然后是执行mct_list_traverse,分别初始化

然后看一下sensor_init_probe:

static boolean sensor_probe(module_sensor_ctrl_t *module_ctrl, int32_t fd,
  const char *sensor_name, char *path, struct xmlCameraConfigInfo *xmlConfig)
{
  boolean                              ret = TRUE;
  int32_t                              rc = 0, i;
  sensor_lib_params_t                  *sensor_lib_params;
  struct sensor_init_cfg_data          cfg;
  struct msm_camera_sensor_slave_info *slave_info = NULL;
  struct msm_sensor_power_setting *power_up_setting = NULL;
  struct msm_sensor_power_setting *power_down_setting = NULL;
  struct camera_power_setting_array *power_setting_array;

/* Validate input parameters */
  if ((fd < 0) || !sensor_name || (xmlConfig == NULL)) {
    SERR("failed: invalid params fd %d sensor_name %s xmlConfig %p ",
      fd, sensor_name, xmlConfig);
    return FALSE;
  }
  
  
  
  
  
  static boolean sensor_init_xml_probe(module_sensor_ctrl_t *module_ctrl,
  int32_t sd_fd)
{
  int32_t         rc = 0;
  boolean         ret = FALSE;
  uint32_t        i = 0;
  char            config_xml_name[BUFF_SIZE_255];
  xmlDocPtr       docPtr = NULL;
  xmlNodePtr      rootPtr = NULL;
  xmlNodePtr      nodePtr = NULL;
  uint32_t        num_cam_config = 0;
  uint8_t         slot_probed[MAX_SENSOR_SLOT_NUMBER] = {0};
  camera_module_config_t camera_cfg;
  struct xmlCameraConfigInfo xmlConfig;
  char prop[PROPERTY_VALUE_MAX];
  uint32_t csidtg_enable = 0;

property_get("persist.camera.csidtg.enable", prop, "0");
  csidtg_enable = atoi(prop);

/* Create the xml path from data partition */
  snprintf(config_xml_name, BUFF_SIZE_255, "%s%s",
    CONFIG_XML_PATH, CONFIG_XML);

if (access(config_xml_name, R_OK)) {
    SHIGH(" read fail (non-fatal) %s. Trying from system partition",
      config_xml_name);

if (csidtg_enable) {
      /* Create the CSIDTG xml path from system partition */
      snprintf(config_xml_name, BUFF_SIZE_255, "%s%s",
        CONFIG_XML_SYSTEM_PATH, CSIDTG_CONFIG_XML);
    } else {
      /* Create the xml path from system partition */
      snprintf(config_xml_name, BUFF_SIZE_255, "%s%s",
        CONFIG_XML_SYSTEM_PATH, CONFIG_XML);
    }

if (access(config_xml_name, R_OK)) {
      SERR("Cannot read file from %s. read failed", config_xml_name);
      return FALSE;
    }
  }

SHIGH("reading from file %s", config_xml_name);

/* Get the Root pointer and Document pointer of XMl file */
  ret = sensor_xml_util_load_file(config_xml_name, &docPtr, &rootPtr,
    "CameraConfigurationRoot");
  if (ret == FALSE) {
    SERR(" sensor_xml_util_load_file failed");
    return FALSE;
  }

/* Get number of camera module configurations */
  num_cam_config = sensor_xml_util_get_num_nodes(rootPtr, "CameraModuleConfig");
  SLOW("num_cam_config = %d", num_cam_config);
  if (!num_cam_config || num_cam_config > MAX_CAMERA_CONFIG) {
    SERR(" invalid num_cam_config = %d", num_cam_config);
    ret = FALSE;
    goto XML_PROBE_EXIT;
  }

这个函数用来解析vendor下msm8953_camera.xml, 然后进行sensor probe:
步骤:
    1.获得xml路径
    2.检查根节点CameraModuleConfig个数,判断有几个camera
    3.for循环判断是否已经probe,没有就进行sensor_probe()
 
-----------
其中第一步中:
    先检查路径 CONFIG_XML_PATH + CONFIG_XML = “/data/misc/camera/camera_config.xml”
    然后判断系统属性persist.camera.csidtg.enable是否设置,为1就检查
    CONFIG_XML_SYSTEM_PATH + CONFIG_XML = "/system/etc/camera/camera_config.xml"
 
这个是out下最终生成的xml

boolean sensor_init_probe(module_sensor_ctrl_t *module_ctrl)
{
  int32_t                     rc = 0, dev_fd = 0, sd_fd = 0;
  uint32_t                    i = 0;
  struct media_device_info    mdev_info;
  int32_t                     num_media_devices = 0;
  char                        dev_name[32];
  char                        subdev_name[32];
  struct sensor_init_cfg_data cfg;
  boolean                     ret = TRUE;

while (1) {
    uint32_t num_entities = 1;
    snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
    dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    if (dev_fd < 0) {
      SLOW("Done enumerating media devices");
      break;
    }

mct_module_t *module_sensor_init(const char *name)
{
  boolean                      ret = TRUE;
  int32_t                      rc = 0;
  mct_module_t                *s_module = NULL;
  module_sensor_ctrl_t        *module_ctrl = NULL;
  eebin_ctl_t bin_ctl;

SHIGH("Sensor driver Version: %s", SENSOR_DRIVER_VERSION);
  SHIGH("Sensor SDK capabilities: %s", SENSOR_SDK_CAPABILITIES);

SHIGH("Actuator driver Version: %s", ACTUATOR_DRIVER_VERSION);
  SHIGH("Actuator SDK capabilities: %s", ACTUATOR_SDK_CAPABILITIES);

SHIGH("EEPROM driver Version: %s", EEPROM_DRIVER_VERSION);
  SHIGH("EEPROM SDK capabilities: %s", EEPROM_SDK_CAPABILITIES);

SHIGH("Flash driver Version: %s", FLASH_DRIVER_VERSION);
  SHIGH("Flash SDK capabilities: %s", FLASH_SDK_CAPABILITIES);

SHIGH("OIS driver Version: %s", OIS_DRIVER_VERSION);
  SHIGH("OIS SDK capabilities: %s", OIS_SDK_CAPABILITIES);

SHIGH("PDAF driver Version: %s", PDAF_DRIVER_VERSION);
  SHIGH("PDAF SDK capabilities: %s", PDAF_SDK_CAPABILITIES);

/* Create MCT module for sensor */
  s_module = mct_module_create(name);
  if (!s_module) {
    SERR("failed");
    return NULL;
  }

/* Fill function table in MCT module */
  s_module->set_mod = module_sensor_set_mod;
  s_module->query_mod = module_sensor_query_mod;
  s_module->start_session = module_sensor_start_session;
  s_module->stop_session = module_sensor_stop_session;
  s_module->set_session_data = module_sensor_set_session_data;
  s_module->get_session_data = module_sensor_get_session_data;
  /* Create sensor module control structure that consists of bundle
     information */
  module_ctrl = malloc(sizeof(module_sensor_ctrl_t));
  if (!module_ctrl) {
    SERR("failed");
    goto ERROR1;
  }
  memset(module_ctrl, 0, sizeof(module_sensor_ctrl_t));

s_module->module_private = (void *)module_ctrl;

/* sensor module doesn't have sink port */
  s_module->numsinkports = 0;

rc = eebin_interface_init(&module_ctrl->eebin_hdl);
  if (rc < 0) {
    SERR("failed");
  }

bin_ctl.cmd = EEPROM_BIN_GET_BIN_DATA;
  rc = eebin_interface_control(module_ctrl->eebin_hdl, &bin_ctl);
  if (rc < 0) {
    SERR("failed");
  }

/* module_sensor_probe_sensors */
  ret = sensor_init_probe(module_ctrl);
  if (ret == FALSE) {
    SERR("failed");
    goto ERROR1;
  }
  
  
1.枚举/dev/media*, 然后用ioctl打开,获得mdev_info, 比较是不是msm_config,不是就结束
2.sd_fd = open(subdev_name, O_RDWR);                          //获得文件描述符

1.调用sensor_load_libbrary()            //加载libmmcamera_ov7251.so这类库文件
                                   //这个函数调用的dlsy打开库,返回符号地址,通过地址调用方法
 
2.从返回的地址获得上电时序power_setting_array
 
3.然后是malloc申请空间这些,主要目的是把xml里的信息,复制到变量slave_info中
                        //struct msm_camera_sensor_slave_info slave_info
 
4.把slave_info传到kernel层,通过ioctl(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg)的方式
                        //这里slave_info是cfg的成员
                        //对应kernel:
                        //传入的命令码是VIDIOC_MSM_SENSOR_INIT_CFG
                        //cfg.cfgtype = CFG_SINIT_PROBE;
 
5.执行完ioctl, 通过返回的cfg.probed_info.session_id在这一层判断是否probe成功

对应的是:
        driver/media/platform/msm/camera_v2/sensor/msm_sensor_init.c +117
                case VIDIOC_MSM_SENSOR_INIT_CFG:
 
//上面cfg传到这里成了arg
//
static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init,void *arg)
 
这个函数中判断了上面的cfg->cfgtype, 然后就执行了kernel底层的硬件probe
 
 72     switch (cfg->cfgtype) {
 73     case CFG_SINIT_PROBE:
 74         mutex_lock(&s_init->imutex);
 75         s_init->module_init_status = 0;
 76         rc = msm_sensor_driver_probe(cfg->cfg.setting,
 77                                             &cfg->probed_info,
 78                                                     cfg->entity_name);
 
 
最后执行到msm_sensor_driver_probe()
这个函数里面static int __init msm_sensor_driver_init(void)
{
    int32_t rc = 0;

CDBG("%s Enter\n", __func__);
    rc = platform_driver_register(&msm_sensor_platform_driver);
    if (rc)
        pr_err("%s platform_driver_register failed rc = %d",
            __func__, rc);
    rc = i2c_add_driver(&msm_sensor_driver_i2c);
    if (rc)
        pr_err("%s i2c_add_driver failed rc = %d",  __func__, rc);

return rc;
}
做的一些事情,主要是把user层的camera信息复制到kerner层的结构体中
 
比如把上下电时序复制到msm_sensor_ctrl_t->sensordata->power_info中,
然后执行真正的上电检测
           rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
 
然后Create /dev/videoX node;
 
然后下电    s_ctrl->func_tbl->sensor_power_down(s_ctrl);

static int __init msm_sensor_driver_init(void)
{
    int32_t rc = 0;

CDBG("%s Enter\n", __func__);
    rc = platform_driver_register(&msm_sensor_platform_driver);
    if (rc)
        pr_err("%s platform_driver_register failed rc = %d",
            __func__, rc);
    rc = i2c_add_driver(&msm_sensor_driver_i2c);
    if (rc)
        pr_err("%s i2c_add_driver failed rc = %d",  __func__, rc);

return rc;
}

static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev)
{
    int32_t rc = 0;
    struct msm_sensor_ctrl_t *s_ctrl = NULL;

/* Create sensor control structure */
    s_ctrl = kzalloc(sizeof(*s_ctrl), GFP_KERNEL);
    if (!s_ctrl)
        return -ENOMEM;

platform_set_drvdata(pdev, s_ctrl);

/* Initialize sensor device type */
    s_ctrl->sensor_device_type = MSM_CAMERA_PLATFORM_DEVICE;
    s_ctrl->of_node = pdev->dev.of_node;

/*fill in platform device*/
    s_ctrl->pdev = pdev;

rc = msm_sensor_driver_parse(s_ctrl);
    if (rc < 0) {
        pr_err("failed: msm_sensor_driver_parse rc %d", rc);
        goto FREE_S_CTRL;
    }

/* Get clocks information */
    rc = msm_camera_get_clk_info(s_ctrl->pdev,
        &s_ctrl->sensordata->power_info.clk_info,
        &s_ctrl->sensordata->power_info.clk_ptr,
        &s_ctrl->sensordata->power_info.clk_info_size);
    if (rc < 0) {
        pr_err("failed: msm_camera_get_clk_info rc %d", rc);
        goto FREE_S_CTRL;
    }

/* Fill platform device id*/
    pdev->id = s_ctrl->id;

/* Fill device in power info */
    s_ctrl->sensordata->power_info.dev = &pdev->dev;
    return rc;
FREE_S_CTRL:
    kfree(s_ctrl);
    return rc;

int32_t msm_sensor_driver_probe(void *setting,
    struct msm_sensor_info_t *probed_info, char *entity_name)
{
    int32_t                              rc = 0;
    struct msm_sensor_ctrl_t            *s_ctrl = NULL;
    struct msm_camera_cci_client        *cci_client = NULL;
    struct msm_camera_sensor_slave_info *slave_info = NULL;
    struct msm_camera_slave_info        *camera_info = NULL;

unsigned long                        mount_pos = 0;
    uint32_t                             is_yuv;

/* Validate input parameters */
    if (!setting) {
        pr_err("failed: slave_info %pK", setting);
        return -EINVAL;
    }

msm 8953 camera 流程相关推荐

  1. Android Camera 流程学习记录(五)—— Camera.takePicture() 流程解析

    简介 在前面的几篇笔记中,我已经把 Camera 控制流的部分梳理得比较清楚了.在 Camera 流程中,还有一个重要的部分,即数据流. Camera API 1 中,数据流主要是通过函数回调的方式, ...

  2. 第4讲 Android Camera2 API Open/Close Camera流程

    本讲是Android Camera专题系列的第4讲,我们介绍Android Camera2 API专题的Open/Close Camera部分. 视频在线观看: 极客笔记:极客笔记在线课程 会讲解如下 ...

  3. AIS Camera流程-opencamera

    本文主要介绍AIS camera打开相机流程. 上篇文章中介绍了ais_v4l2_proxy 这个服务的启动,作用是遍历ais_v4l2loopback_config.xml中的配置的 所有camer ...

  4. MSM USB插入流程代码分析

    点击打开链接 代码路径:kernel\msm-3.18\drivers\power\qpnp-smbcharger.c src_detect_handler -->update_usb_stat ...

  5. 【IoT】高通 Camera 流程及调试步骤

    目录 1.Camera BringUp 前期条件 2.OTP BringUp 前期条件 步骤 3.Actuator BringUp 前期条件

  6. Android 自定义相机Camera流程

    demo 下载 android Camera 如何 获取最佳合适的尺寸 1.如何利用 Camera 开发自定义相机? a.Camera.getNumberOfCameras() 获取 相机数目返回一个 ...

  7. msm 8953 制作算法分区的部分记录,太容易忘记了

    ./out/host/linux-x86/bin/make_ext4fs -l 1024M -s out/target/product/msm8953_64/custom.img out/target ...

  8. Android Camera 打开预览流程分析(一)--打开camera的SDK流程

    Android系统应用场景中,Camera的使用场景变得越来越重要,在手机端不管是牌照美颜,还是拍小视频上传小视频平台.在其他领域,如车载,倒车视频,360全景影像也同样会用到Camera接口.那我们 ...

  9. 【高通SDM660平台 Android 10.0】(10) --- Camera Sensor lib 与 Kernel Camera Probe 代码分析

    [高通SDM660平台 Android 10.0]Camera Sensor lib 与 Kernel Camera Probe 代码分析 一.libmmcamera_imx258.so 代码分析 1 ...

  10. 安卓camera总体框架

    今天是周五了,时间过得真快,通常这个时候,我都还沉醉了上班的状态中,说到上班,我是认真的,我非常喜欢上班,特别是今天,我会听到一声优美的声音,我的银行卡会多出一些钱,而这些最粗鲁的奖励也是我最讨厌的, ...

最新文章

  1. cmder里ls、pwd、自定义的alias等一系列命令都无法使用
  2. 服务器虚拟机怎么控制,虚拟机可以控制云服务器吗
  3. 原文翻译:关于机器学习,我们忽视的东西
  4. Python中math模块的使用
  5. php选中文本区域,php – 将新行更改为文本区域
  6. 配置管理规范 配置管理计划_配置管理简介
  7. html做qq钓鱼网站,QQ钓鱼网站是什么?
  8. 计算机学报编辑待遇,《计算机学报》编辑委员会
  9. MFC窗体的扩展样式和其值
  10. mysql是什么?mysql的特点
  11. yarn : 无法加载文件 C:\Users\HYGK\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsof
  12. java实现微博_java实现的新浪微博分享代码实例
  13. 日本語トレーニング45
  14. 海湾汉字编码表全部_汉字unicode码表范围和常用汉字unicode码
  15. 热爱生活热爱工作才是第一位的
  16. 光伏组件机器视觉新突破!维视智造上线汇流带引线焊接检测新方案 “误检率”低至0.01%
  17. Android webview加载本地html详细教程
  18. 线性链表java实现_线性表的Java实现--链式存储(双向链表)
  19. 初学python:Python 3的下载、安装、第一个程序(Helloworld.py)与卸载
  20. 根据两点经纬度计算两点距离...工具类

热门文章

  1. [ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
  2. 路由期末复习(二)—配置命令
  3. Oracle Coherence中文教程十二:配置高速缓存
  4. matlab src,SRC 这是一个利用了稀疏表示方法的MATLAB程序,供大家参考学习。 Special Effects 图形图像处理 256万源代码下载- www.pudn.com...
  5. C语言使用josn库解析数据
  6. du命令排序文件大小
  7. JAVA最强工具类之一HuTool
  8. 【多元函数微分学】易错点总结
  9. Java——自定义图片和居中
  10. 印第安纳大学计算机与信息学院,印第安纳大学伯明顿分校管理信息系统(MIS)专业详解...