android_驱动_qcom_【高通SDM660平台 Android 10.0】(9) --- Qcom Camera Daemon 代码分析


【高通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平台 Android 10.0】(11) — Eeprom lib 与 Kernel eeprom代码分析
【高通SDM660平台 Android 10.0】(12) — Camera Chromatix 代码分析

《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》
《【高通SDM660平台 Android 10.0】 — 高通马达、eeprom、flash 等外设代码分析》


前面我都是在Android 8.0 的代码上分析的,前两天,我刚下载好一套高通SDM660 Android 10.0 的源码,
所以后续,我们分析代码都是在 10.0 上分析。

好,废话不多说,我们来看下 Camera Sensor Daemon吧。

高通camera把sensor端底层设置、ISP效果参数、chomatix等进行了单独的剥离,放在daemon进程中进行。


一、mm-qcamera-daemon 进程

其代码位于/vendor/qcom/proprietary/mm-camera/mm-camera2/server-imaging/Android.mk

LOCAL_SRC_FILES:= server.c \
  server_process.c

LOCAL_SHARED_LIBRARIES:= libcutils libdl libmmcamera2_mct
libmmcamera2_stats_modules
libmmcamera2_iface_modules
libmmcamera2_isp_modules
libmmcamera2_sensor_modules
libmmcamera2_pproc_modules
libmmcamera2_imglib_modules
libmmcamera_dbg
LOCAL_MODULE:= mm-qcamera-daemon

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以看出,mm-qcamera-daemon是包含sensor、iface、isp、stats、pproc、imglib 这几个模块的。


@ /device/qcom/sdm660_64/init.target.rc

#start camera server as daemon
service qcamerasvr /system/bin/mm-qcamera-daemon
class late_start
user camera
group camera system inet input graphics

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

1.1 server.c

我们先来看下 server.c 代码
主要工作如下:

  1. 开启 Camera Debug 功能

  2. 打开/dev/media0 获取msm_config 对应的V4L2的 entity名字

  3. 打开节点, /dev/video0

  4. 将当前打开节点,添加到 监听列表 中

  5. 开始初始化sensor 模块,此时会下发 probe camera sensor 命令

  6. 开始初始化其余的模块 包括 iface、isp、stats、pproc、imglib。
    分别调用 module_iface_initmodule_isp_initstats_module_initpproc_module_initmodule_imglib_init
    初始化完毕后,添加到mct_list列表中

  7. 依次下发如下 V4L2 命令,测试是否成功

  8. 创建定时器,供后续监测超时使用

  9. 寻找初始化完毕的 V4L2 节点的 MSM_CAMERA_SUBDEV_SENSOR_INIT 类型设备, 对应的 msm_sensor_init

  10. 打开节点

  11. 下发 sensor_init VIDIOC_MSM_SENSOR_INIT_CFG 命令, cfgtype= CFG_SINIT_PROBE_DONE

  12. 通过 select 监听已经打开的v4l2 节点的事件

@ /vendor/qcom/proprietary/mm-camera/mm-camera2/server-imaging/server.c

int main(int argc __unused, char *argv[] __unused)
{
old_mode = umask(S_IRWXO);

// 1. 开启 Camera Debug 功能
cam_debug_open();

CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: start of camera Daemon.”);
/* 1. find server node name and open the node */
// 2. 打开/dev/media0 获取msm_config 对应的V4L2的 entity名字
get_server_node_name(serv_hal_node_name);
CLOGD(CAM_MCT_MODULE, “after get_server_node_name”);

hal_fd = malloc(sizeof(read_fd_info_t));
// 3. 打开节点, /dev/video0
snprintf(dev_name, sizeof(dev_name), “/dev/%s”, serv_hal_node_name);
hal_fd->fd[0] = open(dev_name, O_RDWR | O_NONBLOCK);

// 4. 将当前打开节点,添加到 监听列表 中
hal_fd->type = RD_FD_HAL;
listen_fd_list = mct_list_append(listen_fd_list, hal_fd, NULL, NULL);

property_get(“vendor.camera.cameradaemon.SaveMemAtBoot”, savemem, “0”);
enabled_savemem = atoi(savemem);

CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: start all modules init”);
// 5. 开始初始化sensor 模块,此时会下发 probe camera sensor 命令
/* 2. after open node, initialize modules /
server_process_module_sensor_init();
>
+ @/vendor/qcom/proprietary/mm-camera/mm-camera2/server-imaging/server_process.c
+ CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: Begin sensor init mods”);
+
+ temp = modules_list[0].init_mod(modules_list[0].name);
+ if (temp) {
+ modules_list[0].module = temp;
+ modules = mct_list_append(modules, temp, NULL, NULL));
+ }
+ ->
+ @ /mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
+ mct_module_t module_sensor_init(const char *name)
+ <-
+ CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: sensor init mods done”);
<====
CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON:End of all modules init”);

// 6. 开始初始化其余的模块 包括 iface、isp、stats、pproc、imglib。
if (enabled_savemem != 1) {
server_process_module_init();
>
// mm-camera/mm-camera2/server-imaging/server_process.c
// 分别调用 module_iface_init、module_isp_init、stats_module_init、pproc_module_init、module_imglib_init
// 初始化完毕后,添加到mct_list列表中。
for (i = 1; i < (int)(sizeof(modules_list)/sizeof(mct_module_init_name_t)); i++) {
CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: module name : %s: E”, modules_list[i].name);
temp = modules_list[i].init_mod(modules_list[i].name);
CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON: module name : %s: X”, modules_list[i].name);
if (temp) {
modules_list[i].module = temp;
(modules = mct_list_append(modules, temp, NULL, NULL));
}
modules_all = mct_list_append(modules_all, temp, NULL, NULL);
}
} /* for */
<====
}

// 7. 依次下发如下 V4L2 命令,测试是否成功
/* Subcribe V4L2 event /
// / event id */
#define MSM_CAMERA_EVENT_MIN 0
#define MSM_CAMERA_NEW_SESSION (MSM_CAMERA_EVENT_MIN + 1)
#define MSM_CAMERA_DEL_SESSION (MSM_CAMERA_EVENT_MIN + 2)
#define MSM_CAMERA_SET_PARM (MSM_CAMERA_EVENT_MIN + 3)
#define MSM_CAMERA_GET_PARM (MSM_CAMERA_EVENT_MIN + 4)
#define MSM_CAMERA_MAPPING_CFG (MSM_CAMERA_EVENT_MIN + 5)
#define MSM_CAMERA_MAPPING_SES (MSM_CAMERA_EVENT_MIN + 6)
#define MSM_CAMERA_MSM_NOTIFY (MSM_CAMERA_EVENT_MIN + 7)
#define MSM_CAMERA_EVENT_MAX (MSM_CAMERA_EVENT_MIN + 8)

memset(&subscribe, 0, sizeof(struct v4l2_event_subscription));
subscribe.type = MSM_CAMERA_V4L2_EVENT_TYPE;
for (i = MSM_CAMERA_EVENT_MIN + 1; i < MSM_CAMERA_EVENT_MAX; i++) {
subscribe.id = i;
ioctl(hal_fd->fd[0], VIDIOC_SUBSCRIBE_EVENT, &subscribe);
}

signal_received = 0;
select_fds.select_fd = hal_fd->fd[0];
/* create a timer */
// 8. 创建定时器,供后续监测超时使用
mct_t_ret = mct_util_create_timer();
// 9. 寻找初始化完毕的 V4L2 节点的 MSM_CAMERA_SUBDEV_SENSOR_INIT 类型设备, 对应的 msm_sensor_init
ret_subdev = mct_util_find_v4l2_subdev(probe_done_node_name);

// 10. 打开节点
snprintf(probe_done_dev_name, sizeof(probe_done_dev_name), “/dev/%s”, probe_done_node_name);
probe_done_fd = open(probe_done_dev_name, O_RDWR | O_NONBLOCK);

// 11. 下发 sensor_init VIDIOC_MSM_SENSOR_INIT_CFG 命令, cfgtype= CFG_SINIT_PROBE_DONE
cfg.cfgtype = CFG_SINIT_PROBE_DONE;
if (ioctl(probe_done_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
CLOGE(CAM_MCT_MODULE, “ioctl SENSOR_INIT_CFG failed”);
ret = FALSE;
}
close(probe_done_fd);
CLOGD(CAM_MCT_MODULE, “CAMERA_DAEMON:waiting for camera to open”);
do {
// 12. 通过 select 监听已经打开的v4l2 节点的事件
FD_ZERO(&(select_fds.fds));
mct_list_traverse(listen_fd_list, server_reset_select_fd, &select_fds);
/* no timeout /
ret = select(select_fds.select_fd + 1, &(select_fds.fds), NULL, NULL, NULL);
// 13.
if (ret > 0) {
find_list = mct_list_find_custom(listen_fd_list, &(select_fds.fds), server_check_listen_fd);
fd_info = (read_fd_info_t )find_list->data;

  <span class="token keyword">switch</span> <span class="token punctuation">(</span>fd_info<span class="token operator">-</span><span class="token operator">&gt;</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">case</span> RD_FD_HAL<span class="token operator">:</span> <span class="token punctuation">{</span>			<span class="token comment">// 13. 将消息发送到MCT </span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">ioctl</span><span class="token punctuation">(</span>fd_info<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> VIDIOC_DQEVENT<span class="token punctuation">,</span> <span class="token operator">&amp;</span>event<span class="token punctuation">)</span> <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 keyword">continue</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">/* server process HAL event:
     *
     *   1. if it returns success, it means the event message has been
     *      posted to MCT, don't need to send CMD ACK back to kernel
     *      immediately, because MCT will notify us after process;
     *
     *   2. if it returns failure, it means the event message was not
     *      posted to MCT successfully, hence we need to send CMD ACK back
     *      to kernel immediately so that HAL thread which sends this
     *      event can be blocked.
     */</span>
      proc_ret <span class="token operator">=</span> <span class="token function">server_process_hal_event</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>event<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token keyword">break</span><span class="token punctuation">;</span>

  <span class="token keyword">case</span> RD_DS_FD_HAL<span class="token operator">:</span>
    <span class="token comment">/* server process message sent by HAL through Domain Socket */</span>
    proc_ret <span class="token operator">=</span> <span class="token function">server_process_hal_ds_packet</span><span class="token punctuation">(</span>fd_info<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> fd_info<span class="token operator">-</span><span class="token operator">&gt;</span>session<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>

  <span class="token keyword">case</span> RD_PIPE_FD_MCT<span class="token operator">:</span>
    <span class="token comment">/* server process message sent by media controller through pipe: */</span>
    proc_ret <span class="token operator">=</span> <span class="token function">server_process_mct_msg</span><span class="token punctuation">(</span>fd_info<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>d_info<span class="token operator">-</span><span class="token operator">&gt;</span>session<span class="token punctuation">)</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 comment">/* switch (fd_info-&gt;type) */</span>

  <span class="token keyword">switch</span> <span class="token punctuation">(</span>proc_ret<span class="token punctuation">.</span>result<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">case</span> RESULT_NEW_SESSION<span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token keyword">struct</span> msm_v4l2_event_data <span class="token operator">*</span>ret_data <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">struct</span> msm_v4l2_event_data <span class="token operator">*</span><span class="token punctuation">)</span>proc_ret<span class="token punctuation">.</span>ret_to_hal<span class="token punctuation">.</span>ret_event<span class="token punctuation">.</span>u<span class="token punctuation">.</span>data<span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span> ret_data<span class="token operator">-</span><span class="token operator">&gt;</span>status <span class="token operator">==</span> MSM_CAMERA_CMD_SUCCESS<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      num_sessions<span class="token operator">++</span><span class="token punctuation">;</span>
      hal_ds_fd <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>read_fd_info_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      hal_ds_fd<span class="token operator">-</span><span class="token operator">&gt;</span>session <span class="token operator">=</span> proc_ret<span class="token punctuation">.</span>new_session_info<span class="token punctuation">.</span>session_idx<span class="token punctuation">;</span>
      hal_ds_fd<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>   <span class="token operator">=</span> proc_ret<span class="token punctuation">.</span>new_session_info<span class="token punctuation">.</span>hal_ds_fd<span class="token punctuation">;</span>
      hal_ds_fd<span class="token operator">-</span><span class="token operator">&gt;</span>type    <span class="token operator">=</span> RD_DS_FD_HAL<span class="token punctuation">;</span>
      
      mct_fds <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>read_fd_info_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      mct_fds<span class="token operator">-</span><span class="token operator">&gt;</span>session <span class="token operator">=</span> proc_ret<span class="token punctuation">.</span>new_session_info<span class="token punctuation">.</span>session_idx<span class="token punctuation">;</span>
      mct_fds<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>   <span class="token operator">=</span> proc_ret<span class="token punctuation">.</span>new_session_info<span class="token punctuation">.</span>mct_msg_rd_fd<span class="token punctuation">;</span>
      mct_fds<span class="token operator">-</span><span class="token operator">&gt;</span>fd<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>   <span class="token operator">=</span> proc_ret<span class="token punctuation">.</span>new_session_info<span class="token punctuation">.</span>mct_msg_wt_fd<span class="token punctuation">;</span>
      mct_fds<span class="token operator">-</span><span class="token operator">&gt;</span>type    <span class="token operator">=</span> RD_PIPE_FD_MCT<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
    listen_fd_list <span class="token operator">=</span> <span class="token function">mct_list_append</span><span class="token punctuation">(</span>listen_fd_list<span class="token punctuation">,</span>hal_ds_fd<span class="token punctuation">,</span><span class="token constant">NULL</span><span class="token punctuation">,</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    listen_fd_list <span class="token operator">=</span> <span class="token function">mct_list_append</span><span class="token punctuation">(</span>listen_fd_list<span class="token punctuation">,</span> mct_fds<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>listen_fd_list<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">free</span><span class="token punctuation">(</span>hal_ds_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">free</span><span class="token punctuation">(</span>mct_fds<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">goto</span> server_proc_new_session_error<span class="token punctuation">;</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 function">CLOGE</span><span class="token punctuation">(</span>CAM_MCT_MODULE<span class="token punctuation">,</span> <span class="token string">"New session [%d] creation failed with error"</span><span class="token punctuation">,</span> ret_data<span class="token operator">-</span><span class="token operator">&gt;</span>session_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>TRUE <span class="token operator">==</span> <span class="token function">server_register_for_kill_signal</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>default_sa<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      is_signal_registered <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>num_sessions <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>TRUE <span class="token operator">==</span> <span class="token function">server_register_timer_cb</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>timer_id<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        is_timer_cb_registered <span class="token operator">=</span> TRUE<span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">goto</span> check_proc_ret<span class="token punctuation">;</span>
  <span class="token punctuation">}</span> <span class="token comment">/* RESULT_NEW_SESSION */</span>
    <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> RESULT_DEL_SESSION<span class="token operator">:</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 punctuation">}</span>  <span class="token keyword">goto</span> check_proc_ret<span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> RESULT_FAILURE<span class="token operator">:</span> <span class="token keyword">goto</span> server_proc_error<span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
  <span class="token keyword">case</span> RESULT_SUCCESS<span class="token operator">:</span> <span class="token keyword">goto</span> check_proc_ret<span class="token punctuation">;</span>  <span class="token keyword">break</span><span class="token punctuation">;</span>

  <span class="token punctuation">}</span> <span class="token comment">/* switch (proc_ret.result) */</span>

return 0;
}

  • 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

1.1.1 Sensor模块初始化 module_sensor_init()

  1. 初始化一个 mct_module 类型结构体,填充sensor ssession 操作方法
  2. EEPROM BIN 初始化
  3. 获取eeprom bin 数据
  4. 初始化Camera Sensor,此时会开始下发 probe 命令
  5. 寻找现有的外设
  6. 外设func_tbl结构体函数初始化,获取各个外设的 open,procexx,close 方法
  7. 创建外设 port 端口
  8. 加载eeprom lib 库,初始化 eeprom
@ /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
/** module_sensor_init: sensor module init
 *  Return: mct_module_t pointer corresponding to sensor
 *  This function creates mct_module_t for sensor module,
 *  creates port, fills capabilities and add it to the sensor module **/
mct_module_t *module_sensor_init(const char *name)
{
  mct_module_t                *s_module = NULL;
  module_sensor_ctrl_t        *module_ctrl = NULL;

SHIGH(“Sensor driver Version: %s”, SENSOR_DRIVER_VERSION); // “2.15.0”
SHIGH(“Sensor SDK capabilities: %s”, SENSOR_SDK_CAPABILITIES);

SHIGH(“Actuator driver Version: %s”, ACTUATOR_DRIVER_VERSION); // “1.0.0”
SHIGH(“Actuator SDK capabilities: %s”, ACTUATOR_SDK_CAPABILITIES);// “VCM, PIEZO, HVCM, BIVCM”

SHIGH(“EEPROM driver Version: %s”, EEPROM_DRIVER_VERSION); // “2.3.0”
SHIGH(“EEPROM SDK capabilities: %s”, EEPROM_SDK_CAPABILITIES);

SHIGH(“Flash driver Version: %s”, FLASH_DRIVER_VERSION); // “1.0.0”
SHIGH(“Flash SDK capabilities: %s”, FLASH_SDK_CAPABILITIES);

SHIGH(“OIS driver Version: %s”, OIS_DRIVER_VERSION); // “1.2.1”
SHIGH(“OIS SDK capabilities: %s”, OIS_SDK_CAPABILITIES);

SHIGH(“PDAF driver Version: %s”, PDAF_DRIVER_VERSION); // “2.3.3”
SHIGH(“PDAF SDK capabilities: %s”, PDAF_SDK_CAPABILITIES);

/* Create MCT module for sensor */
// 1. 初始化一个 mct_module 类型结构体,填充sensor ssession 操作方法
s_module = mct_module_create(name);

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

s_module->module_private = (void *)module_ctrl;

/* sensor module doesn’t have sink port */
s_module->numsinkports = 0;
// 2. EEPROM BIN 初始化
rc = eebin_interface_init(&module_ctrl->eebin_hdl);

// 3. 获取eeprom bin 数据
bin_ctl.cmd = EEPROM_BIN_GET_BIN_DATA;
rc = eebin_interface_control(module_ctrl->eebin_hdl, &bin_ctl);
=>
eebin_get_bin_data(ctrl);
<=

// 4. 初始化Camera Sensor
/* module_sensor_probe_sensors /
ret = sensor_init_probe(module_ctrl);
=>
RETURN_ON_FALSE(sensor_init_xml_probe(module_ctrl, sd_fd));
<=
// 5. 寻找现有的外设
/ find all the actuator, etc with sensor /
ret = module_sensor_find_other_subdev(module_ctrl);
// 6. 外设func_tbl结构体函数初始化,获取各个外设的 open,procexx,close 方法
/ Init sensor modules */
ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensors_subinit, NULL);

// 7. 创建外设 port 端口
/* Create ports based on CID info */
ret = mct_list_traverse(module_ctrl->sensor_bundle, port_sensor_create, s_module);

// 8. 加载eeprom lib 库,初始化 eeprom
/* intiialize the eeprom */
ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_eeprom, module_ctrl->eebin_hdl);

// 9. 初始化 chromatix
/* Create chromatix manager */
ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_chromatix, module_ctrl->eebin_hdl);

/* Initialize dual cam stream mutex */
pthread_mutex_init(&module_ctrl->dual_cam_mutex, NULL);

SLOW(“SUCCESS”);
return s_module;

SERR(“FAILED”);
ERROR1:
mct_module_destroy(s_module);
return NULL;
}

  • 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

1.1.1.1 Camera初始化 sensor_init_xml_probe()
  1. 拼凑camera_config.xml 路径的字符串,/data/vendor/camera/camera_config.xml
  2. 打开camera_config.xml文件,找到 CameraConfigurationRoot 节点
  3. 每个 CameraModuleConfig 对应着一个 Camera, 统计config 数量,供后续遍历使用
  4. 对每个Camera开始probe,下发sensor name,开始 probe ,例sensor name=imx258, 成功后保存在 slot_probed[] 数组中
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_init.c
static boolean sensor_init_xml_probe(module_sensor_ctrl_t *module_ctrl, int32_t sd_fd)
{
  /* Create the xml path from data partition */
  // 1. 拼凑camera_config.xml 路径的字符串,/data/vendor/camera/camera_config.xml
  snprintf(config_xml_name, BUFF_SIZE_255, "%s%s", CONFIG_XML_PATH, CONFIG_XML);
  SHIGH("reading from file %s", config_xml_name);

// 2. 找到 CameraConfigurationRoot 节点
/* Get the Root pointer and Document pointer of XMl file */
ret = sensor_xml_util_load_file(config_xml_name, &docPtr, &rootPtr, “CameraConfigurationRoot”);

// 3. 每个 CameraModuleConfig 对应着一个 Camera, 统计config 数量,供后续遍历使用
/* Get number of camera module configurations */
num_cam_config = sensor_xml_util_get_num_nodes(rootPtr, “CameraModuleConfig”);
SLOW(“num_cam_config = %d”, num_cam_config);

xmlConfig.docPtr = docPtr;
xmlConfig.configPtr = &camera_cfg;

// 4. 对每个Camera下发probe 命令
for (i = 0; i < num_cam_config; i++) {
nodePtr = sensor_xml_util_get_node(rootPtr, “CameraModuleConfig”, i);
xmlConfig.nodePtr = nodePtr;
ret = sensor_xml_util_get_camera_probe_config(&xmlConfig, “CameraModuleConfig”);
// 4.1 如果该Camera 已经probe 过了,则直接 continue
if (slot_probed[camera_cfg.camera_id]) {
SHIGH(“slot %d already probed”, camera_cfg.camera_id);
continue;
}
// 4.2 下发sensor name开始 probe ,例sensor name=imx258, 成功后保存在 slot_probed[] 数组中
rc = sensor_probe(module_ctrl, sd_fd, camera_cfg.sensor_name, NULL, &xmlConfig, FALSE, FALSE);
slot_probed[camera_cfg.camera_id] = TRUE;
}
return ret;
}

  • 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

1.1.1.1.1 触发Camera Probe初始化 sensor_probe()
  1. 根据xml 中解析的 sensor name, 查找并打开对应的 sensor lib 库,映射lib库方法,如果支持PDAF ,则加载 PDAF 的函数
  2. 获取 Camera Sensor 上下电配置
  3. 获取上电,下电配置
  4. 获取 Sensor 出图的数据类型 ,BAYER(RGB) Or YCBCR(YUV)
  5. 下发 CFG_SINIT_PROBE ,开始触发 Sensor Probe,传参 slave_info,包含上下电配置
  6. 解析该Camera 对应的 Lens info、CSI Info、chromatix info 信息
  7. 将该camera Sensor 和其他的相关的外设绑定在一起
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_init.c

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)
{
sensor_lib_params_t sensor_lib_params;
struct sensor_init_cfg_data cfg;
struct msm_camera_sensor_slave_info slave_info = NULL;
struct msm_sensor_power_setting power_up_setting = NULL;
struct msm_sensor_power_setting power_down_setting = NULL;
struct camera_power_setting_array *power_setting_array;

sensor_lib_params = CAM_CALLOC(1, sizeof(sensor_lib_params_t));
// 1. 根据xml 中解析的 sensor name, 查找并打开对应的 sensor lib 库,例如 libmmcamera_imx258.so
/* Load sensor library */
rc = sensor_load_library(sensor_name, sensor_lib_params, path);
>
@ mm-camera/mm-camera2/media-controller/modules/sensors/sensor/module/sensor.c

<span class="token function">snprintf</span><span class="token punctuation">(</span>lib_name<span class="token punctuation">,</span> BUFF_SIZE_255<span class="token punctuation">,</span> <span class="token string">"libmmcamera_%s.so"</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle <span class="token operator">=</span> <span class="token function">dlopen</span><span class="token punctuation">(</span>lib_name<span class="token punctuation">,</span> RTLD_NOW<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>sensor_open_lib <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle<span class="token punctuation">,</span>open_lib_str<span class="token punctuation">)</span><span class="token punctuation">;</span>
sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_ptr <span class="token operator">=</span> <span class="token punctuation">(</span>sensor_lib_t <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">sensor_open_lib</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 如果支持PDAF ,则加载 PDAF 的函数 	</span>
API_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>pdlib_get_defocus <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle<span class="token punctuation">,</span> API_name<span class="token operator">-</span><span class="token operator">&gt;</span>pdaf_get_defocus_API<span class="token punctuation">)</span><span class="token punctuation">;</span>
API_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>pdlib_init <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle<span class="token punctuation">,</span> API_name<span class="token operator">-</span><span class="token operator">&gt;</span>pdaf_init_API<span class="token punctuation">)</span><span class="token punctuation">;</span>
API_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>pdlib_deinit <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle<span class="token punctuation">,</span> API_name<span class="token operator">-</span><span class="token operator">&gt;</span>pdaf_deinit_API<span class="token punctuation">)</span><span class="token punctuation">;</span>
API_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_custom_calc_defocus <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_handle<span class="token punctuation">,</span> sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>sensorlib_pdaf_api<span class="token punctuation">.</span>calcdefocus<span class="token punctuation">)</span><span class="token punctuation">;</span>

<====
// 2. 获取 Camera Sensor 上下电配置
power_setting_array = &sensor_lib_params->sensor_lib_ptr->sensor_slave_info. power_setting_array;

slave_info = (struct msm_camera_sensor_slave_info )malloc(sizeof(slave_info));
RETURN_ON_NULL(slave_info);
memset(slave_info, 0, sizeof(*slave_info));

power_up_setting = (struct msm_sensor_power_setting )malloc( sizeof(power_up_setting) power_setting_array->size);
power_down_setting = (struct msm_sensor_power_setting )malloc( sizeof(power_down_setting) power_setting_array->size_down);
// 3. 获取上电,下电配置
translate_sensor_slave_info(slave_info,
&sensor_lib_params->sensor_lib_ptr->sensor_slave_info,
xmlConfig->configPtr, power_up_setting, power_down_setting);

// 4. 获取 Sensor 出图的数据类型 ,BAYER(RGB) Or YCBCR(YUV)
/* Update the output format in slave info */
if (SENSOR_BAYER == sensor_lib_params->sensor_lib_ptr->sensor_output.output_format)
slave_info->output_format = MSM_SENSOR_BAYER;
else
slave_info->output_format = MSM_SENSOR_YCBCR;

// 5. 下发 CFG_SINIT_PROBE ,开始触发 Sensor Probe,传参 slave_info,包含上下电配置
// 有关 VIDIOC_MSM_SENSOR_INIT_CFG 见《【高通SDM660平台 Android 10.0】Camera Sensor lib 与 Kernel Camera Probe 代码分析》
/* Pass slave information to kernel and probe */
memset(&cfg, 0, sizeof(cfg));
cfg.cfgtype = CFG_SINIT_PROBE;
cfg.cfg.setting = slave_info;
ioctl(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg);

SLOW("[%s] probe succeeded: session_id(%d) entity_name(%s)", sensor_name, cfg.probed_info.session_id, cfg.entity_name);
// 6. 解析该Camera 对应的 Lens info、CSI Info、chromatix info 信息
ret = sensor_xml_util_get_camera_full_config(xmlConfig);
=>
/* Read the Lens info /
RETURN_ON_FALSE(sensor_xml_util_get_lens_info(docPtr, nodePtr, configPtr));
/ Read the CSI info /
RETURN_ON_FALSE(sensor_xml_util_get_csi_info(docPtr, nodePtr, configPtr));
/ Read the chromatix info /
if (xmlStrlen((const xmlChar )(configPtr->chromatix_name))) {
RETURN_ON_FALSE(sensor_xml_util_parse_chromatix_config(configPtr));
} else {
SHIGH(" No chromatix xml mentioned for %s", configPtr->sensor_name);
}
<=
/* CSID core is taken from xml config file */
cfg.probed_info.subdev_id[SUB_MODULE_CSID] = xmlConfig->configPtr->camera_csi_params.csid_core;
// 7. 将该camera Sensor 和其他的相关的外设绑定在一起,保存在 sensor_bundle 结构体中
sensor_create_sbundle(module_ctrl,
&cfg.probed_info,
cfg.entity_name,
xmlConfig->configPtr,
sensor_lib_params,
is_stereo_config,
bypass_video_node_creation);

return ret;
}

  • 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

1.1.1.2 寻找现有的外设 module_sensor_find_other_subdev()
  1. 打开 /dev/media0 节点,下发 MEDIA_IOC_DEVICE_INFO 获取的设备信息,匹配找到“msm_config”
  2. 循环遍历,将所有的外设的类型,id,name 均保存在 module_ctrl->sensor_bundle 中
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
static boolean module_sensor_find_other_subdev(module_sensor_ctrl_t *module_ctrl)
{
  while (1) {
	// 1. 打开 /dev/media0 节点,下发 MEDIA_IOC_DEVICE_INFO  获取的设备信息,匹配找到“msm_config”
    snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
    dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    SLOW("Opened Device %s",dev_name);
num_media_devices<span class="token operator">++</span><span class="token punctuation">;</span>
rc <span class="token operator">=</span> <span class="token function">LOG_IOCTL</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_DEVICE_INFO<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mdev_info<span class="token punctuation">,</span> <span class="token string">"dev_info"</span><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">strncmp</span><span class="token punctuation">(</span>mdev_info<span class="token punctuation">.</span>model<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>mdev_info<span class="token punctuation">.</span>model<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">close</span><span class="token punctuation">(</span>dev_fd<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 comment">// 2. 循环遍历,将所有的外设的类型,id,name 均保存在 module_ctrl-&gt;sensor_bundle 中</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">struct</span> media_entity_desc entity<span class="token punctuation">;</span>
  <span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>entity<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>entity<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  entity<span class="token punctuation">.</span>id <span class="token operator">=</span> num_entities <span class="token operator">|</span> MEDIA_ENT_ID_FLAG_NEXT<span class="token punctuation">;</span>
  <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"entity id %d"</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  rc <span class="token operator">=</span> <span class="token function">LOG_IOCTL</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">,</span> MEDIA_IOC_ENUM_ENTITIES<span class="token punctuation">,</span> <span class="token operator">&amp;</span>entity<span class="token punctuation">,</span> <span class="token string">"enum_entities"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  num_entities <span class="token operator">=</span> entity<span class="token punctuation">.</span>id<span class="token punctuation">;</span>
  <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"entity name %s type %x group id %d"</span><span class="token punctuation">,</span>  entity<span class="token punctuation">.</span>name<span class="token punctuation">,</span> entity<span class="token punctuation">.</span>type<span class="token punctuation">,</span> entity<span class="token punctuation">.</span>group_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  subdev_type <span class="token operator">=</span> entity<span class="token punctuation">.</span>type<span class="token punctuation">;</span>


  <span class="token keyword">if</span> <span class="token punctuation">(</span>subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_ACTUATOR <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_EEPROM <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_FLASH <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_STROBE_FLASH <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_CSIPHY <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_CSID <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_OIS <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_EXT <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_IR_LED <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_IR_CUT <span class="token operator">||</span>
    subdev_type <span class="token operator">==</span> MSM_CAMERA_SUBDEV_LASER_LED<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">snprintf</span><span class="token punctuation">(</span>subdev_name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>subdev_name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"/dev/%s"</span><span class="token punctuation">,</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"sensor subdev %s"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    sd_fd <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>subdev_name<span class="token punctuation">,</span> O_RDWR<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">/* Read subdev index */</span>
    rc <span class="token operator">=</span> <span class="token function">LOG_IOCTL</span><span class="token punctuation">(</span>sd_fd<span class="token punctuation">,</span> VIDIOC_MSM_SENSOR_GET_SUBDEV_ID<span class="token punctuation">,</span> <span class="token operator">&amp;</span>subdev_id<span class="token punctuation">,</span> <span class="token string">"subdev_id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"subdev_name %s subdev id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">/* TODO: read id and fill in sensor_bundle.entity.actuator_name */</span>
    <span class="token keyword">switch</span> <span class="token punctuation">(</span>subdev_type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
       <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_ACTUATOR<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_ACTUATOR<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_ACTUATOR subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span>subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span>  module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_EEPROM<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_EEPROM<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_EEPROM subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_FLASH<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_LED_FLASH<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_LED_FLASH subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_STROBE_FLASH<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_STROBE_FLASH<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_STROBE_FLASH subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span>subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_CSIPHY<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_CSIPHY<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_CSIPHY subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_CSID<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_CSID<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_CSID subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_OIS<span class="token operator">:</span>
        match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_OIS<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
        match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
        <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_OIS subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span>  module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_IR_LED<span class="token operator">:</span>
          match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_IR_LED<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
          <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_IR_LED subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_IR_CUT<span class="token operator">:</span>
          match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_IR_CUT<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
          <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_IR_CUT subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_LASER_LED<span class="token operator">:</span>
          match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_LASER_LED<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
          <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_LASER_LED subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span>  module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> MSM_CAMERA_SUBDEV_EXT<span class="token operator">:</span>
          match_id_params<span class="token punctuation">.</span>sub_module <span class="token operator">=</span> SUB_MODULE_EXT<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_id <span class="token operator">=</span> subdev_id<span class="token punctuation">;</span>
          match_id_params<span class="token punctuation">.</span>subdev_name <span class="token operator">=</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
          <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"SUB_MODULE_EXT subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_name<span class="token punctuation">,</span> match_id_params<span class="token punctuation">.</span>subdev_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token function">mct_list_traverse</span><span class="token punctuation">(</span>module_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_bundle<span class="token punctuation">,</span> module_sensor_set_sub_module_id<span class="token punctuation">,</span> <span class="token operator">&amp;</span>match_id_params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">default</span><span class="token operator">:</span>
          <span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"ERROR Default subdev_type %d subdev_name %s subdev_id %d"</span><span class="token punctuation">,</span> subdev_type<span class="token punctuation">,</span> entity<span class="token punctuation">.</span>name<span class="token punctuation">,</span> subdev_id<span class="token punctuation">)</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 function">close</span><span class="token punctuation">(</span>sd_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">close</span><span class="token punctuation">(</span>dev_fd<span class="token punctuation">)</span><span class="token punctuation">;</span>

}
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
  • 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

1.1.1.3 外设func_tbl结构体函数初始化 module_sensors_subinit()
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
static boolean module_sensors_subinit(void *data, void *user_data __attribute__((unused)))
{
	for (i = 0; i < SUB_MODULE_MAX; i++) {
    	s_bundle->module_sensor_params[i] = malloc(sizeof(module_sensor_params_t));
		intf_info = &s_bundle->subdev_info[i].intf_info[SUBDEV_INTF_PRIMARY];
    	memset(s_bundle->module_sensor_params[i], 0, sizeof(module_sensor_params_t));
	rc <span class="token operator">=</span> sub_module_init<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>module_sensor_params<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-</span><span class="token operator">&gt;</span>func_tbl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">module_sensor_update_settings_size</span><span class="token punctuation">(</span>s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_common_info<span class="token punctuation">.</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_ptr<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

各个模块init 函数,定义如下:

@ mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c
/** Initialization table **/
static int32_t (*sub_module_init[SUB_MODULE_MAX])(sensor_func_tbl_t *) = {
  [SUB_MODULE_SENSOR]       = sensor_sub_module_init,
  [SUB_MODULE_CHROMATIX]    = chromatix_sub_module_init,
  [SUB_MODULE_ACTUATOR]     = actuator_sub_module_init,
  [SUB_MODULE_EEPROM]       = eeprom_sub_module_init,
  [SUB_MODULE_LED_FLASH]    = led_flash_sub_module_init,
  [SUB_MODULE_CSIPHY]       = csiphy_sub_module_init,
  [SUB_MODULE_CSIPHY_3D]    = csiphy_sub_module_init,
  [SUB_MODULE_CSID]         = csid_sub_module_init,
  [SUB_MODULE_CSID_3D]      = csid_sub_module_init,
  [SUB_MODULE_OIS]          = ois_sub_module_init,
  [SUB_MODULE_EXT]          = external_sub_module_init,
  [SUB_MODULE_IR_LED]       = ir_led_sub_module_init,
  [SUB_MODULE_IR_CUT]       = ir_cut_sub_module_init,
  [SUB_MODULE_LASER_LED]    = laser_led_sub_module_init
};

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

我们进代码看下:
可以看出,主要工作就是,保存subdev 模块的 open、process、close 方法。

当需要使用该模块时,通过 process 方法,发相应的事件过去即可。

下面我们挑几个常用的来看下:

@ mm-camera/mm-camera2/media-controller/modules/sensors/sensor/module/sensor.c
int32_t sensor_sub_module_init(sensor_func_tbl_t *func_tbl)
{
  func_tbl->open = sensor_open;
  func_tbl->process = sensor_process;
  func_tbl->close = sensor_close;
  return SENSOR_SUCCESS;
}

@ mm-camera/mm-camera2/media-controller/modules/sensors/chromatix/module/chromatix_sub_module.c
int32_t chromatix_sub_module_init(sensor_func_tbl_t *func_tbl)
{
func_tbl->open = chromatix_open;
func_tbl->process = chromatix_process;
func_tbl->close = chromatix_close;
return SENSOR_SUCCESS;
}

@ mm-camera/mm-camera2/media-controller/modules/sensors/actuator/module/actuator.c
int32_t actuator_sub_module_init(sensor_func_tbl_t *func_tbl)
{
func_tbl->open = actuator_open;
func_tbl->process = actuator_process;
func_tbl->close = actuator_close;
return 0;
}

@ mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/module/eeprom.c
int32_t eeprom_sub_module_init(sensor_func_tbl_t *func_tbl)
{
func_tbl->open = eeprom_open;
func_tbl->process = eeprom_process;
func_tbl->close = eeprom_close;
return SENSOR_SUCCESS;
}

@ mm-camera/mm-camera2/media-controller/modules/sensors/flash/module/flash.c
int32_t led_flash_sub_module_init(sensor_func_tbl_t *func_tbl)
{
func_tbl->open = flash_open;
func_tbl->process = flash_process;
func_tbl->close = flash_close;
return SENSOR_SUCCESS;
}

  • 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

好,写到这里就不再深入了,后面,我们再写一篇文章来专门写外设procexx 工作代码分析:
《【高通SDM660平台 Android 10.0】 — 高通马达、eeprom、flash 等外设代码分析》。

敬请期待吧。^_^


1.1.1.4 创建外设 port 端口 port_sensor_create()

主要工作如下:

  1. 打开 /dev/csi, 切点下发 CSID_INIT 命令,初始化 CSID ,上电,使能 csi clk, 使能中断等
  2. 发送 CSID_GET_VERSION 命令 获得 CSID 版本号
  3. 发送 SENSOR_GET_SENSOR_PORT_INFO 命令获得sensor 端口信息,也就是sensor lib库 头文件中的 sensor_stream_info_array 信息
  4. 以 /sensor/libs/imx258/imx258_lib.h 为例,此处 sensor_stream_info_array->siz = 2
  5. 创建 mct port 口, name=csi0 / csi1
  6. 将创建 好的 sensor PORT 口添加在 s_module 中
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/port_sensor.c

boolean port_sensor_create(void data, void user_data)
{
module_sensor_params = s_bundle->module_sensor_params[SUB_MODULE_SENSOR];
csid_module_params = s_bundle->module_sensor_params[SUB_MODULE_CSID];

// 1. 打开 /dev/csi, 切点下发 CSID_INIT 命令,初始化 CSID ,上电,使能 csi clk, 注册中断等
rc = csid_module_params->func_tbl.open(&csid_module_params->sub_module_private,
&s_bundle->subdev_info[SUB_MODULE_CSID]);
>
+ @ mm-camera/mm-camera2/media-controller/modules/sensors/csid/csid.c
+ snprintf(subdev_string, sizeof(subdev_string), “/dev/%s”,
+ info->intf_info[SUBDEV_INTF_PRIMARY].sensor_sd_name);
+ ctrl->fd = open(subdev_string, O_RDWR);
+ cfg.cfgtype = CSID_INIT;
+ rc = ioctl(ctrl->fd, VIDIOC_MSM_CSID_IO_CFG, &cfg);
+ >
+ rc = msm_csid_init(csid_dev, &cdata->cfg.csid_version);
+ >
+ cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,CAM_AHB_SVS_VOTE);
+ /* power up */
+ msm_camera_config_vreg(&csid_dev->pdev->dev, csid_dev->csid_vreg,
+ csid_dev->regulator_count, NULL, 0, &csid_dev->csid_reg_ptr[0], 1);
+
+ msm_camera_config_vreg(&csid_dev->pdev->dev,
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info),NULL, 0, &csid_dev->csi_vdd, 1);
+
+ msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_dev->csid_vreg,
+ csid_dev->regulator_count, NULL, 0, &csid_dev->csid_reg_ptr[0], 1);
+
+ msm_camera_enable_vreg(&csid_dev->pdev->dev,
+ csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1);
+
+ msm_camera_clk_enable(&csid_dev->pdev->dev,csid_dev->csid_clk_info, csid_dev->csid_clk,
+ csid_dev->num_clk, true);
+ msm_camera_enable_irq(csid_dev->irq, true);
+ msm_csid_reset(csid_dev);
+ csid_dev->csid_state = CSID_POWER_UP;
+ <
<====

// 2. 发送 CSID_GET_VERSION 命令 获得 CSID 版本号
rc = csid_module_params->func_tbl.process(csid_module_params->sub_module_private,
CSID_GET_VERSION, &csid_version);
->
+ csid_get_version(csid_ctrl, data);
+ >
+ csid_version = (uint32_t )data;
+ csid_version = ctrl->csid_version;
<-

csid_module_params->func_tbl.close(csid_module_params->sub_module_private);

// 3. 发送 SENSOR_GET_SENSOR_PORT_INFO 命令获得sensor 端口信息,也就是sensor lib库 头文件中的 sensor_stream_info_array 信息
module_ctrl = (module_sensor_ctrl_t )s_module->module_private;
sensor_lib_params = s_bundle->sensor_lib_params;
rc = module_sensor_params->func_tbl.process(s_bundle->sensor_lib_params,
SENSOR_GET_SENSOR_PORT_INFO, &sensor_stream_info_array);
->
+ @ mm-camera/mm-camera2/media-controller/modules/sensors/sensor/module/sensor.c
+ case SENSOR_GET_SENSOR_PORT_INFO:
+ rc = sensor_get_sensor_port_info(sctrl, data);
+ >
+ sensor_stream_info_array_t sensor_port_info_array = (sensor_stream_info_array_t )data;
+ sensor_port_info_array = &(lib->sensor_lib_ptr->sensor_stream_info_array);
+ <
<-

// 4. 以 /sensor/libs/imx258/imx258_lib.h 为例,此处 sensor_stream_info_array->siz = 2
SLOW(“sensor_stream_info_array->size %d”, sensor_stream_info_array->size);
for (j = 0; j < sensor_stream_info_array->size; j++) {
// 5. 创建 mct port 口, name=csi0 / csi1
snprintf(port_name, sizeof(port_name), “%s%d”, s_bundle->sensor_info->sensor_name, j);
s_port = mct_port_create(port_name);
>
+ @ mm-camera/mm-camera2/media-controller/mct/port/mct_port.c
+ port = malloc(sizeof(mct_port_t));
+ mct_object_set_name(MCT_OBJECT_CAST(port), name); => object->name = mct_strdup(name);
+ mct_port_init_default(port);
<==

sensor_src_port_cap <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>sensor_src_port_cap_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">memset</span><span class="token punctuation">(</span>sensor_src_port_cap<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>sensor_src_port_cap_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>session_id <span class="token operator">=</span> s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_info<span class="token operator">-</span><span class="token operator">&gt;</span>session_id<span class="token punctuation">;</span>
sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>num_cid_ch <span class="token operator">=</span> sensor_stream_info_array<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_stream_info<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">.</span>vc_cfg_size<span class="token punctuation">;</span>
sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>is_stereo_config <span class="token operator">=</span> s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>is_stereo_configuration<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> sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>num_cid_ch<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_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>cid <span class="token operator">=</span> sensor_stream_info_array<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_stream_info<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">.</span>vc_cfg<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>cid<span class="token punctuation">;</span>
<span class="token operator">+</span>      sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>csid <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">uint32_t</span><span class="token punctuation">)</span>s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_info<span class="token operator">-</span><span class="token operator">&gt;</span>subdev_id<span class="token punctuation">[</span>SUB_MODULE_CSID<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token operator">+</span>
<span class="token operator">+</span>      sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>csid_version <span class="token operator">=</span> csid_version<span class="token punctuation">;</span>
<span class="token operator">+</span>      sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>dt <span class="token operator">=</span> sensor_stream_info_array<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_stream_info<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">.</span>vc_cfg<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>dt<span class="token punctuation">;</span>
<span class="token operator">+</span>	
<span class="token operator">+</span>      sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>is_bayer_sensor <span class="token operator">=</span>
<span class="token operator">+</span>        		s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_common_info<span class="token punctuation">.</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>        		sensor_output<span class="token punctuation">.</span>output_format <span class="token operator">==</span> SENSOR_YCBCR <span class="token operator">?</span> <span class="token number">0</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 operator">+</span> 	   pix_fmt_fourcc <span class="token operator">=</span> <span class="token function">sensor_util_get_fourcc_format</span><span class="token punctuation">(</span> 
<span class="token operator">+</span> 	 			sensor_stream_info_array<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_stream_info<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">.</span>pix_data_fmt<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token operator">+</span>    			s_bundle<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_params<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_lib_ptr<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_output<span class="token punctuation">.</span>filter_arrangement<span class="token punctuation">,</span>
<span class="token operator">+</span>    			sensor_stream_info_array<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_stream_info<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">.</span>vc_cfg<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>decode_format<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span> 
<span class="token operator">+</span> 	   sensor_src_port_cap<span class="token operator">-</span><span class="token operator">&gt;</span>sensor_cid_ch<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>fmt <span class="token operator">=</span> <span class="token function">sensor_util_get_hal_format</span><span class="token punctuation">(</span>pix_fmt_fourcc<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

s_port<span class="token operator">-</span><span class="token operator">&gt;</span>direction <span class="token operator">=</span> MCT_PORT_SRC<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>check_caps_reserve <span class="token operator">=</span> port_sensor_caps_reserve<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>check_caps_unreserve <span class="token operator">=</span> port_sensor_caps_unreserve<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>ext_link <span class="token operator">=</span> port_sensor_ext_link_func<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>un_link <span class="token operator">=</span> port_sensor_unlink_func<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>event_func <span class="token operator">=</span> port_sensor_port_process_event<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>intra_event_func <span class="token operator">=</span> port_sensor_port_process_event<span class="token punctuation">;</span>

<span class="token function">SLOW</span><span class="token punctuation">(</span><span class="token string">"s_port=%p event_func=%p"</span><span class="token punctuation">,</span> s_port<span class="token punctuation">,</span> s_port<span class="token operator">-</span><span class="token operator">&gt;</span>event_func<span class="token punctuation">)</span><span class="token punctuation">;</span>

s_port<span class="token operator">-</span><span class="token operator">&gt;</span>caps<span class="token punctuation">.</span>u<span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>sensor_src_port_cap<span class="token punctuation">;</span>
s_port<span class="token operator">-</span><span class="token operator">&gt;</span>port_private <span class="token operator">=</span> <span class="token punctuation">(</span>module_sensor_port_data_t <span class="token operator">*</span><span class="token punctuation">)</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>module_sensor_port_data_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>s_port<span class="token operator">-</span><span class="token operator">&gt;</span>port_private<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>module_sensor_port_data_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 6. 将 PORT 口添加在 s_module 中。</span>
ret <span class="token operator">=</span> <span class="token function">mct_module_add_port</span><span class="token punctuation">(</span>s_module<span class="token punctuation">,</span> s_port<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
  • 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
1.1.1.4.1 Stream Info 示例

以 IMX258 为例, stream info 如下

@ mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/imx258/imx258_lib.h
.sensor_stream_info_array =
  {
    .sensor_stream_info =
    {
      {
        .vc_cfg_size = 2,
        .vc_cfg =
        {
          {
            .cid = 0,
            .dt = CSI_RAW10,
            .decode_format = CSI_DECODE_10BIT,
          },
          {
            .cid = 1,
            .dt = IMX258_CSI_PD_ISTATS,
            .decode_format = CSI_DECODE_8BIT,
          },
        },
        .pix_data_fmt =
        {
          SENSOR_BAYER,
          SENSOR_META,
        },
      },
      {
        .vc_cfg_size = 1,
        .vc_cfg =
        {
          {
            .cid = 2,
            .dt = CSI_EMBED_DATA,
            .decode_format = CSI_DECODE_8BIT,
          },
        },
        .pix_data_fmt =
        {
          SENSOR_META,
        },
      },
    },
    .size = 2,
  },

 
 
  • 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

1.1.1.5 Eeprom初始化 module_sensor_init_eeprom()
  1. 初始化 eeprom 的open、process、close 方法
  2. 找开 msm_eeprom 节点 ( /dev/v4l-subdevX )
  3. copy sensor name (解析自 config.xml 中,如 rohm_brcg064gwz_3)
  4. 加载 eeprom lib 库,映射 eeprom_open_lib 方法
  5. 解析EEPROM 上电时序,下发 CFG_EEPROM_INIT 上电且初始化 eeprom
  6. 下发 CFG_EEPROM_READ_CAL_DATA 获取eeprom 数据
  7. 处理 EEPROM OTP 数据
  8. 获取格式化过后的 eeprom 数据
  9. 如果是双摄的话,格式化双摄数据
@ mm-camera/mm-camera2/media-controller/modules/sensors/module/module_sensor.c

static boolean module_sensor_init_eeprom(void data, void eebin_hdl)
{
s_bundle = (module_sensor_bundle_info_t *)data;
// 1. 初始化eeprom 的open、process、close 方法
eeprom_sub_module_init(&func_tbl);
>
+ func_tbl->open = eeprom_open;
+ func_tbl->process = eeprom_process;
+ func_tbl->close = eeprom_close;
<-

s_bundle->eeprom_data = (sensor_eeprom_data_t *) malloc(sizeof(sensor_eeprom_data_t));

// 2. 找开 msm_eeprom 节点 ( /dev/v4l-subdevX )
/* (1) Open the eeprom sub module /
rc = func_tbl.open((void )&s_bundle->eeprom_data, &s_bundle->subdev_info[SUB_MODULE_EEPROM]);
->
ctrl = (sensor_eeprom_data_t )(*eeprom_ctrl);
snprintf(subdev_string, sizeof(subdev_string), “/dev/%s”,
info->intf_info[SUBDEV_INTF_PRIMARY].sensor_sd_name);
<-

// 3. copy sensor name(解析自 config.xml中,如 rohm_brcg064gwz_3 )
memset(&s_bundle->eeprom_data->eeprom_params, 0, sizeof(eeprom_params_t));
memcpy(s_bundle->eeprom_data->eeprom_params.eeprom_name,
s_bundle->sensor_common_info.camera_config.eeprom_name,
sizeof(s_bundle->eeprom_data->eeprom_params.eeprom_name));

/* (2) Load eeprom library */
bin_ctl.cmd = EEPROM_BIN_GET_NAME_DATA;
bin_ctl.ctl.q_num.type = EEPROM_BIN_LIB_EEPROM;
bin_ctl.ctl.name_data.name = s_bundle->sensor_info->sensor_name;
bin_ctl.ctl.name_data.path = NULL;
rc = eebin_interface_control(eebin_hdl, &bin_ctl);
>
@ mm-camera/mm-camera2/media-controller/modules/sensors/eebin/module/eebin_interface.c
rc = eebin_name_data(eebin_hdl, &bin_ctl->ctl.name_data);
type_l = BIN_DEV_EEPROM;
for (i = 0; i < master_h->num_modules; i++) {
for(j = 0; j < bin_device->moddev[i].module_h.max_devices; j++) {
if(bin_device->moddev[i].device_h[j].type type_l) {
if(!strncmp(bin_device->moddev[i].device_h[j].name, name_data->name,
sizeof(bin_device->moddev[i].device_h[j].name)))
{
name_data->lib_name = bin_device->moddev[i].device_h[j].lib_name;
name_data->path = bin_device->moddev[i].device_h[j].path;
SLOW(“name:%s lib_name:%s, path:%s”,
bin_device->moddev[i].device_h[j].name,
bin_device->moddev[i].device_h[j].lib_name,
bin_device->moddev[i].device_h[j].path);
}
}
}
}
<==
SHIGH(“EEPROM path: %s name: %s”, bin_ctl.ctl.name_data.path, s_bundle->eeprom_data->eeprom_params.eeprom_name);

// 4. 加载eeprom lib库,映射 eeprom_open_lib 方法
rc = eeprom_load_library(s_bundle->eeprom_data, bin_ctl.ctl.name_data.path);
==>
@ mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/module/eeprom.c
snprintf(lib_name, sizeof(lib_name), “libmmcamera_%s_eeprom.so”, name);
SHIGH(“lib_name %s”,lib_name);
e_ctrl->eeprom_lib.eeprom_lib_handle = dlopen(lib_name, RTLD_NOW);

<span class="token function">snprintf</span><span class="token punctuation">(</span>open_lib_str<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>open_lib_str<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%s_eeprom_open_lib"</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>eeprom_open_lib  <span class="token operator">=</span> <span class="token function">dlsym</span><span class="token punctuation">(</span>e_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>eeprom_lib<span class="token punctuation">.</span>eeprom_lib_handle<span class="token punctuation">,</span> open_lib_str<span class="token punctuation">)</span><span class="token punctuation">;</span>

e_ctrl<span class="token operator">-</span><span class="token operator">&gt;</span>eeprom_lib<span class="token punctuation">.</span>func_tbl <span class="token operator">=</span> <span class="token punctuation">(</span>eeprom_lib_func_t <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">eeprom_open_lib</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<==

// 5. 解析EEPROM 上电时序,下发 CFG_EEPROM_INIT 上电且初始化 eeprom
/* (3) Powerup and parse the eeprom /
rc = func_tbl.process(s_bundle->eeprom_data, EEPROM_INIT, NULL);
==>
+ // mm-camera/mm-camera2/media-controller/modules/sensors/eeprom/module/eeprom.c
+ static int32_t eeprom_init(void ptr)
+ {
+ power_setting_array = (struct msm_sensor_power_setting_array *)malloc(
+ sizeof(struct msm_sensor_power_setting_array));
+ translate_camera_power_setting(power_setting_array<span class="token punctuati

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值