msm 8953 camera 流程
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 流程相关推荐
- Android Camera 流程学习记录(五)—— Camera.takePicture() 流程解析
简介 在前面的几篇笔记中,我已经把 Camera 控制流的部分梳理得比较清楚了.在 Camera 流程中,还有一个重要的部分,即数据流. Camera API 1 中,数据流主要是通过函数回调的方式, ...
- 第4讲 Android Camera2 API Open/Close Camera流程
本讲是Android Camera专题系列的第4讲,我们介绍Android Camera2 API专题的Open/Close Camera部分. 视频在线观看: 极客笔记:极客笔记在线课程 会讲解如下 ...
- AIS Camera流程-opencamera
本文主要介绍AIS camera打开相机流程. 上篇文章中介绍了ais_v4l2_proxy 这个服务的启动,作用是遍历ais_v4l2loopback_config.xml中的配置的 所有camer ...
- MSM USB插入流程代码分析
点击打开链接 代码路径:kernel\msm-3.18\drivers\power\qpnp-smbcharger.c src_detect_handler -->update_usb_stat ...
- 【IoT】高通 Camera 流程及调试步骤
目录 1.Camera BringUp 前期条件 2.OTP BringUp 前期条件 步骤 3.Actuator BringUp 前期条件
- Android 自定义相机Camera流程
demo 下载 android Camera 如何 获取最佳合适的尺寸 1.如何利用 Camera 开发自定义相机? a.Camera.getNumberOfCameras() 获取 相机数目返回一个 ...
- msm 8953 制作算法分区的部分记录,太容易忘记了
./out/host/linux-x86/bin/make_ext4fs -l 1024M -s out/target/product/msm8953_64/custom.img out/target ...
- Android Camera 打开预览流程分析(一)--打开camera的SDK流程
Android系统应用场景中,Camera的使用场景变得越来越重要,在手机端不管是牌照美颜,还是拍小视频上传小视频平台.在其他领域,如车载,倒车视频,360全景影像也同样会用到Camera接口.那我们 ...
- 【高通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 ...
- 安卓camera总体框架
今天是周五了,时间过得真快,通常这个时候,我都还沉醉了上班的状态中,说到上班,我是认真的,我非常喜欢上班,特别是今天,我会听到一声优美的声音,我的银行卡会多出一些钱,而这些最粗鲁的奖励也是我最讨厌的, ...
最新文章
- cmder里ls、pwd、自定义的alias等一系列命令都无法使用
- 服务器虚拟机怎么控制,虚拟机可以控制云服务器吗
- 原文翻译:关于机器学习,我们忽视的东西
- Python中math模块的使用
- php选中文本区域,php – 将新行更改为文本区域
- 配置管理规范 配置管理计划_配置管理简介
- html做qq钓鱼网站,QQ钓鱼网站是什么?
- 计算机学报编辑待遇,《计算机学报》编辑委员会
- MFC窗体的扩展样式和其值
- mysql是什么?mysql的特点
- yarn : 无法加载文件 C:\Users\HYGK\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsof
- java实现微博_java实现的新浪微博分享代码实例
- 日本語トレーニング45
- 海湾汉字编码表全部_汉字unicode码表范围和常用汉字unicode码
- 热爱生活热爱工作才是第一位的
- 光伏组件机器视觉新突破!维视智造上线汇流带引线焊接检测新方案 “误检率”低至0.01%
- Android webview加载本地html详细教程
- 线性链表java实现_线性表的Java实现--链式存储(双向链表)
- 初学python:Python 3的下载、安装、第一个程序(Helloworld.py)与卸载
- 根据两点经纬度计算两点距离...工具类
热门文章
- [ 英语 ] 语法重塑 之 英语学习的核心框架 —— 英语兔学习笔记(1)
- 路由期末复习(二)—配置命令
- Oracle Coherence中文教程十二:配置高速缓存
- matlab src,SRC 这是一个利用了稀疏表示方法的MATLAB程序,供大家参考学习。 Special Effects 图形图像处理 256万源代码下载- www.pudn.com...
- C语言使用josn库解析数据
- du命令排序文件大小
- JAVA最强工具类之一HuTool
- 【多元函数微分学】易错点总结
- Java——自定义图片和居中
- 印第安纳大学计算机与信息学院,印第安纳大学伯明顿分校管理信息系统(MIS)专业详解...