高通camera驅動 mm-camera部分 (一)

        想寫一份關於qualcomm 平臺 的camera driver 的文檔 ,想講清楚 camera 各個 module 和 camera sensor的各個sub module。

        無論是 camx 還是 mm-camera 結構, 無論是android O 還是 N 東西就那麼多,就不同的寫法和實現,萬變不離其宗。他強由他強,清風拂山崗。一理通百里用說的就是這個道理。目前下面的是基於mm-camera的學習。有啥不對的,歡迎指正。會持續更新。

 主進程 [email protected] 主要調用的庫有:

              camera hal庫 camera.<平臺>.so ,如:高通的camera.qcom.so 在設備 vendor/lib/hw 目錄下。

              camera 各個submodule庫。

              備註:老版的框架調用的是mm-qcamera-deamon。

大致框架有2種:

1. camx 代碼需要高通平臺權限下載後放置 vendor 目錄下 chi-cdk 同級目錄即可。camx (沒看過,待完善)對應hal,編譯生成camera.qcom.so

  chi-cdk 目錄下主要爲各個module,eeprom sensor chromatix等主要都是通過配置xml實現的功能。吐槽:修改起來很麻煩

2. mm-camera 代碼結構,主要調用的庫 libmmcamera2_mct_shimlayer.so 入口函數 mct_shimlayrt_process_module_init 注意看函數註釋:this function is the direct call from HAL to init all the modules present in backend.

mct_shimlayrt_module_sensor_init
mct_shimlayrt_module_init

 Old 2. 老版本mm-camera  主進程 mm-qcamera-deamon  main函數所在 server.c  server process 。(2和old2的區別及優點每個overview都重複描述,以後補充)

mm-camera 結構

    |- mct——應該就是camera的引擎 裏面包含了引擎、pipiline、bus、module、stream及event等定義及封裝。

    |- modules ——  這裏面就是劃分好的一些模塊代碼,各模塊大致功能如下 :

        |- sensor  ——  sensor 的驅動模塊(src模塊)

        |- iface     ——  ISP interface模塊(inter模塊)

        |- isp        —— 主要是ISP的處理,其內部又包含了衆多的模塊(inter模塊)

        |- stats    —— 一些統計算法模塊,如3A,ASD,AFD,IS,GRRO等數據統計的處理(sink模塊)

        |- pproc   —— post process處理(inter模塊)

        |- imglib   —— 主要是圖片的一些後端處理,如HDR等(sink模塊)

以上各模塊內部又包含了衆多的模塊,具體需要看代碼分析。

將camera的所有功能劃分爲不同的模塊,讓模塊自己來決定自己的事情(高內聚,低耦合),模塊需要有統一的接口和格式。模塊中有端口,通過端口把模塊連接起來,又把模塊掛在總線上。每一個端口的連接就是一個流,把這些流用pipeline來管理。每次啓動一個camera就創建一個會話,由這個會話來管理此camera的一切事物。對於每一個會話,模塊是共享的,它可以是camera的硬件資源也可以是其它資源(如一些軟件算法等資源)。

 

module_list:

  • module_sensor_init << sensor module
  • module_iface_init
  • module_isp_init
  • stats_module_init
  • pproc_module_init
  • module_imglib_init

sensor module  (正題) /mmcamera/mm-camera2/media-controller_modules/sensors

sensor模塊是衆多模塊中的一個,主要是由模組的各個硬件模塊組成,包括sensor、Flash、Af、EEprom、OIS、CSI、ir_cut、ir_led 等。這個模塊主要描述了模組硬件的一些工作原理及部分驅動相關部分。sensors目錄及子目錄下的每個module文件夾包含的都是當前目錄的功能實現。

   在前面講到的server process 或者 mct shimlayer 中提到,調用開始後會初始化各個模塊,其中就包括sensor模塊,sensor初始化入口函數即爲module_sensor_init(...)。這個函數將創建sensor模塊並返回其指針,另外將創建它的端口,填充一些功能函數等。它的主要執行流程如下:

    1.創建sensor的MCT module。  —— mct_module_create(name)

        創建完之後填充set mode、query mode、start session、stop session及set session data五個接口函數。

    2.創建module_sensro_ctrl_t結構體,此結構體包含bundle信息,用來構建前面提到的模塊樹(方便添加、遍歷等操作)。

    3.sensor模塊是source模塊,所以其numsinkports應該設置爲0。

    4.eebin相關的操作  << eebin_interface_init

    5.sensor的probe操作,用來probe有效的sensor。

    6.填入所有已probe到sensor的信息。 << sensor_init_probe

    7.填入所以sensor的其它信息(Actuator,Flash,CSID,OIS等)module_sensor_find_other_subdev

    8.初始化sensor模塊。 <<  module_sensor_subinit(初始化子模塊函數列表)

    9.創建基於CID info的端口 port_sensor_create

    10.初始化eeprom module_sensor_init_eeprom

          (1)open the eeprom sub module

         (2)load eeprom library   

         (3)powerup and parse the eeprom

         (4)read the eeprom data from kernel

        (5)format the cal data

        (6)close the eprom sub module

   11.創建chromatix的管理 module_sensor_init_chromatix

 

sub_module_init << 下列是每個子模塊

  • sensor_sub_module_init << sensor/module/sensor.c (camera sensor driver)
  • chromatix_sub_module_init
  • actuator_sub_module_init
  • eeprom_sub_module_init << eeprom/module/eeprom.c (eeprom driver)
  • led_flash_sub_module_init
  • csiphy_sub_module_init
  • csid_sub_moduLe init 
  • ois_ sub_module_init
  • external_sub_module_init
  • ir_led_sub_module_init
  • ir_cut_sub_module_init
  • laser_led_sub_module_init 

sensor driver

/vendor/qcom/proprietary/mm-camera/ mm-camera2/media-controller/modules/sensors/sensor_libs/.

libs 下面的文件

Android.mk - 包含構建規則和包含路徑。

<sensor> _lib.c - 包含傳感器特定的邏輯和功能。

<sensor> _lib.h - 包含傳感器配置和傳感器處理器結構。

在power_setting_array中可以添加powerup和powerdown序列 camera_power_setting_array結構體。

.power_setting_array = {

.power_setting = power_setting,

.size = ARRAY_SIZE(power_setting),

},

power_setting指向一個數組,其中包含要用於GPIO / CLK / VREG的信息配置每個傳感器。

static struct camera_power_setting power_setting[] = {

{

.seq_type = SENSOR_VREG,

.seq_val = CAM_VDIG,

.config_val = 0,

.delay = 0, //this delay is in ms

},

{

.seq_type = SENSOR_VREG,

.seq_val = CAM_VANA,

.config_val = 0,

.delay = 0, //this delay is in ms

},

這個結構用在內核中的msm_camera_power_up()中來配置傳感器啓動順序。

sensor_init_params包含相機模塊配置。

80-NV354-3 Rev. A

modes_supported - 屏幕顯示支持的模式(2D,3D)。

position - 設置設備上的傳感器位置(背面或前置攝像頭)。

sensor_mount_angle - 設置相對於顯示器的相機安裝角度。

 

typedef struct {

sensor_output_format_t output_format;

sensor_connection_mode_t connection_mode;

sensor_raw_output_t raw_output;

sensor_filter_arrangement filter_arrangement;

} sensor_output_t;

output_format - 傳感器爲RAW幀傳送BAYER(SENSOR_BAYER)。

connection_mode - 傳輸接口 - MIPI(SENSOR_MIPI_CSI)或並行。

raw_output - 傳輸的數據類型 - RAW10(SENSOR_10_BIT_DIRECT),

RAW12(SENSOR_12_BIT_DIRECT),RAW8(SENSOR_8_BIT_DIRECT),DPCM8等

filter_arrangement - 由傳感器流出的幀的拜耳色彩圖案

struct sensor_output_reg_addr_t {

unsigned short x_output;

unsigned short y_output;

unsigned short line_length_pclk;

unsigned short frame_length_lines;

};

x_output - x_output寄存器的地址。 該寄存器包含每個活動像素的數量在傳感器輸出中。

y_output - y_output寄存器的地址。 該寄存器包含每行的活動行數框中傳感器輸出。

line_length_pclk - line_length_pclk寄存器的地址。 該寄存器包含的號碼傳感器輸出中每行的總像素數。

frame_length_lines - y_output寄存器的地址。 該寄存器包含總數傳感器輸出中每幀的行數。

struct sensor_exp_gain_info_t {

unsigned short coarse_int_time_addr;

unsigned short global_gain_addr;

unsigned short vert_offset;

};

coarse_int_time_addr。 該寄存器包含幀曝光次數。

global_gain_addr。 該寄存器包含幀模擬增益。 其值由傳感器特定功能計算。

vert_offset - 包含max_coarse_integration_margin的值,它是一個傳感器 - 具體價值。 它是曝光和幀長度之間的最大值。 曝光不能大於幀長度減去vert_offset。

max_exp <= frame_length – vert_offset

typedef struct {

float min_gain;

float max_gain;

float min_analog_gain;

float max_linecount;

}sensor_aec_data_t;

min_gain - 以標準化單位(1.00x)設置傳感器增益的最低可接受值。如果沒有另外指定,設置爲1.00x。

max_gain - 以標準化單位(1.00x)設置增益的最高可接受值。 這是結果的模擬和數字增益。

max_analog_gain - 以標準化單位(1.00x)設置傳感器的模擬增益的最高可接受值。 如果傳感器沒有數字增益,max_analog_gain和max_gain應該相等。

max_linecount - 設置傳感器曝光的最高可接受值。 此值取決於rough_integration_time寄存器分辨率和max_coarse_integration_margin(在vert_offset中設置)。

typedef struct {

float focal_length;

float pix_size;

float f_number;

float total_f_dist;

float hor_view_angle;

float ver_view_angle;

sensor_sensing_method_type_t sensing_method;

float crop_factor; //depends on sensor physical dimentions

float min_focus_distance;

} sensor_lens_info_t;

focal_length - 設置鏡頭焦距。

pix_size - 設置鏡頭單元格尺寸。

f_number - 設置鏡頭的F數。

Total_f_dist - 設置總焦距。 值以米爲單位。

hor_view_angle - 設置鏡頭的水平視角。 值以度爲單位。

ver_view_angle - 設置鏡頭的水平視角。 值以度爲單位。

sensing_method - 設置感應方式。 如果方法未知,請設置爲

SENSOR_SMETHOD_NOT_DEFINED。

crop_factor - 設置鏡頭裁剪係數。 該值取決於鏡頭和傳感器的物理尺寸,顯示鏡頭是否從傳感器矩陣中裁出。

min_focus_distance - 設置鏡頭最小移動步長。 如果鏡頭沒有特殊的限制,設置爲0.1

 

typedef struct {

float pix_width;

float pix_height;

}sensor_physical_dimensions_t;

包含有關傳感器顏色的物理尺寸的信息矩陣。

pix_width - 以毫米爲單位設置傳感器像素陣列寬度。 (單元大小*有效像素寬度)

pix_height - 以毫米爲單位設置傳感器像素陣列高度。 (單元格大小*有效像素高度)

 

typedef struct {

sensor_dimension_t active_array_size;

unsigned short left_dummy;

unsigned short right_dummy;

unsigned short top_dummy;

unsigned short bottom_dummy;

} sensor_imaging_pixel_array_size;

typedef struct {

int width;

int height;

} sensor_dimention_t;

active_array_size.width - 以像素數設置傳感器有源像素陣列寬度。

active_array_size.height - 設置傳感器有源像素陣列高度的行數。

left_dummy - 在左側的有效和有效像素陣列之間設置傳感器緩衝區。 該值爲像素數。

right_dummy - 在右側的有效和有效像素陣列之間設置傳感器緩衝區。 該值爲像素數。

top_dummy - 在頂部的有效和有效像素陣列之間設置傳感器緩衝區。 該值爲行數。

bottom_dummy - 在底部的有效和有效像素陣列之間設置傳感器緩衝區。 該值爲行數。

 

typedef struct {

unsigned short white_level;

unsigned short r_pedestal;

unsigned short gr_pedestal;

unsigned short gb_pedestal;

unsigned short b_pedestal;

} sensor_color_level_info;

white_level - 將傳感器DAC的值設置爲白色。 這通常是最大可能的值DAC可以輸出(1023爲RAW10)。

r_pedestal - 設置紅色通道的黑色電平/數據基座。 該值用於RAW10數據。 對於RAW12乘以4。

gr_pedestal - 設置綠色(紅線)通道的黑色電平/數據基座。 值爲RAW10數據。 對於RAW12乘以4。

gr_pedestal - 設置綠色(藍線)通道的黑色電平/數據基座。 值爲RAW10數據。 對於RAW12乘以4。

b_pedestal - 設置藍色通道的黑色電平/數據基座。 該值用於RAW10數據。 對於RAW12乘以4。

 

start_settings - 寄存器設置命令傳感器開始流出幀。

stop_settings - 寄存器設置命令傳感器停止流出幀。

groupon_setting - 寄存器設置命令傳感器設置組參數保持邏輯。

groupoff_settings - 寄存器設置命令傳感器釋放組參數保持邏輯。

embedded_data_enable_settings - 寄存器設置以命令傳感器啓用流式傳輸嵌入式數據。

embedded_data_disable_settings - 寄存器設置命令傳感器禁用流出嵌入式數據。

 

struct camera_i2c_reg_setting {

struct camera_i2c_reg_array *reg_setting;

unsigned short size;

enum camera_i2c_reg_addr_type addr_type;

enum camera_i2c_data_type data_type;

unsigned short delay;

};

struct camera_i2c_reg_array {

unsigned short reg_addr;

unsigned short reg_data;

unsigned int delay;

};

size - 設置當前配置中設置的寄存器編號。

addr_type - 設置I2C寄存器地址長度。

data_type - 設置I2C寄存器數據長度。

delay - 設置配置完成後的等待延遲(以ms爲單位)。

reg_setting.reg_addr - 設置要更新的寄存器的傳感器寄存器地址。

reg_setting.reg_data - 設置需要寫入傳感器寄存器的數據。

reg_setting.delay - 設置註冊配置完成後的等待延遲(以ms爲單位)。

 

傳感器分辨率設置

struct sensor_lib_reg_settings_array {

struct camera_i2c_reg_setting reg_settings[MAX_RESOLUTION_MODES];

unsigned int size;

};

傳感器分辨率配置表

struct sensor_lib_out_info_array {

/* sensor output for each resolutions */

struct sensor_lib_out_info_t out_info[MAX_RESOLUTION_MODES];

/* Number of valid entries in out_info array */

unsigned short size;

};

struct sensor_lib_out_info_t {

unsigned short x_output;

unsigned short y_output;

unsigned short line_length_pclk;

unsigned short frame_length_lines;

unsigned int vt_pixel_clk;

unsigned int op_pixel_clk;

unsigned short binning_factor;

float min_fps;

float max_fps;

unsigned int mode;

unsigned int offset_x;

unsigned int offset_y;

unsigned int scale_factor;

};

size - 設置傳感器模式配置的數量。大小應等於可用的配置,不能大於MAX_RESOLUTION_MODES。

out_info.x_output - 設置每行傳感器輸出的有效像素數。該值是像素數。

out_info.y_output - 設置每幀傳感器輸出的有效線數。該值是行數。

out_info.line_length_pclk - 設置每行傳感器輸出的像素總數。這包括有源像素和水平消隱。該值是像素數。

out_info.frame_length_lines - 設置每幀傳感器輸出的總線數。這包括有效行和垂直消隱。該值是行數。

out_info.vt_pixel_clk - 設置由傳感器內部PLL模塊生成的視頻域定時時鐘值。要計算其值,請使用外部時鐘(EXTCLK)頻率和PLL設置。傳感器使用此時鐘進行多項內部任務,其值控制多個傳感器參數 - 快門/曝光時間,幀速率,傳感器內部ISP處理等。

out_info.op_pixel_clk - 設置由傳感器內部PLL模塊生成的輸出域定時時鐘值。 要計算其值,請使用外部時鐘(EXTCLK)頻率和PLL設置。 傳感器使用此時鐘作爲其輸出模塊。 該時鐘用作MIPI / CSI_Tx速度的基礎。

struct sensor_csiphy_params {

unsigned char lane_cnt;

unsigned char settle_cnt;

unsigned short lane_mask;

unsigned char combo_mode;

unsigned char csid_core;

unsigned int csiphy_clk;

};

lane_cnt - 設置CSI2車道數。 根據傳感器模式配置,可以使用兩個或四個通道進行流出。

sett_cnt - 對於CSI_Tx(傳感器)和CRI_Rx(設備)正常工作,需要在它們之間同步的時間段。 這個時間被設置爲定時器時鐘滴答的數量。 它必須在由公式計算的MIN和MAX值之間:

MIN [Settle count * T(Timer clock)] > T(HS_SETTLE)_MIN

MAX [Settle count * T(Timer clock)] < T(HS-PREPARE)+T(HS_ZERO) - 4*T(Timer clock)

lane_mask - 設置在當前配置中使用哪些CSI2通道。 該值是標誌的組合。

 

struct sensor_lib_crop_params_array{

struct sensor_crop_parms_t crop_params[MAX_RESOLUTION_MODES];

unsigned short size;

};

struct sensor_crop_parms_t {

unsigned short top_crop;

unsigned short bottom_crop;

unsigned short left_crop;

unsigned short right_crop;

};

crop_

params.top_crop - 從當前模式的頂端設置裁剪。

crop_params.bottom_crop - 從當前模式的底部設置裁剪。

crop_params.left_crop - 從當前模式的左側設置裁剪。

crop_params.right_crop - 從當前模式的右側設置裁剪。

 

struct sensor_lib_chromatix_array {

struct sensor_lib_chromatix_t sensor_lib_chromatix[MAX_RESOLUTION_MODES];

unsigned short size;

};

struct sensor_lib_chromatix_t {

char *common_chromatix;

char *camera_preview_chromatix;

char *camera_snapshot_chromatix;

char *camcorder_chromatix;

char *liveshot_chromatix;

char *cpp_chromatix;

char *cpp_snapchromatix;

char *cpp_videochromatix;

char *cpp_liveshotchromatix;

char *postproc_chromatix;

};

sensor_lib_chromatix.common_chromatix - 爲當前傳感器模式/分辨率設置指向公共(VFE)chromatix的指針。

sensor_lib_chromatix.camera_preview_chromatix - 設置指針以預覽chromatix

用於當前的傳感器模式/分辨率。當模式用於圖像預覽時,它被加載。

sensor_lib_chromatix.camera_snapshot_chromatix - 爲當前傳感器模式/分辨率設置指向快照chromatix的指針。當模式用於快照時加載。

sensor_lib_chromatix.camcorder_chromatix - 爲當前傳感器模式/分辨率設置指向攝像機chromatix的指針。當模式用於視頻預覽/錄製時,它被加載。

sensor_lib_chromatix.liveshot_chromatix - 設置指向livehot chromatix的指針電流傳感器模式/分辨率。在拍攝時拍攝(快照,錄像)。

sensor_lib_chromatix.cpp_chromatix - 爲當前傳感器模式/分辨率設置指向cpp chromatix的指針。當模式用於圖像預覽時,將被加載。

sensor_lib_chromatix.cpp_snapchromatix - 爲當前傳感器模式/分辨率設置指向cpp snapshot chromatix的指針。當模式用於快照時加載。

sensor_lib_chromatix.cpp_videochromatix - 爲當前傳感器模式/分辨率設置指向cpp video chromatix的指針。當模式用於視頻預覽/錄製時,它被加載。

sensor_lib_chromatix.cpp_liveshotchromatix - 設置指向cpp的照片chromatix

用於當前的傳感器模式/分辨率。在拍攝時拍攝(快照,錄像)。

sensor_lib_chromatix.postproc_chromatix - 爲當前傳感器模式/分辨率設置指向後處理chromatix的指針。它用於軟件後處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章