本文轉載自:http://blog.sina.com.cn/s/blog_c0de2be70102vyn1.html
1 camera基本代碼架構
高通平台對於camera的代碼組織,大體上還是遵循Android的框架:即上層應用和HAL層交互,高通平台在HAL層里面實現自己的一套管理策略;在kernel中實現sensor的底層驅動。但是,對於最核心的sensor端的底層設置、ISP效果相關等代碼則是單獨進行了抽離,放在了一個 daemon進程中進行管理:

圖1 Qualcomm平台camera代碼架構簡圖
由於高通把大部分具體的設置及參數放到了daemon進程中,所以在kernel部分只是進行了V4L2的設備注冊、IIC設備注冊等簡單的動作:

圖2 kernel層camera主要代碼簡圖
如上圖,camera在kernel層的主文件為msm.c,負責設備的具體注冊及相關方法的填充;在msm_sensor.c文件中,主要維護高通自己的一個sensor相關結構體—msm_sensor_ctrl_t,同時把dts文件中的配置信息讀取出來;kernel層對於不同的sensor對應自己的一個驅動文件— xxsensor.c,主要是把power setting的設定填充到msm_sensor_ctrl_t中。
在vendor目錄下,高通把各個sensor實質性的代碼放置在此。一部分代碼是高通自己實現的daemon進程和kernel層及HAL層進行通訊的框架代碼;另一部分則是和sensor相關的chromatix效果代碼和sensor lib部分代碼(init setting、lens info、output info)。

圖3 vendor下主要camera代碼簡圖
如上圖,高通平台通過一個函數指針數組sub_module_init來管理sensor相關的 組件;其中重要的是sensor_sub_module_init和chromatix_sub_module_init模塊,對於sensor模塊需要對應填充sensor_lib_t下的接口,對於chromatix模塊則是通過高通的chromatix工具生成。
從更高的層次來看,sensor部分的代碼只是camera子系統的一部分。打開高通vendor下面關於camera的源碼也可以看到,/mm- camera2/media-controller/modules目錄下面,sensors只是modules文件下面其中的一個子目錄。

圖4 高通camera子系統模塊草圖
2 主要移植步驟
2.1 kernel層代碼移植
對於kernel層的代碼移植,實際上對dts文件的移植。因為kernel層驅動代碼基本已經被高通的框架以及vendor下代碼架空,只剩下一個上電的列表。具體步驟為:
1. 在目錄kernel/arch/arm/boot/dts/下的對應dtsi文件中新增camera節點,主要關注節點中的IIC地址、sensro的ID信息、電壓設定信息:

圖5 dtsi中camera中的節點信息截選
2.在目錄kernel/drivers/media/platform/msm /camera_v2/sensor/目錄新增xxsensor.c文件,主要填充msm_sensor_power_setting結構體:sensor上電的包含的引腳設定和電壓設定,具體格式可以參考同目錄下的其他文件。
3. kernel下面的相關mk文件:

圖6 kernel目錄下camera相關配置文件
其他:如果sensor中帶有eeprom,需要在dts文件中增加eeprom的節點信息;同樣,sensor帶有對焦功能,需要在dts文件中增加actuator節點信息;對於帶eeprom的sensor,還需要配置eeprom的時鍾控制代碼(有待研究)。
2.2 vendor下代碼移植
Vendor下面的代碼主要是兩部分,一個是sensor_libs目錄下的sensor具體設定、配置文件,另一個是chromatix下面的ISP效果文件。具體為:
1. sensor_libs目錄下文件:包括一個Android.mk文件和一個.c文件。其中Android.mk文件參考同目錄下其他.mk文件修改和對應sensor有關設定即可;.c文件中需要填充的為一個sensor_lib_t類型的結構體:

圖7 sensor_lib_t成員截選圖
2. chromatix目錄下相關文件,在對應sensor目錄下包含4個目錄和一個Android文件,總共13個文件,這些文件都會由chromatix調試工具生成。下面為IMX179文件實例:

圖8 vendor下chromatix相關文件示例圖
3. vendor下還有eeprom文件,模組自帶的eeprom數據處理相關;AF相關文件,調試工具生成的關於AF的效果文件;配置文件,把需要編譯的模塊填進配置文件中。

圖9 vendor下其他camera文件
3 調試常見問題
3.1 kernel和vendor下命名匹配
對於不是高通釋放的標准驅動來說,在參考其他代碼移植調試一個新sensor的過程中,要注意在對應的dts文件中給sensor配置節點信息的過程中,“qcom,sensor-name”字段的配置要和vendor下面的sensor lib代碼中的“xxx_open_lib”函數名以及對應的Android.mk中的“LOCAL_MODULE”名稱匹配,否則相應sensor的 vendor下庫文件無法調用,這時打開camera會出現閃退現象。具體可參考平台代碼sensor.c中的 sensor_load_library()函數。

圖10 camera name匹配詳圖
3.2 sensor lib中的sensor_lib_out_info_t填充
一般來說,每個sensor可以配置輸出不同大小的圖像。此時,除了進行對應的sensor setting來改變sensor自身的輸出及相關配置外;還需要將相關的輸出大小、幀率等信息通知平台端,即填充struct sensor_lib_out_info_t結構體。

圖11 高通平台獲取sensor信息框圖
填充的這個sensor_lib_out_info_t中的成員,最終會作為sensor基本信息的一部分被HAL層獲取到,上圖為高通平台獲取sensor信息的一個簡單框圖。
在調試過程中,需要注意的是這個結構體的成員max_fps需要填寫至少大於等於30;否則會因為在獲取capability時無法得到有效的 previewsize、video size而無法進入預覽。具體可參考平台代碼mct_pipeline.c中的 mct_pipeline_populate_query_cap_buffer()函數。
3.3 sensorlib中的exposure_table_size填寫
對於sensor端輸出RAW數據,平台端進行ISP處理的情形來說,sensor端除了基本的init配置外,另外一個就是根據平台端AEC計算出來的數據來對應調整sensor的曝光。在高通平台上將平台端的AEC和具體的sensor曝光設置聯系起來的是chromatix文件中的一個 Exposure Table和sensor lib文件中的exposure對應接口。
這里的exposure_table_size對應着sensor lib中sensor_fill_exposure_array() 接口寫入的sensor寄存器的個數,平台代碼中需要根據這個 exposure_table_size來動態分配內存大小。如果這個值的填寫和sensor_fill_exposure_array()中實際寫入的值大小不一致,就會造成內存方面的crash。具體可參考平台代碼sensor.c中的sensor_apply_exposure()函數。
3.4 kernel 層非常規設定
一般情況下,一個新sensor的移植和調試需要在kernel層進行的工作基本上沒有問題。但是對於一些sensor來說,對於電壓的設定或是MCLK的設定有非常規要求的時候,可能就需要修改平台上相關的默認設定。
對於sensor的幾路工作電壓 (AVDD、DVDD、IOVDD),平台端一般都是通過PMIC的相應regulator供電,而硬件上regulator的輸出能力一般都有限制,代碼上也會有體現。如果有sensor需要的電壓超過代碼上相應regulator的限制值,可以查看PMIC上的說明,如果代碼上的限制值並不是硬件的真正極限,可以修改平台代碼解決。
對於MCLK的設定,高通平台有一些常規的值設定。如果sensor有特殊要求,而這個MCLK不能被平台識別,這時候可以在平台的clock相關代碼中,通過配置平台的PLL參數來生成特定的MCLK時鍾給sensor使用。

圖12 kernel非常規設定代碼片段
