android_驱动_qcom_【高通SDM660平台】(2)---Kernel 驱动层代码逻辑分析

10 篇文章 2 订阅


【高通SDM660平台】(1) — Camera 驱动 Bringup Guide
【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析
【高通SDM660平台】(3) — Camera V4L2 驱动层分析
【高通SDM660平台】(4) — Camera Init 初始化流程
【高通SDM660平台】(5) — Camera Open 流程
【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程
【高通SDM660平台】(7) — Camera onPreview 代码流程
【高通SDM660平台】(8) — Camera MetaData介绍
【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析
【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析
《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》


在前面《【高通SDM660平台】Camera 驱动 Bringup Guide》中,我们学习了如何移植Camera 驱动,今天开始,我们要结合代码,学习下Kernel 中Camera 驱动具体的原理。

1. Camera Kernel 驱动

Kernel 驱动中 高通把Camera系统分为 Camera 和 Sensor 两部分:
Camera 部分是通用的代码逻辑,该部分由msm_cam 设备作为 video设备 与 userspace 进行交互,Qcom自已的MIPI,ISP,CPP 等硬件设备都属于Camera部分。
Sensor 可以理解为外部设备,是不同产商生产的Camera sensor模组。开发者分只需要配置不同的Sensor模组,将其注册到msm_cam设备上,创建好对应的video 设备,其他具体的接口逻辑均由Camera部分来实现。


在实际工作时,camera video设备主要是提供一个v4l2接口,Camera 驱动在接收到event消息后,会把该event消息及其参数以Post event形式发出到hal 层中,hal层接收到camera 驱动post 上来的event,来调用对应的逻辑,如果要操作sensor ,刚调用对应的 video设备就可以了。


接下来,我们依次来看看 msm_cam、sensor、v4l2 这几部分的代码逻辑:

2. msm-cam 驱动

msm-cam是在dts 中定义的,
\kernel\msm-4.4\arch\arm\boot\dts\qcom\sdm660-camera.dtsi中我们看到如下代码:

	qcom,msm-cam@ca00000 {
		compatible = "qcom,msm-cam";
		reg = <0xca00000 0x4000>;
		reg-names = "msm-cam";
		status = "ok";
		bus-vectors = "suspend", "svs", "nominal", "turbo";
		qcom,bus-votes = <0 150000000 320000000 320000000>;
		qcom,gpu-limit = <700000000>;
	};

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

查找代码,我们可以看到,其注册的地方在\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\msm.c
可以看出,msm-cam 是以平台驱动的形式注册在kernel 中。

static const struct of_device_id msm_dt_match[] = {
	{.compatible = "qcom,msm-cam"},
	{}
};
MODULE_DEVICE_TABLE(of, msm_dt_match);

static struct platform_driver msm_driver = {
.probe = msm_probe,
.driver = {
.name = “msm”,
.owner = THIS_MODULE,
.of_match_table = msm_dt_match,
},
};

static int __init msm_init(void)
{
return platform_driver_register(&msm_driver);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

初始化注册成功后,会调用msm_probe函数,在该函数中,主要工作如下:

  1. 初始化 v4l2_device、video_device 、media_device 结构体并分配好KERNEL 内存。
  2. 注册 media_device 、v4l2_device、video_device 设备。
  3. 创建好 camera debug root fs
@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\msm.c

static struct v4l2_device *msm_v4l2_dev; // 初始化一个 v4l2_device 类型的结构体

static int msm_probe(struct platform_device pdev)
{
struct msm_video_device pvdev = NULL;
static struct dentry *cam_debugfs_root;

<span class="token comment">// 1. 初始化一个 v4l2_device 类型的结构体,并分配好结构体内存</span>
msm_v4l2_dev <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>msm_v4l2_dev<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
pvdev <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_video_device<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2. 分配 video_device 结构体内存</span>
pvdev<span class="token operator">-&gt;</span>vdev <span class="token operator">=</span> <span class="token function">video_device_alloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
<span class="token comment">// ---&gt; kzalloc(sizeof(struct video_device), GFP_KERNEL); </span>

<span class="token comment">// 3. 分配 media_device 结构体内存</span>
msm_v4l2_dev<span class="token operator">-&gt;</span>mdev <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> media_device<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">strlcpy</span><span class="token punctuation">(</span>msm_v4l2_dev<span class="token operator">-&gt;</span>mdev<span class="token operator">-&gt;</span>model<span class="token punctuation">,</span> MSM_CONFIGURATION_NAME<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>msm_v4l2_dev<span class="token operator">-&gt;</span>mdev<span class="token operator">-&gt;</span>model<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// msm_config</span>
msm_v4l2_dev<span class="token operator">-&gt;</span>mdev<span class="token operator">-&gt;</span>dev <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">(</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 4. 注册 media_device , 使用的 v4l2 </span>
rc <span class="token operator">=</span> <span class="token function">media_device_register</span><span class="token punctuation">(</span>msm_v4l2_dev<span class="token operator">-&gt;</span>mdev<span class="token punctuation">)</span><span class="token punctuation">;</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>entity<span class="token punctuation">.</span>type <span class="token operator">=</span> MEDIA_ENT_T_DEVNODE_V4L<span class="token punctuation">;</span>		 <span class="token comment">// V4L</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>entity<span class="token punctuation">.</span>group_id <span class="token operator">=</span> QCAMERA_VNODE_GROUP_ID<span class="token punctuation">;</span>   <span class="token comment">// #define QCAMERA_VNODE_GROUP_ID 2</span>

msm_v4l2_dev<span class="token operator">-&gt;</span>notify <span class="token operator">=</span> msm_sd_notify<span class="token punctuation">;</span>  <span class="token comment">// 用于发现对应的 subdev</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>v4l2_dev <span class="token operator">=</span> msm_v4l2_dev<span class="token punctuation">;</span>

<span class="token comment">// 5. 设置父设备为 pdev-&gt;dev (也就是 qcom,msm-cam 的设备信息)</span>
rc <span class="token operator">=</span> <span class="token function">v4l2_device_register</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">)</span><span class="token punctuation">,</span> pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>v4l2_dev<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 6. 注册 video_device设备 </span>
<span class="token function">strlcpy</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> <span class="token string">"msm-config"</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>release  <span class="token operator">=</span> video_device_release<span class="token punctuation">;</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>fops     <span class="token operator">=</span> <span class="token operator">&amp;</span>msm_fops<span class="token punctuation">;</span>			<span class="token comment">// 配置 video_device 的字符设备操作函数</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>ioctl_ops <span class="token operator">=</span> <span class="token operator">&amp;</span>g_msm_ioctl_ops<span class="token punctuation">;</span>	<span class="token comment">// 配置 v4l2 IOCTRL</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>minor     <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>vfl_type  <span class="token operator">=</span> VFL_TYPE_GRABBER<span class="token punctuation">;</span>
rc <span class="token operator">=</span> <span class="token function">video_register_device</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token punctuation">,</span> VFL_TYPE_GRABBER<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 7. 将当前 msm_video_device 结构体设为私有数据 </span>
<span class="token function">video_set_drvdata</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token punctuation">,</span> pvdev<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 8. 分配  msm_queue_head 结构体内存</span>
msm_session_q <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>msm_session_q<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">msm_init_queue</span><span class="token punctuation">(</span>msm_session_q<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 9. 创建 camera 调试目录</span>
cam_debugfs_root <span class="token operator">=</span> <span class="token function">debugfs_create_dir</span><span class="token punctuation">(</span>MSM_CAM_LOGSYNC_FILE_BASEDIR<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

rc <span class="token operator">=</span> <span class="token function">cam_ahb_clk_init</span><span class="token punctuation">(</span>pdev<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">.</span>of_node<span class="token punctuation">,</span>
	<span class="token string">"qcom,gpu-limit"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>gpu_limit<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">goto</span> probe_end<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

2.1 struct v4l2_device 结构体描述

@ \kernel\msm-4.4\include\media\v4l2-device.h

struct v4l2_device {
/* dev->driver_data points to this struct.
Note: dev might be NULL if there is no parent device
as is the case with e.g. ISA devices. /

struct device dev;
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_device mdev;
#endif
/ used to keep track of the registered subdevs /
struct list_head subdevs;
/ lock this struct; can be used by the driver as well if this
struct is embedded into a larger struct. /

spinlock_t lock;
/ unique device name, by default the driver name + bus ID /
char name[V4L2_DEVICE_NAME_SIZE];
/ notify callback called by some sub-devices. /
void (notify)(struct v4l2_subdev sd,
unsigned int notification, void arg);
/* The control handler. May be NULL. /
struct v4l2_ctrl_handler ctrl_handler;
/* Device’s priority state /
struct v4l2_prio_state prio;
/ Keep track of the references to this struct. /
struct kref ref;
/ Release function that is called when the ref count goes to 0. /
void (release)(struct v4l2_device *v4l2_dev);
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.2 struct msm_video_device 结构体描述

@ \kernel\msm-4.4\drivers\media\platform\msm\camera_v2\msm.h

struct msm_video_device {
struct video_device *vdev;
atomic_t opened;
struct mutex video_drvdata_mutex;
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.3 struct media_device 结构体描述

struct media_device {
	/* dev->driver_data points to this struct. */
	struct device *dev;				// Parent device
	struct media_devnode devnode;	// Media device node
<span class="token keyword">char</span> model<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span><span class="token punctuation">;</span>					<span class="token comment">// Device model name</span>
<span class="token keyword">char</span> serial<span class="token punctuation">[</span><span class="token number">40</span><span class="token punctuation">]</span><span class="token punctuation">;</span>				<span class="token comment">// Device serial number (optional)</span>
<span class="token keyword">char</span> bus_info<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span><span class="token punctuation">;</span>				<span class="token comment">// Unique and stable device location identifier</span>
u32 hw_revision<span class="token punctuation">;</span>				<span class="token comment">// Hardware device revision</span>
u32 driver_version<span class="token punctuation">;</span>				<span class="token comment">// Device driver version</span>

u32 entity_id<span class="token punctuation">;</span>					<span class="token comment">// ID of the next entity to be registered</span>
<span class="token keyword">struct</span> list_head entities<span class="token punctuation">;</span>		<span class="token comment">// List of registered entities</span>

<span class="token comment">/* Protects the entities list */</span>
spinlock_t lock<span class="token punctuation">;</span>				<span class="token comment">// Entities list lock</span>
<span class="token comment">/* Serializes graph operations. */</span>
<span class="token keyword">struct</span> mutex graph_mutex<span class="token punctuation">;</span>		<span class="token comment">// Entities graph operation lock</span>

<span class="token keyword">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>link_notify<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">struct</span> media_link <span class="token operator">*</span>link<span class="token punctuation">,</span> u32 flags<span class="token punctuation">,</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> notification<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Link state change notification callback</span>

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3. Sensor 驱动

还是从 dts 开始看,前面我们配置camera sensor时,节点为 compatible = "qcom,camera";
对应代码在\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_driver.c

在代码中,将 qcom,camera注册在平台驱动中,并注册对应的sensor i2c 驱动。

@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_driver.c

static const struct of_device_id msm_sensor_driver_dt_match[] = {
{.compatible = “qcom,camera”},
{}
};

MODULE_DEVICE_TABLE(of, msm_sensor_driver_dt_match);

static struct platform_driver msm_sensor_platform_driver = {
.probe = msm_sensor_driver_platform_probe,
.driver = {
.name = “qcom,camera”,
.owner = THIS_MODULE,
.of_match_table = msm_sensor_driver_dt_match,
},
.remove = msm_sensor_platform_remove,
};

static struct i2c_driver msm_sensor_driver_i2c = {
.id_table = i2c_id,
.probe = msm_sensor_driver_i2c_probe,
.remove = msm_sensor_driver_i2c_remove,
.driver = {
.name = SENSOR_DRIVER_I2C,
},
};

static int __init msm_sensor_driver_init(void)
{
rc = platform_driver_register(&msm_sensor_platform_driver);
rc = i2c_add_driver(&msm_sensor_driver_i2c);
return rc;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

3.1 平台驱动probe函数 msm_sensor_driver_platform_probe()

msm_sensor_driver_platform_probe函数中,其主要工作如下:

  1. 创建并分配 msm_sensor_ctrl_t结构体内存。
  2. sensor device type初始化为 MSM_CAMERA_PLATFORM_DEVICE
  3. 解析 节点为 compatible = "qcom,camera";的 dts 内容
  4. 解析dts 中配置的camera clk 信息
    clock-names = "cam_src_clk", "cam_clk";
    qcom,clock-rates = <24000000 0>;
@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_driver.c

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

<span class="token comment">// 1. 创建并分配 msm_sensor_ctrl_t 结构体内存。</span>
<span class="token comment">/* Create sensor control structure */</span>
s_ctrl <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">platform_set_drvdata</span><span class="token punctuation">(</span>pdev<span class="token punctuation">,</span> s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 2. 将sensor device type 初始化为 MSM_CAMERA_PLATFORM_DEVICE</span>
<span class="token comment">/* Initialize sensor device type */</span>
s_ctrl<span class="token operator">-&gt;</span>sensor_device_type <span class="token operator">=</span> MSM_CAMERA_PLATFORM_DEVICE<span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>of_node <span class="token operator">=</span> pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">.</span>of_node<span class="token punctuation">;</span>

<span class="token comment">/*fill in platform device*/</span>
s_ctrl<span class="token operator">-&gt;</span>pdev <span class="token operator">=</span> pdev<span class="token punctuation">;</span>

<span class="token comment">// 3. 解析 节点为  compatible = "qcom,camera"; 的 dts 内容</span>
rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_parse</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">|</span>	<span class="token keyword">static</span> int32_t <span class="token function">msm_sensor_driver_parse</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_sensor_ctrl_t <span class="token operator">*</span>s_ctrl<span class="token punctuation">)</span>
<span class="token operator">|</span>	<span class="token punctuation">{</span>
<span class="token operator">|</span>		<span class="token comment">/* Allocate memory for sensor_i2c_client */</span>
<span class="token operator">|</span>		s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">|</span>	
<span class="token operator">|</span>		<span class="token comment">/* Parse dt information and store in sensor control structure */</span>
<span class="token operator">|</span>		rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_get_dt_data</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 解析Camera DTS 节点,详见 Chapter 3.2</span>
<span class="token operator">|</span>
<span class="token operator">|</span>		<span class="token comment">/* Initilize v4l2 subdev info */</span>
<span class="token operator">|</span>		s_ctrl<span class="token operator">-&gt;</span>sensor_v4l2_subdev_info <span class="token operator">=</span> msm_sensor_driver_subdev_info<span class="token punctuation">;</span>
<span class="token operator">|</span>		s_ctrl<span class="token operator">-&gt;</span>sensor_v4l2_subdev_info_size <span class="token operator">=</span> <span class="token function">ARRAY_SIZE</span><span class="token punctuation">(</span>msm_sensor_driver_subdev_info<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">|</span>	
<span class="token operator">|</span>		<span class="token comment">/* Initialize default parameters */</span>
<span class="token operator">|</span>		rc <span class="token operator">=</span> <span class="token function">msm_sensor_init_default_params</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 初始化默认参数</span>
<span class="token operator">|</span>
<span class="token operator">|</span>		<span class="token comment">// 将 sensor ctrl 节构体保存在 g_sctrl 数组中。</span>
<span class="token operator">|</span>		<span class="token comment">/* Store sensor control structure in static database */</span>
<span class="token operator">|</span>		g_sctrl<span class="token punctuation">[</span>s_ctrl<span class="token operator">-&gt;</span>id<span class="token punctuation">]</span> <span class="token operator">=</span> s_ctrl<span class="token punctuation">;</span>
<span class="token operator">|</span>		<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"g_sctrl[%d] %pK"</span><span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>id<span class="token punctuation">,</span> g_sctrl<span class="token punctuation">[</span>s_ctrl<span class="token operator">-&gt;</span>id<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">|</span>		<span class="token keyword">return</span> rc<span class="token punctuation">;</span>
<span class="token operator">|</span>	<span class="token punctuation">}</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 4. 解析dts 中配置的camera clk 信息</span>
<span class="token comment">// 解析 clock-names = "cam_src_clk", "cam_clk";</span>
<span class="token comment">// 解析 qcom,clock-rates = &lt;24000000 0&gt;;</span>
<span class="token comment">/* Get clocks information */</span>
rc <span class="token operator">=</span> <span class="token function">msm_camera_get_clk_info</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>pdev<span class="token punctuation">,</span> <span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>clk_info<span class="token punctuation">,</span>
	<span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>clk_ptr<span class="token punctuation">,</span> <span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>clk_info_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
<span class="token operator">|</span>	<span class="token comment">// @\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\common\cam_soc_api.c</span>
<span class="token operator">|</span>	rc <span class="token operator">=</span> <span class="token function">msm_camera_get_clk_info_internal</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">,</span> clk_info<span class="token punctuation">,</span> clk_ptr<span class="token punctuation">,</span> num_clk<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">/* Fill platform device id*/</span>
pdev<span class="token operator">-&gt;</span>id <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>id<span class="token punctuation">;</span>

<span class="token comment">/* Fill device in power info */</span>
s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>dev <span class="token operator">=</span> <span class="token operator">&amp;</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

3.2 解析Camera DTS 节点 msm_sensor_driver_get_dt_data()

在该函数中主要是对dts 中配置的camera 节点解析,工作如下:

  1. 初始化 msm_camera_sensor_board_info结构体并分配对应的内存
  2. 解析 cell-index = <0>,以此为camera 数组计数 id
  3. 检测 camera id 是否大于系统最大支持数量
  4. 判断 msm_sensor_ctrl 全局数组中当前id 是否已经初始化
  5. 解析Camera 外设信息,包括 "qcom,actuator-src"、"qcom,ois-src"、"qcom,eeprom-src"、"qcom,led-flash-src"、"qcom,csiphy-sd-index"
  6. 解析Camera 电压配置,qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig", "cam_vaf";
  7. 解析Camera GPIO配置
    解析 "qcom,gpio-req-tbl-num"、"qcom,gpio-req-tbl-flags"、"qcom,gpio-req-tbl-label"
    如果配置了使用gpio 供电的话,则在此初化始化,"qcom,gpio-vana"、"qcom,gpio-vio"、"qcom,gpio-vaf"、"qcom,gpio-vdig"、"qcom,gpio-reset"、"qcom,gpio-standby"、"qcom,gpio-flash-en"
  8. 解析I2C master ,"qcom,cci-master = <0>;"
  9. 解析摄像头旋转角度"qcom,mount-angle",如果没有配置默认设置为0
  10. 解析sensor 前后摄"qcom,sensor-position"
  11. 解析"qcom,sensor-mode"
@ \kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_driver.c

static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t s_ctrl)
{
int32_t rc = 0, i = 0;
struct msm_camera_sensor_board_info sensordata = NULL;
struct device_node *of_node = s_ctrl->of_node;
uint32_t cell_id;

<span class="token comment">// 1. 初始化 msm_camera_sensor_board_info 结构体并分配对应的内存</span>
s_ctrl<span class="token operator">-&gt;</span>sensordata <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>sensordata<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
sensordata <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token punctuation">;</span>

<span class="token comment">// 2. 解析 cell-index = &lt;0&gt;,以此为camera 数组计数 id</span>
<span class="token comment">/** Read cell index - this cell index will be the camera slot where this camera will be mounted */</span>
rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"cell-index"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>cell_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>id <span class="token operator">=</span> cell_id<span class="token punctuation">;</span>

<span class="token comment">// 3. 检测camera id是否大于系统最大支持数量</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>cell_id <span class="token operator">&gt;=</span> MAX_CAMERAS<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"failed: invalid cell_id %d"</span><span class="token punctuation">,</span> cell_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
	rc <span class="token operator">=</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span>
	<span class="token keyword">goto</span> FREE_SENSOR_DATA<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 4. 判断全msm_sensor_ctrl 全局数组中当前id 是否已经初始化</span>
<span class="token comment">/* Check whether g_sctrl is already filled for this cell_id */</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>g_sctrl<span class="token punctuation">[</span>cell_id<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"failed: sctrl already filled for cell_id %d"</span><span class="token punctuation">,</span> cell_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
	rc <span class="token operator">=</span> <span class="token operator">-</span>EINVAL<span class="token punctuation">;</span>
	<span class="token keyword">goto</span> FREE_SENSOR_DATA<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 5. 解析Camera 外设信息,包括 "qcom,actuator-src"、"qcom,ois-src"、"qcom,eeprom-src"、</span>
<span class="token comment">// 			"qcom,led-flash-src"、"qcom,csiphy-sd-index"</span>
<span class="token comment">/* Read subdev info */</span>
rc <span class="token operator">=</span> <span class="token function">msm_sensor_get_sub_module_index</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>	<span class="token comment">//@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\io\msm_camera_dt_util.c</span>
<span class="token operator">+</span>	<span class="token keyword">int</span> <span class="token function">msm_sensor_get_sub_module_index</span><span class="token punctuation">(</span><span class="token keyword">struct</span> device_node <span class="token operator">*</span>of_node<span class="token punctuation">,</span> <span class="token keyword">struct</span>  msm_sensor_info_t <span class="token operator">*</span><span class="token operator">*</span>s_info<span class="token punctuation">)</span>
<span class="token operator">+</span>	<span class="token punctuation">{</span>
<span class="token operator">+</span>		<span class="token keyword">struct</span> msm_sensor_info_t <span class="token operator">*</span>sensor_info<span class="token punctuation">;</span>
<span class="token operator">+</span>		sensor_info <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		
<span class="token operator">+</span>		<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> SUB_MODULE_MAX<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>			sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">/* Subdev expose additional interface for same sub module*/</span>
<span class="token operator">+</span>			sensor_info<span class="token operator">-&gt;</span>subdev_intf<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token punctuation">}</span>
<span class="token operator">+</span>		src_node <span class="token operator">=</span> <span class="token function">of_parse_phandle</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,actuator-src"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_ACTUATOR<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token operator">+</span>		
<span class="token operator">+</span>		src_node <span class="token operator">=</span> <span class="token function">of_parse_phandle</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,ois-src"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_OIS<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token operator">+</span>		
<span class="token operator">+</span>		src_node <span class="token operator">=</span> <span class="token function">of_parse_phandle</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,eeprom-src"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_EEPROM<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token operator">+</span>	
<span class="token operator">+</span>		src_node <span class="token operator">=</span> <span class="token function">of_parse_phandle</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,led-flash-src"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_LED_FLASH<span class="token punctuation">]</span> <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token operator">+</span>		
<span class="token operator">+</span>		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">of_get_property</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,csiphy-sd-index"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>count<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>			count <span class="token operator">/</span><span class="token operator">=</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>uint32_t<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			val_array <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>uint32_t<span class="token punctuation">)</span> <span class="token operator">*</span> count<span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32_array</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,csiphy-sd-index"</span><span class="token punctuation">,</span> val_array<span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>				sensor_info<span class="token operator">-&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_CSIPHY <span class="token operator">+</span> i<span class="token punctuation">]</span> <span class="token operator">=</span> val_array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>				<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s csiphy_core[%d] = %d\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> val_array<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			<span class="token punctuation">}</span>
<span class="token operator">+</span>		<span class="token comment">//.... 省略一部分解析代码</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 6. 解析Camera 电压配置, qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig", "cam_vaf";</span>
<span class="token comment">/* Read vreg information */</span>
rc <span class="token operator">=</span> <span class="token function">msm_camera_get_dt_vreg_data</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>cam_vreg<span class="token punctuation">,</span> <span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>num_vreg<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>	<span class="token comment">//@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\io\msm_camera_dt_util.c</span>
<span class="token operator">+</span>	<span class="token keyword">int</span> <span class="token function">msm_camera_get_dt_vreg_data</span><span class="token punctuation">(</span><span class="token keyword">struct</span> device_node <span class="token operator">*</span>of_node<span class="token punctuation">,</span> <span class="token keyword">struct</span> camera_vreg_t <span class="token operator">*</span><span class="token operator">*</span>cam_vreg<span class="token punctuation">,</span> <span class="token keyword">int</span> <span class="token operator">*</span>num_vreg<span class="token punctuation">)</span>
<span class="token operator">+</span>	<span class="token punctuation">{</span>
<span class="token operator">+</span>		count <span class="token operator">=</span> <span class="token function">of_property_count_strings</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,cam-vreg-name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s qcom,cam-vreg-name count %d\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		vreg <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>vreg<span class="token punctuation">)</span> <span class="token operator">*</span> count<span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">*</span>cam_vreg <span class="token operator">=</span> vreg<span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">*</span>num_vreg <span class="token operator">=</span> count<span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_string_index</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,cam-vreg-name"</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span> <span class="token operator">&amp;</span>vreg<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>reg_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s reg_name[%d] = %s\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span>vreg<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>reg_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token punctuation">}</span>
<span class="token operator">+</span>		<span class="token comment">//.... 省略一部分解析代码</span>
<span class="token operator">+</span>	<span class="token punctuation">}</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 7. 解析Camera GPIO配置</span>
<span class="token comment">/* Read gpio information */</span>
rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_get_gpio_data</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>gpio_conf<span class="token punctuation">)</span><span class="token punctuation">,</span> of_node<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>	<span class="token comment">//@\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\io\msm_camera_dt_util.c</span>
<span class="token operator">+</span>	int32_t <span class="token function">msm_sensor_driver_get_gpio_data</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_camera_gpio_conf <span class="token operator">*</span><span class="token operator">*</span>gpio_conf<span class="token punctuation">,</span> <span class="token keyword">struct</span> device_node <span class="token operator">*</span>of_node<span class="token punctuation">)</span>
<span class="token operator">+</span>	<span class="token punctuation">{</span>
<span class="token operator">+</span>		uint16_t                    <span class="token operator">*</span>gpio_array <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token keyword">struct</span> msm_camera_gpio_conf <span class="token operator">*</span>gconf <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		gpio_array_size <span class="token operator">=</span> <span class="token function">of_gpio_count</span><span class="token punctuation">(</span>of_node<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		gconf <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_camera_gpio_conf<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token operator">+</span>		<span class="token operator">*</span>gpio_conf <span class="token operator">=</span> gconf<span class="token punctuation">;</span>
<span class="token operator">+</span>	
<span class="token operator">+</span>		<span class="token comment">// 解析 "qcom,gpio-req-tbl-num"、"qcom,gpio-req-tbl-flags"、"qcom,gpio-req-tbl-label"</span>
<span class="token operator">+</span>		rc <span class="token operator">=</span> <span class="token function">msm_camera_get_dt_gpio_req_tbl</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> gconf<span class="token punctuation">,</span> gpio_array<span class="token punctuation">,</span> gpio_array_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	<span class="token function">of_get_property</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-req-tbl-num"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>count<span class="token punctuation">)</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">of_property_read_u32_array</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-req-tbl-num"</span><span class="token punctuation">,</span> val_array<span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	rc <span class="token operator">=</span> <span class="token function">of_property_read_u32_array</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-req-tbl-flags"</span><span class="token punctuation">,</span> val_array<span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> count<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>		<span class="token operator">+</span>		rc <span class="token operator">=</span> <span class="token function">of_property_read_string_index</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span><span class="token string">"qcom,gpio-req-tbl-label"</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span><span class="token operator">&amp;</span>gconf<span class="token operator">-&gt;</span>cam_gpio_req_tbl<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>label<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">+</span>		<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s cam_gpio_req_tbl[%d].label = %s\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> i<span class="token punctuation">,</span>gconf<span class="token operator">-&gt;</span>cam_gpio_req_tbl<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>label<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	<span class="token punctuation">}</span>
<span class="token operator">+</span>		<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token operator">+</span>		<span class="token operator">+</span>	如果配置了使用gpio 供电的话,则在此初化始化, <span class="token string">"qcom,gpio-vana"</span>、<span class="token string">"qcom,gpio-vio"</span>、<span class="token string">"qcom,gpio-vaf"</span>、<span class="token string">"qcom,gpio-vdig"</span>、<span class="token string">"qcom,gpio-reset"</span>、<span class="token string">"qcom,gpio-standby"</span>、<span class="token string">"qcom,gpio-flash-en"</span>
<span class="token operator">+</span>		rc <span class="token operator">=</span> <span class="token function">msm_camera_init_gpio_pin_tbl</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> gconf<span class="token punctuation">,</span> gpio_array<span class="token punctuation">,</span>gpio_array_size<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-vana"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_VANA<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-vio"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_VIO<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-vaf"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_VAF<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-vdig"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_VDIG<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-reset"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_RESET<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-standby"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_STANDBY<span class="token punctuation">]</span> <span class="token operator">=</span>gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-af-pwdm"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_AF_PWDM<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,gpio-flash-en"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			gconf<span class="token operator">-&gt;</span>gpio_num_info<span class="token operator">-&gt;</span>gpio_num<span class="token punctuation">[</span>SENSOR_GPIO_FL_EN<span class="token punctuation">]</span> <span class="token operator">=</span> gpio_array<span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>			<span class="token comment">//.... 省略一部分解析代码</span>
<span class="token operator">+</span>		<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token operator">+</span>	<span class="token punctuation">}</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 8. 解析I2C master ,"qcom,cci-master = &lt;0&gt;;"</span>
<span class="token comment">/* Get CCI master */</span>
rc <span class="token operator">=</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,cci-master"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>cci_i2c_master<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"qcom,cci-master %d, rc %d"</span><span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>cci_i2c_master<span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 9. 解析摄像头旋转角度"qcom,mount-angle",如果没有配置默认设置为0</span>
<span class="token comment">/* Get mount angle */</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">&gt;</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,mount-angle"</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>sensor_mount_angle<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">/* Invalidate mount angle flag */</span>
	sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>is_mount_angle_valid <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
	sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>sensor_mount_angle <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
	sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>is_mount_angle_valid <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s qcom,mount-angle %d\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>sensor_mount_angle<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 10. 解析sensor 前后摄"qcom,sensor-position"</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">&gt;</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,sensor-position"</span><span class="token punctuation">,</span><span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>position<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s:%d Invalid sensor position\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> <span class="token constant">__LINE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>position <span class="token operator">=</span> INVALID_CAMERA_B<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 11. 解析sensor-mode</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">&gt;</span> <span class="token function">of_property_read_u32</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,sensor-mode"</span><span class="token punctuation">,</span>
	<span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>modes_supported<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s:%d Invalid sensor mode supported\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span> <span class="token constant">__LINE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>modes_supported <span class="token operator">=</span> CAMERA_MODE_INVALID<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">/* Get vdd-cx regulator */</span>
<span class="token comment">/*Optional property, don't return error if absent */</span>
<span class="token function">of_property_read_string</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span> <span class="token string">"qcom,vdd-cx-name"</span><span class="token punctuation">,</span><span class="token operator">&amp;</span>sensordata<span class="token operator">-&gt;</span>misc_regulator<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"qcom,misc_regulator %s"</span><span class="token punctuation">,</span> sensordata<span class="token operator">-&gt;</span>misc_regulator<span class="token punctuation">)</span><span class="token punctuation">;</span>

s_ctrl<span class="token operator">-&gt;</span>set_mclk_23880000 <span class="token operator">=</span> <span class="token function">of_property_read_bool</span><span class="token punctuation">(</span>of_node<span class="token punctuation">,</span><span class="token string">"qcom,mclk-23880000"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"%s qcom,mclk-23880000 = %d\n"</span><span class="token punctuation">,</span> <span class="token constant">__func__</span><span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>set_mclk_23880000<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174

3.2.1 msm_camera_sensor_board_info 结构体描述

在msm_camera_sensor_board_info 中保存了所有camera 及硬件相关的name及参数。

//@ \kernel\msm-4.4\include\soc\qcom\camera2.h
struct msm_camera_sensor_board_info {
	const char *sensor_name;		// camera sensor name
	const char *eeprom_name;		// eeprom name
	const char *actuator_name;		// actuator name
	const char *ois_name;			// ois name
	const char *flash_name;			// flashlight name
	const char *special_support_sensors[MAX_SPECIAL_SUPPORT_SIZE];
	int32_t special_support_size;
	struct msm_camera_slave_info *slave_info;	// i2c addr
	struct msm_camera_csi_lane_params *csi_lane_params;
	struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;	
	struct msm_actuator_info *actuator_info;
	struct msm_sensor_info_t *sensor_info;
	const char *misc_regulator;
	struct msm_camera_power_ctrl_t power_info;
	struct msm_camera_sensor_slave_info *cam_slave_info;
};

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
3.2.2 Camera 支持的外设类型 sensor_sub_module_t
@ \kernel\msm-4.4\include\uapi\media\msm_cam_sensor.h
enum sensor_sub_module_t {
	SUB_MODULE_SENSOR,
	SUB_MODULE_CHROMATIX,
	SUB_MODULE_ACTUATOR,
	SUB_MODULE_EEPROM,
	SUB_MODULE_LED_FLASH,
	SUB_MODULE_STROBE_FLASH,
	SUB_MODULE_CSID,
	SUB_MODULE_CSID_3D,
	SUB_MODULE_CSIPHY,
	SUB_MODULE_CSIPHY_3D,
	SUB_MODULE_OIS,
	SUB_MODULE_EXT,
	SUB_MODULE_IR_LED,
	SUB_MODULE_IR_CUT,
	SUB_MODULE_MAX,
};

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.3 【重点】全局CameraSensorCtrol数组g_sctrl

g_sctrl 是静态全局的一个msm_sensor_ctrl_t * 结构体指针数组,其定义如下:

/* Static declaration */
static struct msm_sensor_ctrl_t *g_sctrl[MAX_CAMERAS];

 
 
  • 1
  • 2

前面我们在配置dts 时也发现了,通常我们要配置的camera数量是大于1的,前面代码中,我们配置了3个Camera,两个后摄,一个前摄。而这三个camera dts 中的节点都是一样的"qcom,camera"
可以看出,驱动和设备会匹配三次,换句话说,也就是 msm_sensor_driver_platform_probe()函数会走三次,每次传递的dts节点内容是不一样的,三个camera都会依次probe 一次,
从而,当probe 完毕后,会保存三个struct msm_sensor_ctrl_t *结构体的数据保存在全局 g_sctrl 中。

至此,我们代码中,就把dts 的内容成功的转化为了msm_sensor_ctrl_t结构体保存在 全局 g_sctrl 中。


3.4 【重点】摄像头probe 函数 msm_sensor_driver_probe()

本章3.1 中我们分析过了 平台驱动probe函数 msm_sensor_driver_platform_probe(),这个函数主要作用还是解析DTS,但并不会真正probe camera sensor。
那问题来了,camera sensor probe 是在什么时候呢?

其实,camera probe 并不是和其他kernerl 驱动一样,在初始化时就probe,而是通过hal 层下发 probe 指令来控制probe 的。

3.4.1 hal层函数 module_sensor_init()

hal层代码位于 \vendor\qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\sensors\module\module_sensor.c

//@\vendor\qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\sensors\module\module_sensor.c
mct_module_t *module_sensor_init(const char *name)
{
	......
	/* module_sensor_probe_sensors */
 	ret = sensor_init_probe(module_ctrl);
<span class="token comment">/* find all the actuator, etc with sensor */</span>
ret <span class="token operator">=</span> <span class="token function">module_sensor_find_other_subdev</span><span class="token punctuation">(</span>module_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* Init sensor modules */</span>
ret <span class="token operator">=</span> <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensors_subinit<span class="token punctuation">,</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* intiialize the eeprom */</span>
ret <span class="token operator">=</span> <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_init_eeprom<span class="token punctuation">,</span>module_ctrl<span class="token operator">-&gt;</span>eebin_hdl<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* Create chromatix manager */</span>
ret <span class="token operator">=</span> <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_init_chromatix<span class="token punctuation">,</span> module_ctrl<span class="token operator">-&gt;</span>eebin_hdl<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* Initialize dual cam stream mutex */</span>
<span class="token function">pthread_mutex_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>module_ctrl<span class="token operator">-&gt;</span>dual_cam_mutex<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3.4.2 hal层函数 sensor_init_probe()

上层代码逻辑我们后续会详细分析,并不是我们本章的重点,我们重点关注sensor_init_probe(),其内容如下:

sensor_init_eebin_probe()中,我们可以看出,知道camera 数量后,在for循环中,依次调用 sensor_probe()函数初始化每个camera,我们当前代码中有三个camera,这面就会调用三次sensor_probe()
至于 hal 层中又是如何知道我们是三个camera的,后续我们分析到hal 层再说吧。

/** sensor_init_probe: probe available sensors
 *
 *  @module_ctrl: sensor ctrl pointer
 *
 *  Return: 0 for success and negative error on failure
 *
 *  1) Find sensor_init subdev and it
 *  2) Open EEPROM subdev and check whether any sensor library
 *  is present in EEPROM
 *  3) Open sensor libraries present in dumped firware location
 *  4) Check library version of EEPROM and dumped firmware
 *  5) Load latest of both
 *  6) Pass slave information, power up and probe sensors
 *  7) If probe succeeds, create video node and sensor subdev
 *  8) Repeat step 2-8 for all sensor libraries present in
 *  EEPROM
 *  9) Repeat step 6-8 for all sensor libraries present in
 *  absolute path
 **/

boolean sensor_init_probe(module_sensor_ctrl_t *module_ctrl)
{
......
ret = sensor_init_eebin_probe(module_ctrl, sd_fd);
......
}

static boolean sensor_init_eebin_probe(module_sensor_ctrl_t *module_ctrl,int32_t sd_fd)
{
SLOW(“Enter”);
bin_ctl.cmd = EEPROM_BIN_GET_NUM_DEV;
bin_ctl.ctl.q_num.type = EEPROM_BIN_LIB_SENSOR;
bin_ctl.ctl.q_num.num_devs = 0;
eebin_interface_control(module_ctrl->eebin_hdl, &bin_ctl);

num_devs <span class="token operator">=</span> bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>q_num<span class="token punctuation">.</span>num_devs<span class="token punctuation">;</span>

<span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"num_devs:%d"</span><span class="token punctuation">,</span> num_devs<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> num_devs<span class="token punctuation">;</span> i<span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
	bin_ctl<span class="token punctuation">.</span>cmd <span class="token operator">=</span> EEPROM_BIN_GET_DEV_DATA<span class="token punctuation">;</span>
	bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>dev_data<span class="token punctuation">.</span>type <span class="token operator">=</span> EEPROM_BIN_LIB_SENSOR<span class="token punctuation">;</span>
	bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>dev_data<span class="token punctuation">.</span>num <span class="token operator">=</span> i<span class="token punctuation">;</span>
	rc <span class="token operator">=</span> <span class="token function">eebin_interface_control</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-&gt;</span>eebin_hdl<span class="token punctuation">,</span> <span class="token operator">&amp;</span>bin_ctl<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span>
  		<span class="token keyword">continue</span><span class="token punctuation">;</span>
	ret <span class="token operator">=</span> <span class="token function">sensor_probe</span><span class="token punctuation">(</span>module_ctrl<span class="token punctuation">,</span>
                   sd_fd<span class="token punctuation">,</span>
                   bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>dev_data<span class="token punctuation">.</span>name<span class="token punctuation">,</span>
                   bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>dev_data<span class="token punctuation">.</span>path<span class="token punctuation">,</span>
                   <span class="token constant">NULL</span><span class="token punctuation">,</span>
                   FALSE<span class="token punctuation">,</span>
                   FALSE<span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token keyword">if</span> <span class="token punctuation">(</span>ret <span class="token operator">==</span> FALSE<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  		<span class="token function">SINFO</span><span class="token punctuation">(</span><span class="token string">"failed: to load %s"</span><span class="token punctuation">,</span> bin_ctl<span class="token punctuation">.</span>ctl<span class="token punctuation">.</span>dev_data<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>

}

SLOW(“Exit”);
return TRUE;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

3.4.3 hal层函数 sensor_probe() 下发 CFG_SINIT_PROBE

进入 sensor_probe()函数:
在函数中可以看出,首先会调用 sensor_load_library()加载vendor 中camera sensor 的库文件。
接着通过 IOCTRL 向通过下发 CFG_SINIT_PROBE消息,通知驱动层作probe 初始化。

/** sensor_probe: probe available sensors
 *  @fd: sensor_init fd
 *  @sensor_name: sensor name
 *  Return: TRUE for success and FALSE for failure
 *  1) Open sensor library
 *  2) Pass slave information, probe sensor
 *  3) If probe succeeds, create video node and sensor subdev is
 *  created in kernel
 **/
static boolean sensor_probe(module_sensor_ctrl_t *module_ctrl, int32_t fd, const char *sensor_name, char *path, struct xmlCameraConfigInfo *xmlConfig, boolean is_stereo_config, boolean bypass_video_node_creation)
{
	/* Load sensor library */
	rc = sensor_load_library(sensor_name, sensor_lib_params, path);
	......
 	/* Pass slave information to kernel and probe */
  	memset(&cfg, 0, sizeof(cfg));
  	cfg.cfgtype = CFG_SINIT_PROBE;
  	cfg.cfg.setting = slave_info;
  	if (ioctl(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
    	SINFO("[%s]CFG_SINIT_PROBE failed",sensor_name);
    	ret = FALSE;
    	goto ERROR;
  	}
<span class="token keyword">if</span> <span class="token punctuation">(</span>cfg<span class="token punctuation">.</span>probed_info<span class="token punctuation">.</span>session_id <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> FALSE <span class="token operator">==</span> bypass_video_node_creation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">SINFO</span><span class="token punctuation">(</span><span class="token string">"[%s] probe failed."</span><span class="token punctuation">,</span> sensor_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
 	ret <span class="token operator">=</span> FALSE<span class="token punctuation">;</span>
	<span class="token keyword">goto</span> ERROR<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">SHIGH</span><span class="token punctuation">(</span><span class="token string">"[%s] probe succeeded: session_id(%d) entity_name(%s)"</span><span class="token punctuation">,</span>sensor_name<span class="token punctuation">,</span> cfg<span class="token punctuation">.</span>probed_info<span class="token punctuation">.</span>session_id<span class="token punctuation">,</span> cfg<span class="token punctuation">.</span>entity_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

IOCTRL 命令定义如下:

/* sensor init structures and enums */
enum msm_sensor_init_cfg_type_t {
	CFG_SINIT_PROBE,
	CFG_SINIT_PROBE_DONE,
	CFG_SINIT_PROBE_WAIT_DONE,
};

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.4.4 Kernel Ioctl 函数 msm_sensor_init_subdev_ioctl()

上层IOCTRL 命令下发到kernerl 中,进入msm_sensor_init_subdev_ioctl()中,接着转发到msm_sensor_driver_cmd()中,调用 msm_sensor_driver_probe()函数

// @\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_init.c
static long msm_sensor_init_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	switch (cmd) {
	case VIDIOC_MSM_SENSOR_INIT_CFG:
		rc = msm_sensor_driver_cmd(s_init, arg);
		break;
	}
}

/* Static function definition /
static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t s_init, void *arg)
{
switch (cfg->cfgtype) {
case CFG_SINIT_PROBE:
mutex_lock(&s_init->imutex);
s_init->module_init_status = 0;
rc = msm_sensor_driver_probe(cfg->cfg.setting,
&cfg->probed_info,
cfg->entity_name);
mutex_unlock(&s_init->imutex);
if (rc < 0)
pr_err("%s failed (non-fatal) rc %d", func, rc);
break;
case CFG_SINIT_PROBE_DONE:
s_init->module_init_status = 1;
wake_up(&s_init->state_wait);
break;
case CFG_SINIT_PROBE_WAIT_DONE:
msm_sensor_wait_for_probe_done(s_init);
break;
return rc;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

3.4.5 probe函数 msm_sensor_driver_probe()

从上层开始下发probe 命令,至此正式开始probe 初始化 camera,代码如下:

  1. 初始化并分配 slave_info 内存
  2. 将上层下发的 slave_info保存在 slave_info32 中
  3. 将 slave_info32 中的信息保存到 slave_info中。
  4. 打印 slave info 信息
  5. 通过camera id 获取到对应的 camera sensor ctrol 信息,也就是对应的camera 的dts 信息。
  6. 检测sensor 是否已经probe 过了,如果不是,直接跳过if 进行probe
  7. 获取camera的power settting
  8. 初始化 msm_camera_slave_info 结构体变量 camera_info ,用于保存 camera 的信息
  9. 配置camera i2c 相关信息
  10. 往s_ctrl 中填充 上下电相关信息
  11. 解析该camera 中所有外设 dts 节点信息 "qcom,eeprom-src"、"qcom,actuator-src"、"qcom,led-flash-src"
  12. 调用 sensor_power_up()给sensor 上电,开始probe sensor ,上电时调用 msm_sensor_check_id(),然后调用msm_sensor_match_id()检测 sensor id 是否区配。
  13. 创建对应的 /dev/videox 节点 及 /dev/mediax 的节点
  14. probe 成功后下电
  15. 更新s_ctrl 结构体信息
// @ kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_driver.c
int32_t msm_sensor_driver_probe(void *setting, struct msm_sensor_info_t *probed_info, char *entity_name)
{
	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;
<span class="token comment">// 1. 初始化并分配 slave_info 内存</span>
<span class="token comment">/* Allocate memory for slave info */</span>
slave_info <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>slave_info<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">is_compat_task</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 2. 将上层下发的 slave_info保存在 slave_info32 中</span>
	<span class="token keyword">struct</span> msm_camera_sensor_slave_info32 <span class="token operator">*</span>slave_info32 <span class="token operator">=</span><span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>slave_info32<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">copy_from_user</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>slave_info32<span class="token punctuation">,</span> setting<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token operator">*</span>slave_info32<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	
	<span class="token comment">// 3. 将 slave_info32 中的信息保存到 slave_info中。</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>actuator_name<span class="token punctuation">,</span> slave_info32<span class="token operator">-&gt;</span>actuator_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>actuator_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>eeprom_name<span class="token punctuation">,</span> slave_info32<span class="token operator">-&gt;</span>eeprom_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>eeprom_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">,</span> slave_info32<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>ois_name<span class="token punctuation">,</span> slave_info32<span class="token operator">-&gt;</span>ois_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>ois_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>flash_name<span class="token punctuation">,</span> slave_info32<span class="token operator">-&gt;</span>flash_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>flash_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	slave_info<span class="token operator">-&gt;</span>addr_type <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>addr_type<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>camera_id <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">;</span>

	slave_info<span class="token operator">-&gt;</span>i2c_freq_mode <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>i2c_freq_mode<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>sensor_id_info <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">;</span>

	slave_info<span class="token operator">-&gt;</span>slave_addr <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>slave_addr<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>module_id_info <span class="token operator">=</span>  slave_info32<span class="token operator">-&gt;</span>module_id_info<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size_down <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size_down<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size_down <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>size_down<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>power_setting <span class="token operator">=</span> <span class="token function">compat_ptr</span><span class="token punctuation">(</span>slave_info32<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>power_setting<span class="token punctuation">)</span><span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>power_down_setting <span class="token operator">=</span> <span class="token function">compat_ptr</span><span class="token punctuation">(</span>slave_info32<span class="token operator">-&gt;</span>power_setting_array<span class="token punctuation">.</span>power_down_setting<span class="token punctuation">)</span><span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>sensor_init_params <span class="token operator">=</span> slave_info32<span class="token operator">-&gt;</span>sensor_init_params<span class="token punctuation">;</span>
	slave_info<span class="token operator">-&gt;</span>output_format <span class="token operator">=</span>slave_ info32<span class="token operator">-&gt;</span>output_format<span class="token punctuation">;</span>
	<span class="token function">kfree</span><span class="token punctuation">(</span>slave_info32<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 保存完毕合释放 slave_info32 内存。</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span>

#endif
{
if (copy_from_user(slave_info,(void )setting, sizeof(slave_info))) {
pr_err(“failed: copy_from_user”);
rc = -EFAULT;
goto free_slave_info;
}
}
// 4. 打印 slave info 信息
/* Print slave info */
CDBG(“camera id %d Slave addr 0x%X addr_type %d\n”, slave_info->camera_id, slave_info->slave_addr, slave_info->addr_type);
CDBG(“sensor_id_reg_addr 0x%X sensor_id 0x%X sensor id mask %d”, slave_info->sensor_id_info.sensor_id_reg_addr, slave_info->sensor_id_info.sensor_id,slave_info->sensor_id_info.sensor_id_mask);
CDBG(“power up size %d power down size %d\n”,slave_info->power_setting_array.size,slave_info->power_setting_array.size_down);
CDBG(“position %d”,slave_info->sensor_init_params.position);
CDBG(“mount %d”,slave_info->sensor_init_params.sensor_mount_angle);

<span class="token comment">// 5. 通过camera id 获取到对应的 camera sensor ctrol 信息,也就是对应的camera 的dts 信息。</span>
<span class="token comment">/* Extract s_ctrl from camera id */</span>
s_ctrl <span class="token operator">=</span> g_sctrl<span class="token punctuation">[</span>slave_info<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"s_ctrl[%d] %pK"</span><span class="token punctuation">,</span> slave_info<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">,</span> s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 6. 检测sensor 是否已经probe 过了,如果不是,直接跳过if 进行probe</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>is_probe_succeed <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">/*
	 * Different sensor on this camera slot has been connected
	 * and probe already succeeded for that sensor. Ignore this
	 * probe */</span>
	<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
<span class="token comment">// 7. 获取camera的power settting</span>
rc <span class="token operator">=</span> <span class="token function">msm_sensor_get_power_settings</span><span class="token punctuation">(</span>setting<span class="token punctuation">,</span> slave_info<span class="token punctuation">,</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 8. 初始化 msm_camera_slave_info 结构体变量 camera_info ,用于保存 camera 的信息</span>
camera_info <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_camera_slave_info<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>

s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>slave_info <span class="token operator">=</span> camera_info<span class="token punctuation">;</span>
<span class="token comment">/* Fill sensor slave info */</span>
camera_info<span class="token operator">-&gt;</span>sensor_slave_addr <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>slave_addr<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>eeprom_slave_addr <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>module_id_info<span class="token punctuation">.</span>module_slave_id<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>eeprom_module_reg_addr <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>module_id_info<span class="token punctuation">.</span>module_id_reg_addr<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>eeprom_module_id <span class="token operator">=</span> 	slave_info<span class="token operator">-&gt;</span>module_id_info<span class="token punctuation">.</span>module_id<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>eeprom_master_id <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>module_id_info<span class="token punctuation">.</span>master_id<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>sensor_id_reg_addr <span class="token operator">=</span>slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id_reg_addr<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>sensor_id <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id<span class="token punctuation">;</span>
camera_info<span class="token operator">-&gt;</span>sensor_id_mask <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id_mask<span class="token punctuation">;</span>


s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>addr_type <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>addr_type<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>client<span class="token punctuation">)</span>
	s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>client<span class="token operator">-&gt;</span>addr <span class="token operator">=</span>camera_info<span class="token operator">-&gt;</span>sensor_slave_addr<span class="token punctuation">;</span>

<span class="token comment">// 9. 配置camera i2c 相关信息。</span>
cci_client <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>cci_client<span class="token punctuation">;</span>

cci_client<span class="token operator">-&gt;</span>cci_i2c_master <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>cci_i2c_master<span class="token punctuation">;</span>
cci_client<span class="token operator">-&gt;</span>sid <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>slave_addr <span class="token operator">&gt;&gt;</span> <span class="token number">1</span><span class="token punctuation">;</span>
cci_client<span class="token operator">-&gt;</span>retries <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
cci_client<span class="token operator">-&gt;</span>id_map <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
cci_client<span class="token operator">-&gt;</span>i2c_freq_mode <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>i2c_freq_mode<span class="token punctuation">;</span>

<span class="token comment">// 10. 往s_ctrl 中填充 上下电相关信息 </span>
<span class="token comment">/* Parse and fill vreg params for powerup settings */</span>
rc <span class="token operator">=</span> <span class="token function">msm_camera_fill_vreg_params</span><span class="token punctuation">(</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>cam_vreg<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>num_vreg<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_setting<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_setting_size<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* Parse and fill vreg params for powerdown settings*/</span>
rc <span class="token operator">=</span> <span class="token function">msm_camera_fill_vreg_params</span><span class="token punctuation">(</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>cam_vreg<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>num_vreg<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_down_setting<span class="token punctuation">,</span>
	s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_down_setting_size<span class="token punctuation">)</span><span class="token punctuation">;</span>

CSID_TG:
/* Update sensor, actuator and eeprom name in
* sensor control structure /

s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
s_ctrl->sensordata->ois_name = slave_info->ois_name;
s_ctrl->sensordata->flash_name = slave_info->flash_name;
/
* Update eeporm subdevice Id by input eeprom name
/

// 11. 解析该camera 中所有外设节点信息 “qcom,eeprom-src”、“qcom,actuator-src”、“qcom,led-flash-src”
rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
=> src_node = of_parse_phandle(of_node, “qcom,eeprom-src”, i);
/
* Update actuator subdevice Id by input actuator name
*/

rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
=> src_node = of_parse_phandle(of_node, “qcom,actuator-src”, 0);
rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);
rc = msm_sensor_fill_flash_subdevid_by_name(s_ctrl);
=> src_node = of_parse_phandle(of_node, “qcom,led-flash-src”, 0);

<span class="token comment">// 12. 调用 sensor_power_up() 给sensor 上电,开始probe sensor ,上电时调用 msm_sensor_check_id(),然后调用msm_sensor_match_id()检测sensor id 是否区配。</span>
<span class="token comment">/* Power up and probe sensor */</span>
rc <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>func_tbl<span class="token operator">-&gt;</span><span class="token function">sensor_power_up</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	@ \kernel\msm<span class="token operator">-</span><span class="token number">4.4</span>\drivers\media\platform\msm\camera_v2\sensor\msm_sensor<span class="token punctuation">.</span>c
	<span class="token keyword">for</span> <span class="token punctuation">(</span>retry <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> retry <span class="token operator">&lt;</span> <span class="token number">3</span><span class="token punctuation">;</span> retry<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">/* session is secure */</span>
		s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>i2c_func_tbl <span class="token operator">=</span><span class="token operator">&amp;</span>msm_sensor_secure_func_tbl<span class="token punctuation">;</span>
		
		rc <span class="token operator">=</span> <span class="token function">msm_camera_power_up</span><span class="token punctuation">(</span>power_info<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>sensor_device_type<span class="token punctuation">,</span> sensor_i2c_client<span class="token punctuation">)</span><span class="token punctuation">;</span>

		rc <span class="token operator">=</span> <span class="token function">msm_sensor_check_id</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span> 
				rc <span class="token operator">=</span> <span class="token function">msm_sensor_match_id</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token function">msm_camera_power_down</span><span class="token punctuation">(</span>power_info<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensor_device_type<span class="token punctuation">,</span> sensor_i2c_client<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token function">msleep</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
			<span class="token keyword">break</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 13. 创建对应的 /dev/videox 节点 及 /dev/mediax 的节点</span>
<span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"%s probe succeeded"</span><span class="token punctuation">,</span> slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*
 * Create /dev/videoX node, comment for now until dummy /dev/videoX
 * node is created and used by HAL
 */</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensor_device_type <span class="token operator">==</span> MSM_CAMERA_PLATFORM_DEVICE<span class="token punctuation">)</span>
	rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_create_v4l_subdev</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 14. probe 成功后下电</span>
<span class="token comment">/* Power down */</span>
s_ctrl<span class="token operator">-&gt;</span>func_tbl<span class="token operator">-&gt;</span><span class="token function">sensor_power_down</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>

rc <span class="token operator">=</span> <span class="token function">msm_sensor_fill_slave_info_init_params</span><span class="token punctuation">(</span>slave_info<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">;</span>

rc <span class="token operator">=</span> <span class="token function">msm_sensor_validate_slave_info</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/* Update sensor mount angle and position in media entity flag */</span>
is_yuv <span class="token operator">=</span> <span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>output_format <span class="token operator">==</span> MSM_SENSOR_YCBCR<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token number">1</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
mount_pos <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>is_secure <span class="token operator">&amp;</span> <span class="token number">0x1</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> <span class="token number">26</span><span class="token punctuation">)</span> <span class="token operator">|</span> is_yuv <span class="token operator">&lt;&lt;</span> <span class="token number">25</span> <span class="token operator">|</span>
	<span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>position <span class="token operator">&lt;&lt;</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">|</span>
	<span class="token punctuation">(</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>
	sensor_info<span class="token operator">-&gt;</span>sensor_mount_angle <span class="token operator">/</span> <span class="token number">90</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>flags <span class="token operator">=</span> mount_pos <span class="token operator">|</span> MEDIA_ENT_FL_DEFAULT<span class="token punctuation">;</span>

<span class="token comment">/*Save sensor info*/</span>
s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>cam_slave_info <span class="token operator">=</span> slave_info<span class="token punctuation">;</span>

<span class="token comment">// 15. 更新s_ctrl 结构体信息</span>
<span class="token function">msm_sensor_fill_sensor_info</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">,</span> probed_info<span class="token punctuation">,</span> entity_name<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/*
 * Set probe succeeded flag to 1 so that no other camera shall
 * probed on this slot
 */</span>
s_ctrl<span class="token operator">-&gt;</span>is_probe_succeed <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204

3.4.6 创建 /dev/videoX节点 msm_sensor_driver_create_v4l_subdev()
@ \kernel\msm-4.4\drivers\media\platform\msm\camera_v2\camera\camera.c
static int32_t msm_sensor_driver_create_v4l_subdev(struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t rc = 0;
	uint32_t session_id = 0;
<span class="token comment">// 1. 初始化 msm_video_device 结构体,调用video_register_device() 注册video 节点</span>
rc <span class="token operator">=</span> <span class="token function">camera_init_v4l2</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>pdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">,</span> <span class="token operator">&amp;</span>session_id<span class="token punctuation">)</span><span class="token punctuation">;</span>	
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
	pvdev <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_video_device<span class="token punctuation">)</span><span class="token punctuation">,</span>GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev <span class="token operator">=</span> <span class="token function">video_device_alloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	v4l2_dev <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> v4l2_device<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>
	rc <span class="token operator">=</span> <span class="token function">v4l2_device_register</span><span class="token punctuation">(</span>dev<span class="token punctuation">,</span> pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>v4l2_dev<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">strlcpy</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> <span class="token string">"msm-sensor"</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>release  <span class="token operator">=</span> video_device_release<span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>fops     <span class="token operator">=</span> <span class="token operator">&amp;</span>camera_v4l2_fops<span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>ioctl_ops <span class="token operator">=</span> <span class="token operator">&amp;</span>camera_v4l2_ioctl_ops<span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>minor     <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
	pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>vfl_type  <span class="token operator">=</span> VFL_TYPE_GRABBER<span class="token punctuation">;</span>
	rc <span class="token operator">=</span> <span class="token function">video_register_device</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token punctuation">,</span>VFL_TYPE_GRABBER<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">*</span>session <span class="token operator">=</span> pvdev<span class="token operator">-&gt;</span>vdev<span class="token operator">-&gt;</span>num<span class="token punctuation">;</span>
	<span class="token function">video_set_drvdata</span><span class="token punctuation">(</span>pvdev<span class="token operator">-&gt;</span>vdev<span class="token punctuation">,</span> pvdev<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>

<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"rc %d session_id %d"</span><span class="token punctuation">,</span> rc<span class="token punctuation">,</span> session_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>session_id <span class="token operator">=</span> session_id<span class="token punctuation">;</span>

<span class="token comment">/* Create /dev/v4l-subdevX device */</span>
<span class="token function">v4l2_subdev_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>sensor_v4l2_subdev_ops<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">snprintf</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%s"</span><span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">v4l2_set_subdevdata</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>pdev<span class="token punctuation">)</span><span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>flags <span class="token operator">|</span><span class="token operator">=</span> V4L2_SUBDEV_FL_HAS_DEVNODE<span class="token punctuation">;</span>
<span class="token function">media_entity_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>type <span class="token operator">=</span> MEDIA_ENT_T_V4L2_SUBDEV<span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>group_id <span class="token operator">=</span> MSM_CAMERA_SUBDEV_SENSOR<span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>name <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>close_seq <span class="token operator">=</span> MSM_SD_CLOSE_2ND_CATEGORY <span class="token operator">|</span> <span class="token number">0x3</span><span class="token punctuation">;</span>
rc <span class="token operator">=</span> <span class="token function">msm_sd_register</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"failed: msm_sd_register rc %d"</span><span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> rc<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">msm_cam_copy_v4l2_subdev_fops</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msm_sensor_v4l2_subdev_fops<span class="token punctuation">)</span><span class="token punctuation">;</span>

#ifdef CONFIG_COMPAT
msm_sensor_v4l2_subdev_fops.compat_ioctl32 =msm_sensor_subdev_fops_ioctl;
#endif
s_ctrl->msm_sd.sd.devnode->fops =&msm_sensor_v4l2_subdev_fops;

<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

3.5 struct msm_sensor_ctrl_t 结构体描述

// @\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor.h
struct msm_sensor_ctrl_t {
	struct platform_device *pdev;
	struct mutex *msm_sensor_mutex;
<span class="token keyword">enum</span> msm_camera_device_type_t sensor_device_type<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_camera_sensor_board_info <span class="token operator">*</span>sensordata<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_sensor_power_setting_array power_setting_array<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_sensor_packed_cfg_t <span class="token operator">*</span>cfg_override<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_sd_subdev msm_sd<span class="token punctuation">;</span>
<span class="token keyword">enum</span> cci_i2c_master_t cci_i2c_master<span class="token punctuation">;</span>

<span class="token keyword">struct</span> msm_camera_i2c_client <span class="token operator">*</span>sensor_i2c_client<span class="token punctuation">;</span>
<span class="token keyword">struct</span> v4l2_subdev_info <span class="token operator">*</span>sensor_v4l2_subdev_info<span class="token punctuation">;</span>
uint8_t sensor_v4l2_subdev_info_size<span class="token punctuation">;</span>
<span class="token keyword">struct</span> v4l2_subdev_ops <span class="token operator">*</span>sensor_v4l2_subdev_ops<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_sensor_fn_t <span class="token operator">*</span>func_tbl<span class="token punctuation">;</span>
<span class="token keyword">struct</span> msm_camera_i2c_reg_setting stop_setting<span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token operator">*</span>misc_regulator<span class="token punctuation">;</span>
<span class="token keyword">enum</span> msm_sensor_state_t sensor_state<span class="token punctuation">;</span>
uint8_t is_probe_succeed<span class="token punctuation">;</span>
uint32_t id<span class="token punctuation">;</span>
<span class="token keyword">struct</span> device_node <span class="token operator">*</span>of_node<span class="token punctuation">;</span>
<span class="token keyword">enum</span> msm_camera_stream_type_t camera_stream_type<span class="token punctuation">;</span>
uint32_t set_mclk_23880000<span class="token punctuation">;</span>
uint8_t is_csid_tg_mode<span class="token punctuation">;</span>
uint32_t is_secure<span class="token punctuation">;</span>

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

4. Camera 驱动总结

通过前面的分析,我们再次验证了Kernel Camera 中的 camera及 Sensor 的两部份。

  1. Camera 部分
    通过解析compatible = "qcom,msm-cam";来初始化并注册好media_device 、v4l2_device、video_device 设备,同时生成/dev/media0节点。

  2. Sensor 部分
    通过解析compatible = "qcom,camera";来初始化调用probe解析camera sensor的dts节点信息,保存在全局g_sctrl 数组中。
    然后,上层在初始化时,依次对每个sensor下发 ioctl 参数,触发其作初始化probe ,上电check_sensor_id 及 创建对应的 /dev/videoX 节点 及 /dev/mediaX 的节点

至此,给合我们之前的移植过程,我们就将Kernel 中的 dts 相关的部分通过代码流程分析清楚了。
接下来,我们来看下 LinuxKernel 中的 V4L2 机制。

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
                            </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值