Linux MIPI CSI 開發(fā)指南
1 前言
1.1 文檔簡介
介紹 VIN(video input)驅(qū)動配置,API 接口和上層使用方法。
1.2 目標讀者
camera 驅(qū)動開發(fā)、維護人員和應用開發(fā)人員。
1.3 適用范圍
表 1-1: 適用產(chǎn)品列表
內(nèi)核版本 | 驅(qū)動文件 |
---|---|
Linux-4.9 | drivers/media/platform/sunxi_vin/*.c |
Linux-5.4 | drivers/media/platform/sunxi_vin/*.c |
2 模塊介紹
2.1 模塊功能介紹
Video input 主要由接口部分(CSI/MIPI)和圖像處理單元(ISP/VIPP)組成;
CSI/MIPI 部分主要實現(xiàn)視頻數(shù)據(jù)的捕捉;
ISP 實現(xiàn) sensor raw data 數(shù)據(jù)的處理,包括 lens 補償、去壞點、gain、gamma、de-mosaic、de-noise、color matrix 等以及一些 3A 的統(tǒng)計;
VIPP 能對將圖進行縮小、和打水印處理。VIPP 支持 bayer raw data 經(jīng)過 ISP 處理后再縮小,也支持對一般的 YUV 格式的 sensor 圖像直接縮小。
2.2 相關術語介紹
表 2-1: 軟件術語
相關術語 | 解釋說明 |
---|---|
ISP | Image Signal Processor 圖像信號處理 |
VIPP | Video Input Post Processor 圖像輸入后處理 |
MIPI | Mobile Industry Processor Interface 移動工業(yè)處理接口 |
CCI | Camera Control Interface 攝像頭控制接口 |
TDM | Time division multiplexing ISP 時分復用 |
MCLK | Master clock(From AP to camera)攝像頭主時鐘 |
PCLK | Pixel clock(From camera to AP,Sampling clock for data-bus)像素時鐘 |
YUV | Color Presentation(Y for luminance,U&V for Chrominance)圖像數(shù)據(jù)格式 |
2.3 驅(qū)動框架介紹
圖 2-1: 驅(qū)動框圖
VIN 驅(qū)動可以分為 Kernel 層、Video Input Framework、Device Driver 層。
2.3.1 Kernel 層
V4l2 Framework;
Linux 內(nèi)核視頻驅(qū)動第二版(Video for Linux Two );
3) 適用于收音機、視頻編解碼、視頻捕獲以及視頻輸出設備驅(qū)動;
4) 提供/dev/videoX 節(jié)點,應用通過該節(jié)點進行相應視頻流和控制操作;
Media Device Framework;
Linux 多媒體設備框架;
7) 適用于管理設備拓撲結(jié)構(gòu);
8) 提供/dev/mediaX 節(jié)點,通過該節(jié)點應用可以獲取媒體設備拓撲結(jié)構(gòu),并能夠通過 API 控制子設備間數(shù)據(jù)流向。
2.3.2 Video Input Framework 層
Video Control : 視頻命令處理(分辨率協(xié)商,數(shù)據(jù)格式處理,Buffer 管理等);
Runtime Handle : 運行時管理(Pipeline 管理,系統(tǒng)資源管理,中斷調(diào)度等);
Event Process : 事件管理(如上層調(diào)用,中斷等事件的接收與分發(fā));
Config Handle : 配置管理(如硬件拓撲結(jié)構(gòu),模組自適應列表等)。
2.3.3 Device Driver 層
Camera Modules : 模組驅(qū)動(圖像傳感器,對焦電機,閃光燈等驅(qū)動);
Camera Interfac : 接口驅(qū)動(MIPI、Sub-Lvds 、HiSpi、Bt656、Bt601、Bt1120、DC等);
Image Signal Processor : 圖像處理器驅(qū)動(基本處理模塊驅(qū)動,3A 統(tǒng)計驅(qū)動);
Video Input Post Processor : 視頻輸入后處理(Scaler,OSD 等)。
2.4 模塊配置介紹
2.4.1 kernel menuconfig 配置
首先,進入 Device Drivers,選擇 Multimedia support ,然后依次打開 Cameras/video grabbers support 、Media Controller support 和 SUNXI platform devices, 如下圖所示。
圖 2-2: Device Drivers 選項配置
其次,進入 SUNXI platform devices,選擇 sunxi video input (camera csi/mipi isp vipp)driver 和 v4l2 new driver for SUNXI,如下圖所示。
圖 2-3: Device Drivers 選項配置
最后,sunxi video input (camera csi/mipi isp vipp)driver 目錄下的其他選項需要根據(jù)實際產(chǎn)品需求進行開關,如:使用閃光燈、對焦馬達、打開 vin log、使用 IOMMU 如下圖所示。
圖 2-4: Device Drivers 選項配置
2.4.2 Device Tree 配置說明
? 設備樹文件的配置是該 SoC 所有方案的通用配置,對于 ARM64 CPU 而言,設備樹的路徑為:kernel/{KERNEL_VERSION}/arch/arm64/boot/dts/sunxi/sun*.dtsi。
? 設備樹文件的配置是該 SoC 所有方案的通用配置,對于 ARM32 CPU 而言,設備樹的路徑為:kernel/{KERNEL_VERSION}/arch/arm/boot/dts/sun*.dtsi。
? 板級設備樹 (board.dts) 路徑:
/device/config/chips/{IC}/configs/{BOARD}/KERNEL_VERSION/board.dts。
在 sun.dtsi 文件中,配置了該 SoC 的 CSI 控制器的通用配置信息,一般不建議修改,由 CSI 驅(qū)動維護者維護,如果需要修改配置請修改板級設備樹 board.dts,板級設備樹里面的內(nèi)容會覆蓋sun.dtsi 對應的信息。
? vind 配置
&vind0 {
vind0_clk = <336000000>;
vind0_isp = <300000000>;
status = "okay";
tdm0:tdm@0 {
work_mode = <0>;
};
isp00:isp@0 {
work_mode = <0>;
};
scaler00:scaler@0 {
work_mode = <0>;
};
scaler10:scaler@4 {
work_mode = <0>;
};
scaler20:scaler@8 {
work_mode = <0>;
};
scaler30:scaler@12 {
work_mode = <0>;
};
actuator0:actuator@0 {
device_type = "actuator0";
actuator0_name = "ad5820_act";
actuator0_slave = <0x18>;
actuator0_af_pwdn = <>;
actuator0_afvdd = "afvcc-csi";
actuator0_afvdd_vol = <2800000>;
status = "disabled";
};
flash0:flash@0 {
device_type = "flash0";
flash0_type = <2>;
flash0_en = <>;
flash0_mode = <>;
flash0_flvdd = "";
flash0_flvdd_vol = <>;
status = "disabled";
};
sensor0:sensor@0 {
device_type = "sensor0";
sensor0_mname = "gc2053_mipi";
sensor0_twi_cci_id = <1>;
sensor0_twi_addr = <0x6e>;
sensor0_mclk_id = <0>;
sensor0_pos = "rear";
sensor0_isp_used = <1>;
sensor0_fmt = <1>;
sensor0_stby_mode = <0>;
sensor0_vflip = <0>;
sensor0_hflip = <0>;
sensor0_iovdd-supply = ;
sensor0_iovdd_vol = <1800000>;
sensor0_avdd-supply = ;
sensor0_avdd_vol = <2800000>;
sensor0_dvdd-supply = ;
sensor0_dvdd_vol = <1200000>;
sensor0_power_en = <>;
sensor0_reset = <&pio PA 18 1 0 1 0>;
sensor0_pwdn = <&pio PA 19 1 0 1 0>;
sensor0_sm_hs = <>;
sensor0_sm_vs = <>;
flash_handle = <&flash0>;
act_handle = <&actuator0>;
status = "okay";
};
sensor1:sensor@1 {
device_type = "sensor1";
sensor1_mname = "imx386_mipi_2";
sensor1_twi_cci_id = <0>;
sensor1_twi_addr = <0x20>;
sensor1_mclk_id = <1>;
sensor1_pos = "front";
sensor1_isp_used = <1>;
sensor1_fmt = <1>;
sensor1_stby_mode = <0>;
sensor1_vflip = <0>;
sensor1_hflip = <0>;
sensor1_iovdd-supply = ;
sensor1_iovdd_vol = <1800000>;
sensor1_avdd-supply = ;
sensor1_avdd_vol = <2800000>;
sensor1_dvdd-supply = ;
sensor1_dvdd_vol = <1200000>;
sensor1_power_en = <>;
sensor1_reset = <&pio PA 20 1 0 1 0>;
sensor1_pwdn = <&pio PA 21 1 0 1 0>;
sensor1_sm_hs = <>;
sensor1_sm_vs = <>;
flash_handle = <>;
act_handle = <>;
status = "okay";
};
vinc00:vinc@0 {
vinc0_csi_sel = <0>;
vinc0_mipi_sel = <0>;
vinc0_isp_sel = <0>;
vinc0_isp_tx_ch = <0>;
vinc0_tdm_rx_sel = <0>;
vinc0_rear_sensor_sel = <0>;
vinc0_front_sensor_sel = <0>;
vinc0_sensor_list = <0>;
work_mode = <0x0>;
status = "okay";
};
vinc01:vinc@1 {
vinc1_csi_sel = <2>;
vinc1_mipi_sel = <0xff>;
vinc1_isp_sel = <1>;
vinc1_isp_tx_ch = <1>;
vinc1_tdm_rx_sel = <1>;
vinc1_rear_sensor_sel = <0>;
vinc1_front_sensor_sel = <0>;
vinc1_sensor_list = <0>;
status = "disabled";
};
vinc02:vinc@2 {
vinc2_csi_sel = <2>;
vinc2_mipi_sel = <0xff>;
vinc2_isp_sel = <2>;
vinc2_isp_tx_ch = <2>;
vinc2_tdm_rx_sel = <2>;
vinc2_rear_sensor_sel = <0>;
vinc2_front_sensor_sel = <0>;
vinc2_sensor_list = <0>;
status = "disabled";
};
vinc03:vinc@3 {
vinc3_csi_sel = <0>;
vinc3_mipi_sel = <0xff>;
vinc3_isp_sel = <0>;
vinc3_isp_tx_ch = <0>;
vinc3_tdm_rx_sel = <0>;
vinc3_rear_sensor_sel = <1>;
vinc3_front_sensor_sel = <1>;
vinc3_sensor_list = <0>;
status = "disabled";
};
…………
};
其中:
status 是 vin 驅(qū)動的總開關,對應的是 media 設備,使用 vin 時必須設為 okay;
vind0_clk 是 vin 模塊的時鐘,實際使用時可以根據(jù) sensor 的幀率和分辨率來設置;
vind0_isp 是 isp 模塊時鐘,實際使用時可以根據(jù) sensor 的幀率和分辨率來設置;
vind0_clk 表示 csi clk,計算公式:幀率 x (vts)x (hts)x 1(wdr 則為 2) / 8 / 1(雙 pixel則為 2) / 1000000,向上取整,單位為 MH;vind0_isp 表示 isp clk,計算公式:幀率 x 寬 x 高 x 1.2 / 1000000,向上取整,單位為 MH;其中有些 ic 是沒有 isp_clk,csi_clk 和isp_clk 都是設置在 vind0_clk。那么 vind0_clk 設置為 csi_clk 和 isp_clk 中最大的數(shù)值;
work_mode: 0:online mode 1:offline mode, 根據(jù)使用需求配置;
flash0_type: 0:FLASH_RELATING, 1:FLASH_EN_INDEPEND, 2:FLASH_POWER
flash0_en: flash enable gpio, type = 0 of 1
flash0_mode: flash mode gpio, type = 0 of 1
flash0_flvdd: flash module io power handle string, pmu power supply, type = 2
flash0_flvdd_vol: flash module io power voltage, pmu power supply, type = 2
status: 是否使用 flash, disable 代表關,okay 代表開
actuator0_name: vcm name
actuator0_slave: vcm iic slave address
actuator0_af_pwdn: vcm power down gpio
actuator0_afvdd: vcm power handle string, pmu power supply
actuator0_afvdd_vol: vcm power voltage, pmu power supply
status: vcm if used, disable 代表關,okay 代表開
device_type: sensor type sensor0_mname: sensor name
sensor0_twi_cci_id:sensor 所使用的 twi 或者 cci 的 id。
sensor0_twi_addr:sensor 的 twi 地址
sensor0_mclk_id:sensor 所使用的 mclk 的 id。
sensor0_pos:sensor 的位置,前置還是后置,主要用在平板上。
sensor0_isp_used: not use isp 1:use isp
sensor0_fmt: 0:yuv 1:bayer raw rgb
sensor0_stby_mode: not shut down power at standby 1:shut down power at standby
sensor0_vflip: flip in vertical direction 0:disable 1:enable
sensor0_hflip: flip in horizontal direction 0:disable 1:enable
sensor0_iovdd-supply: camera module io power handle string, pmu power supply
sensor0_iovdd_vol: camera module io power voltage, pmu power supply
sensor0_avdd-supply: camera module analog power handle string, pmu power supply
sensor0_avdd_vol: camera module analog power voltage, pmu power supply
sensor0_dvdd-supply: camera module core power handle string, pmu power supply
sensor0_dvdd_vol: camera module core power voltage, pmu power supply
sensor0_power_en: camera module power enable gpio
sensor0_reset: camera module reset gpio
sensor0_pwdn: camera module pwdn gpio sensor0_sm_hs: camera module sm_hs
gpio sensor0_sm_vs: camera module sm_vs gpio status: open or close sensor de
vice flash/actautor/sensor 節(jié)點用于對應的外設的開關和配置。這些節(jié)點的配置一般需要參
考對應方案的原理圖和外設的 data sheet 來完成。
vinc0_csi_sel:表示該 pipeline 上 parser 的 id,必須配置,且為有效 id。
vinc0_mipi_sel:表示該 pipeline 上 mipi(sublvds/hispi)的 id,不使用時配置為 0xff。
vinc0_isp_sel:表示該 pipeline 上 isp 的 id,必須配置,當 isp 為空時,這個 isp 只是表示路由不做 isp 的效果處理。
vinc0_isp_tx_ch 表示該 pipeline 上 isp 的 ch,必須配置,默認為 0。當 sensor 是 bt656 多通道或者 WDR 出 RAW 時,該 ch 可以配置 0~3 的值。
vinc0_tdm_rx_sel: 表示該 pipeline 上 tdm rx 的 ch,必須配置,默認為 0。當不使用 tdm功能時,配置為 0xff;
vinc0_rear_sensor_sel 表示該 pipeline 上使用的后置 sensor 的 id。
vinc0_front_sensor_sel 表示該 pipeline 上使用的前置 sensor 的 id。
vinc0_sensor_list 表示是否使用 sensor_list 來時適配不同的模組,1 表示使用,0 表示不使用。
work_mode: 0:online mode 1:offline mode, 根據(jù)使用需求配置;只有 vinc0/4/8/12 可以配置。
status:vipp 的使能開關,okay or disable。
2.5 源碼模塊結(jié)構(gòu)
驅(qū)動路徑位于 drivers/media/platform/sunxi-vin 目錄。
sunxi-vin:.
├── Kconfig
├── Makefile
├── modules
│ ├── actuator
│ │ ├── actuator.c ;vcm driver的一般行為
│ │ ├── actuator.h ;vcm driver的頭文件
│ │ ├── ad5820_act.c ;具體vcm driver型號實現(xiàn)
│ │ ├── an41908a_act.c ;具體vcm driver型號實現(xiàn)
│ │ ├── dw9714_act.c ;具體vcm driver型號實現(xiàn)
│ │ ├── Makefile ;編譯文件
│ ├── flash
│ │ ├── flash.c ;led補光燈控制實現(xiàn)
│ │ ├── flash.h ;led補光燈驅(qū)動頭文件
│ └── sensor
│ ├── ar0238.c ;具體的sensor驅(qū)動
│ ├── camera_cfg.h ;camera ioctl擴展命令頭文件
│ ├── camera.h ;camera公用結(jié)構(gòu)體頭文件
│ ├── gc030a_mipi.c ;具體的sensor驅(qū)動
│ ├── gc0310_mipi.c ;具體的sensor驅(qū)動
│ ├── gc5024_mipi.c ;具體的sensor驅(qū)動
│ ├── imx179_mipi.c ;具體的sensor驅(qū)動
│ ├── imx214.c ;具體的sensor驅(qū)動
│ ├── imx219.c ;具體的sensor驅(qū)動
│ ├── imx317_mipi.c ;具體的sensor驅(qū)動
│ ├── Makefile ;驅(qū)動的編譯文件
│ ├── nvp6134 ;具體的dvp sensor驅(qū)動
│ │ ├── acp.c
│ │ ├── acp_firmup.c
│ │ ├── acp_firmup.h
│ │ ├── acp.h
│ │ ├── common.h
│ │ ├── csi_dev_nvp6134.c
│ │ ├── csi_dev_nvp6134.h
│ │ ├── eq.c
│ │ ├── eq_common.c
│ │ ├── eq_common.h
│ │ ├── eq.h
│ │ ├── eq_recovery.c
│ │ ├── eq_recovery.h
│ │ ├── Makefile
│ │ ├── nvp6134c.c ;具體的sensor驅(qū)動實現(xiàn)
│ │ ├── type.h
│ │ ├── video.c
│ │ └── video.h
│ ├── nvp6158 ;具體的dvp sensor驅(qū)動
│ │ ├── audio.c ;音頻部分實現(xiàn)
│ │ ├── audio.h ;音頻部分頭文件接口
│ │ ├── coax_protocol.c
│ │ ├── coax_protocol.h
│ │ ├── coax_table.h
│ │ ├── common.h
│ │ ├── Makefile
│ │ ├── modules.builtin
│ │ ├── modules.order
│ │ ├── motion.c
│ │ ├── motion.h
│ │ ├── nvp6158c.c ;具體的sensor驅(qū)動實現(xiàn)
│ │ ├── nvp6158_drv.c
│ │ ├── nvp6158_drv.h
│ │ ├── nvp6168_eq_table.h
│ │ ├── video_auto_detect.c
│ │ ├── video_auto_detect.h
│ │ ├── video.c
│ │ ├── video_eq.c
│ │ ├── video_eq.h
│ │ ├── video_eq_table.h
│ │ ├── video.h
│ ├── rn6854m_mipi.c ;具體的sensor驅(qū)動實現(xiàn)
│ ├── sensor-compat-ioctl32.c
│ ├── sensor_helper.c ;驅(qū)動函數(shù)接口的實現(xiàn)
│ ├── sensor_helper.h ;驅(qū)動函數(shù)接口的定義
├── modules.builtin
├── modules.order
├── platform
│ ├── platform_cfg.h ;vin平臺配置文件
│ ├── sun50iw10p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun50iw3p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun50iw6p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun50iw9p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun8iw12p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun8iw15p1_vin_cfg.h ;不同平臺配置文件
│ ├── sun8iw16p1_vin_cfg.h ;不同平臺配置文件
│ └── sun8iw19p1_vin_cfg.h ;不同平臺配置文件
├── top_reg.c
├── top_reg.h
├── top_reg_i.h
├── top_reg.o
├── utility
│ ├── bsp_common.c
│ ├── bsp_common.h
│ ├── bsp_common.o
│ ├── cfg_op.c ;讀取ini文件的實現(xiàn)函數(shù)
│ ├── cfg_op.h ;讀取ini文件的實現(xiàn)函數(shù)
│ ├── config.c ;sensor電壓、通道選擇、i2c地址等信息讀取函數(shù)
│ ├── config.h ;sensor電壓、通道選擇、i2c地址等信息讀取函數(shù)頭文件
│ ├── vin_io.h ;vin模塊寄存器操作頭文件
│ ├── vin_os.c
│ ├── vin_os.h
│ ├── vin_supply.c
│ ├── vin_supply.h
├── vin.c
├── vin-cci
│ ├── bsp_cci.c ;底層cci bsp函數(shù)
│ ├── bsp_cci.h ;底層cci bsp函數(shù)頭文件
│ ├── cci_helper.c ;cci 幫助函數(shù),供sensor驅(qū)動調(diào)用
│ ├── cci_helper.h ;cci 幫助函數(shù)頭文件
│ ├── csi_cci_reg.c ;cci硬件底層實現(xiàn)
│ ├── csi_cci_reg.h ;cci硬件底層實現(xiàn)頭文件
│ ├── csi_cci_reg_i.h ;cci 寄存器資源頭文件
│ ├── Kconfig
│ ├── sunxi_cci.c ;cci 平臺驅(qū)動源文件
│ ├── sunxi_cci.h ;cci 平臺驅(qū)動頭文件
├── vin-csi
│ ├── parser_reg.c ;CSI控制函數(shù)
│ ├── parser_reg.h ;CSI控制函數(shù)頭文件
│ ├── parser_reg_i.h ;CSI 寄存器值
│ ├── sunxi_csi.c ;csi 子模塊驅(qū)動原文件
│ ├── sunxi_csi.h ;csi 子模塊驅(qū)動頭文件
├── vin.h
├── vin-isp
│ ├── isp500
│ │ ├── isp500_reg_cfg.c
│ │ ├── isp500_reg_cfg.h
│ │ ├── isp500_reg_cfg.o
│ │ └── isp500_reg.h
│ ├── isp520
│ │ ├── isp520_reg_cfg.c
│ │ ├── isp520_reg_cfg.h
│ │ └── isp520_reg.h
│ ├── isp521
│ │ ├── isp521_reg_cfg.c
│ │ ├── isp521_reg_cfg.h
│ │ └── isp521_reg.h
│ ├── isp522
│ │ ├── isp522_reg_cfg.c
│ │ ├── isp522_reg_cfg.h
│ │ └── isp522_reg.h
│ ├── isp_default_tbl.h
│ ├── sunxi_isp.c
│ ├── sunxi_isp.h
│ └── sunxi_isp.o
├── vin-mipi
│ ├── bsp_mipi_csi.c ;底層mipi bsp函數(shù)
│ ├── bsp_mipi_csi.h ;底層mipi bsp函數(shù)頭文件
│ ├── bsp_mipi_csi_null.c ;底層mipi bsp空函數(shù)
│ ├── bsp_mipi_csi_v1.c ;底層mipi bsp函數(shù)--v1
│ ├── combo_common.h
│ ├── combo_csi
│ │ ├── combo_csi_reg.c
│ │ ├── combo_csi_reg.h
│ │ └── combo_csi_reg_i.h
│ ├── combo_rx
│ │ ├── combo_rx_reg.c
│ │ ├── combo_rx_reg.h
│ │ ├── combo_rx_reg_i.h
│ │ └── combo_rx_reg_null.c
│ ├── dphy
│ │ ├── dphy.h ;mipi dphy頭文件
│ │ ├── dphy_reg.c ;mipi dphy底層實現(xiàn)函數(shù)
│ │ ├── dphy_reg.h ;mipi dphy底層實現(xiàn)函數(shù)頭文件
│ │ └── dphy_reg_i.h ;mipi dphy 寄存器資源頭文件
│ ├── protocol
│ │ ├── protocol.h ;mipi協(xié)議層頭文件
│ │ ├── protocol_reg.c ;mipi協(xié)議層底層實現(xiàn)
│ │ ├── protocol_reg.h ;mipi協(xié)議層底層實現(xiàn)頭文件
│ │ └── protocol_reg_i.h
│ ├── protocol.h
│ ├── sunxi_mipi.c
│ ├── sunxi_mipi.h
├── vin-stat
│ ├── vin_h3a.c ;3A控制接口函數(shù)
│ ├── vin_h3a.h ;3A控制接口函數(shù)頭文件
├── vin-tdm
│ ├── tdm_reg.c ;TDM寄存器控制函數(shù)
│ ├── tdm_reg.h
│ ├── tdm_reg_i.h
│ ├── vin_tdm.c
│ └── vin_tdm.h
├── vin_test
│ ├── mplane_image
│ │ ├── csi_test_mplane.c ;camera抓圖測試用例
│ │ └── Makefile ;測試用例編譯文件
│ ├── sunxi_camera_v2.h
│ └── sunxi_display2.h
├── vin-video
│ ├── dma_reg.c ;csi dma寄存器控制函數(shù)
│ ├── dma_reg.h ;csi dma寄存器控制函數(shù)
│ ├── dma_reg_i.h ;csi dma 寄存器值定義頭文件
│ ├── vin_core.c ;vin模塊核心
│ ├── vin_core.h ;vin模塊核心頭文件
│ ├── vin_video.c ; 數(shù)據(jù)格式處理、pipe通道選擇、Buffer管理等函數(shù)
│ ├── vin_video.h ;數(shù)據(jù)格式處理、pipe通道選擇、Buffer管理等函數(shù)頭文件
└── vin-vipp
├── sunxi_scaler.c ;圖像壓縮處理函數(shù)
├── sunxi_scaler.h ;圖像壓縮處理函數(shù)頭文件
├── vipp_reg.c ;vipp寄存器控制函數(shù)
├── vipp_reg.h ;vipp寄存器控制函數(shù)頭文件
├── vipp_reg_i.h ;vipp寄存器具體描述頭文件
3 V4L2 接口描述
3.1 VIDIOC_QUERYCAP
3.1.1 Parameters
Capability of csi driver(struct v4l2_capability * capability)
struct v4l2_capability {
__u8 driver[16]; /* i.e. "bttv" */
__u8 card[32]; /* i.e. "Hauppauge WinTV" */
__u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
__u32 version; /* should use KERNEL_VERSION() */
__u32 capabilities; /* Device capabilities */
__u32 reserved[4];
};
3.1.2 Returns
Success:0; Fail: Failure Number
3.1.3 Description
獲取驅(qū)動的名稱、版本、支持的 capabilities 等,如 V4L2_CAP_STREAMIN,V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 等。
3.2 VIDIOC_ENUM_INPUT
3.2.1 Parameters
input(struct v4l2_input *inp)
struct v4l2_input {
__u32 index; /* Which input */
__u8 name[32]; /* Label */
__u32 type; /* Type of input */
__u32 audioset; /* Associated audios (bitfield) */
__u32 tuner; /* Associated tuner */
v4l2_std_id std;
__u32 status;
__u32 capabilities;
__u32 reserved[3];
};
3.2.2 Returns
Success:0; Fail: Failure Number
3.2.3 Description
獲取驅(qū)動支持的 input index。目前驅(qū)動只支持 input index = 0 或 index = 1。
Index = 0 表示 primary csi device
Index = 1 表示 secondary csi device
應用輸入 index 參數(shù),驅(qū)動返回 type。對于 VIN 設備來說,type 為 V4L2_INPUT_TYPE_CAMERA。
3.3 VIDIOC_S_INPUT
3.3.1 Parameters
input(struct v4l2_input *inp)
The same as VIDIOC_ENUM_INPUT
3.3.2 Returns
Success:0; Fail: Failure Number
3.3.3 Description
通過 inp.index 設置當前要訪問的 csi device 為 primary device 還是 secondary device。
Index = 0 (雙攝像頭配置中,一般對應后置攝像頭。若只有一個攝像頭設備,則 index 固定為0)
Index = 1(雙攝像頭配置中,一般對應前置攝像頭)
調(diào)用該接口后,實際上會對 csi device 進行初始化工作。
在 A133 平臺:Index 在 video0、1 時固定要設為 0;在 video2、3 要設為 1。
3.4 VIDIOC_G_INPUT
3.4.1 Parameters
input(struct v4l2_input *inp)
The same as VIDIOC_ENUM_INPUT
3.4.2 Returns
Success:0; Fail: Failure Number
3.4.3 Description
獲取 inp.index,判斷當前設置的 csi device 為 primary device 還是 secondary device。
Index = 0 (雙攝像頭配置中,一般對應后置攝像頭。若只有一個攝像頭設備,則 index 固定為0)
Index = 1(雙攝像頭配置中,一般對應前置攝像頭)
3.5 VIDIOC_S_PARM
3.5.1 Parameters
Parameter(struct v4l2_streamparm *parms)
struct v4l2_streamparm {
enum v4l2_buf_type type;
union {
struct v4l2_captureparm capture;
struct v4l2_outputparm output;
__u8 raw_data[200]; /* user-defined */
} parm;
};
struct v4l2_captureparm {
__u32 capability; /* Supported modes */
__u32 capturemode; /* Current mode */
struct v4l2_fract timeperframe; /* Time per frame in .1us units */
__u32 extendedmode; /* Driver-specific extensions */
__u32 readbuffers; /* # of buffers for read */
__u32 reserved[4];
};
3.5.2 Returns
Success:0; Fail: Failure Number
3.5.3 Description
CSI 作為輸入設備,只關注 parms.type 和 parms. capture。
應用使用時,parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
其中通過設定 parms->capture.capturemode(V4L2_MODE_VIDEO 或 V4L2_MODE_IMAGE),
實現(xiàn)視頻或圖片的采集。通過設定 parms->capture.timeperframe,可以設置幀率。
3.6 VIDIOC_G_PARM
3.6.1 Parameters
Parameter(struct v4l2_streamparm *parms)
The same as VIDIOC_S_PARM
3.6.2 Returns
Success:0; Fail: Failure Number
3.6.3 Description
應用使用時,parms.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
通過 parms->capture.capturemode 返回當前是 V4L2_MODE_VIDEO 或 V4L2_MODE_IMAGE;
通過 parms->capture.timeperframe, 返回當前設置的幀率。
3.7 VIDIOC_ENUM_FMT
3.7.1 Parameters
V4L2 format(struct v4l2_fmtdesc * fmtdesc) struct v4l2_fmtdesc { __u32 index; /* Format number */ enum v4l2_buf_type type; /* buffer type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ __u32 reserved[4]; };
3.7.2 Returns
Success:0; Fail: Failure Number
3.7.3 Description
獲取驅(qū)動支持的 V4L2 格式。
應用輸入 type,index 參數(shù),驅(qū)動返回 pixelformat 。對于 VIN 設備來說,type 為V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。
3.8 VIDIOC_TRY_FMT
3.8.1 Parameters
Video type, format and size(struct v4l2_format * fmt) struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; struct v4l2_pix_format_mplane pix_mp; struct v4l2_window win; struct v4l2_vbi_format vbi; struct v4l2_sliced_vbi_format sliced; __u8 raw_data[200]; } fmt; }; struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; enum v4l2_field field; __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; /* private data, depends on pixelformat */ };
3.8.2 Returns
Success:0; Fail: Failure Number
3.8.3 Description
根據(jù)捕捉視頻的類型、格式和大小,判斷模式、格式等是否被驅(qū)動支持。不會改變?nèi)魏斡布O置。
對于 VIN 設備,type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。使用 struct v4l2_pix_format_mplane 進行參數(shù)傳遞。
應用程序輸入 struct v4l2_pix_format_mplane 結(jié)構(gòu)體里面的 width、height、pixelformat、field 等參數(shù),驅(qū)動返回最接近的 width、height;若 pixelformat、field 不支持,則默認選擇驅(qū)動支持的第一種格式。
3.9 VIDIOC_S_FMT
3.9.1 Parameters
Video type, format and size(struct v4l2_format * fmt) The same as VIDIOC_TRY_FMT
3.9.2 Returns
Success:0; Fail: Failure Number
3.9.3 Description
設置捕捉視頻的類型、格式和大小,設置之前會調(diào)用 VIDIOC_TRY_FMT。
對于 VIN 設備,type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。使用 struct v4l2_pix_format_mplane 進行參數(shù)傳遞。應用程序輸入 width、height、pixelformat、field 等,驅(qū)動返回最接近的 width、height; 若 pixelformat、field 不支持,則默認選擇驅(qū)動支持的第一種格式。
應用程序應該以驅(qū)動返回的 width、height、pixelformat、field 等作為后續(xù)使用傳遞的參數(shù)。對于 OSD 設備,type 為 V4L2_BUF_TYPE_VIDEO_OVERLAY。使用 struct v4l2_window進行參數(shù)傳遞。
應用程序輸入水印的個數(shù)、窗口位置和大小、bitmap 地址、bitmap 格式以及 global_alpha 等。驅(qū)動保存這些參數(shù),并在 VIDIOC_OVERLAY 命令傳遞使能命令時生效。
3.10 VIDIOC_G_FMT
3.10.1 Parameters
Video type, format and size(struct v4l2_format * fmt) The same as VIDIOC_TRY_FMT
3.10.2 Returns
Success:0; Fail: Failure Number
3.10.3 Description
獲取捕捉視頻的 width、height、pixelformat、field、bytesperline、sizeimage 等參數(shù)。
3.11 VIDIOC_OVERLAY
3.11.1 Parameters
Overlay on/off(unsigned int i)
3.11.2 Returns
Success:0; Fail: Failure Number
3.11.3 Description
傳遞 1 表示使能,0 表示關閉。設置使能時會更新 osd 參數(shù),使之生效。
3.12 VIDIOC_REQBUFS
3.12.1 Parameters
Buffer type ,count and memory map type(struct v4l2_requestbuffers * req) struct v4l2_requestbuffers { __u32 count; enum v4l2_buf_type type; enum v4l2_memory memory; __u32 reserved[2]; };
3.12.2 Returns
Success:0; Fail: Failure Number
3.12.3 Description
v4l2_requestbuffers 結(jié)構(gòu)中定義了緩存的數(shù)量,驅(qū)動會據(jù)此申請對應數(shù)量的視頻緩存。多個緩存可以用于建立 FIFO,來提高視頻采集的效率。這些 buffer 通過內(nèi)核申請,申請后需要通過 mmap 方法,映射到 User 空間。
Count:定義需要申請的 video buffer 數(shù)量;
Type:對于 VIN 設備,為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
Memory:目前支持 V4L2_MEMORY_MMAP、V4L2_MEMORY_USERPTR、V4L2_MEMORY_DMABUF 方式。
應用程序傳遞上述三個參數(shù),驅(qū)動會根據(jù) VIDIOC_S_FMT 設置的格式計算供需要 buffer 的大小,并返回 count 數(shù)量。
3.13 VIDIOC_QUERYBUF
3.13.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf) struct v4l2_buffer { __u32 index; enum v4l2_buf_type type; __u32 bytesused; __u32 flags; enum v4l2_field field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ enum v4l2_memory memory; union { __u32 offset; unsigned long userptr; struct v4l2_plane *planes; } m; __u32 length; __u32 input; __u32 reserved; };
3.13.2 Returns
Success:0; Fail: Failure Number
3.13.3 Description
通過 struct v4l2_buffer 結(jié)構(gòu)體的 index,訪問對應序號的 buffer,獲取到對應 buffer 的緩存信息。主要利用 length 信息及 m.offset 信息來完成 mmap 操作。
3.14 VIDIOC_DQBUF
3.14.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf) struct v4l2_buffer is the same as VIDIOC_QUERYBUF
3.14.2 Returns
Success:0; Fail: Failure Number
3.14.3 Description
將 driver 已經(jīng)填充好數(shù)據(jù)的 buffer 出列,供應用使用。
應用程序根據(jù) index 來識別 buffer,此時 m.offset 表示 buffer 對應的物理地址。
3.15 VIDIOC_QBUF
3.15.1 Parameters
Buffer type ,index and memory map type(struct v4l2_buffer *buf)
3.15.2 Returns
Success:0; Fail: Failure Number
3.15.3 Description
將 User 空間已經(jīng)處理過的 buffer,重新入隊,移交給 driver,等待填充數(shù)據(jù)。
應用程序根據(jù) index 來識別 buffer。
3.16 VIDIOC_STREAMON
3.16.1 Parameters
Buffer type(enum v4l2_buf_type *type)
3.16.2 Returns
Success:0; Fail: Failure Number
3.16.3 Description
此處的 buffer type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。運行此 IOCTL, 將 buffer 隊列中所有 buffer 入隊,并開啟 CSIC DMA 硬件中斷,每次中斷便表示完成一幀 buffer 數(shù)據(jù)的填入。
3.17 VIDIOC_STREAMOFF
3.17.1 Parameters
Buffer type(enum v4l2_buf_type *type)
3.17.2 Returns
Success:0; Fail: Failure Number
3.17.3 Description
此處的 buffer type 為 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE。運行此 IOCTL,停止捕捉視頻,將 frame buffer 隊列清空,以及 video buffer 釋放。
3.18 VIDIOC_QUERYCTRL
3.18.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) struct v4l2_queryctrl { __u32 id; enum v4l2_ctrl_type type; __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; __s32 step; __s32 default_value; __u32 flags; __u32 reserved[2]; };
3.18.2 Returns
Success:0; Fail: Failure Number
3.18.3 Description
應用程序通過 id 參數(shù),驅(qū)動返回需要調(diào)節(jié)參數(shù)的 name,minmum,maximum,default_value 以及步進 step。(由 v4l2 conctrols framework 完成)目前可能支持的 id 請參考 VIDIOC_S_CTRL。
3.19 VIDIOC_S_CTRL
3.19.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) The same as VIDIOC_QUERYCTRL
3.19.2 Returns
Success:0; Fail: Failure Number
3.19.3 Description
應用程序通過 id,value 等參數(shù),對 camera 驅(qū)動對應的參數(shù)進行設置。
驅(qū)動內(nèi)部會先調(diào)用 vidioc_queryctrl,判斷 id 是否支持,value 是否在 minimum 和 maximum 之間。(由 v4l2 conctrols framework 完成)目前可能支持的 id 和 value 參考附件。
3.20 VIDIOC_G_CTRL
3.20.1 Parameters
Control id and value(struct v4l2_queryctrl *qc) The same as VIDIOC_QUERYCTRL
3.20.2 Returns
Success:0; Fail: Failure Number
3.20.3 Description
應用程序通過 id,驅(qū)動返回對應 id 當前設置的 value。
3.21 VIDIOC_ENUM_FRAMESIZES
3.21.1 Parameters
index,type,format(struct v4l2_frmsizeenum) enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ };
3.21.2 Returns
Success:0; Fail: Failure Number
3.21.3 Description
根據(jù)應用傳進來的 index,pixel_format,驅(qū)動返回 type,并根據(jù) type 填寫 discrete 或 step-wise 的值。Discrete 表示分辨率固定的值;stepwise 表示分辨率有最小值和最大值,并根據(jù)step 遞增。上層根據(jù)返回的 type,做對應不同的操作。
3.22 VIDIOC_ENUM_FRAMEINTERVALS
3.22.1 Parameters
Index,format,size,type(struct v4l2_frmivalenum) enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ };
3.22.2 Returns
Success:0; Fail: Failure Number
3.22.3 Description
應用程序通過 pixel_format、width、height、驅(qū)動返回 type,并根據(jù) type 填寫
V4L2_FRMIVAL_TYPE_DISCRETE、V4L2_FRMIVAL_TYPE_CONTINUOUS 或V4L2_FRMIVAL_TYPE_STEPWISE。Discrete 表示支持單一的幀率;stepwise 表示支持步進的幀率。
3.23 VIDIOC_ISP_EXIF_REQ
作用: 得到當前照片的 EXIF 信息,填寫到相應的編碼域中。目的:對于 raw sensor 盡量填寫正規(guī)的 EXIF 信息,yuv sensor 該 IOCTRL 也可以使用,不過驅(qū)動中填寫的也是固定值。相關參數(shù):
struct v4l2_fract { __u32 numerator; __u32 denominator; }; struct isp_exif_attribute { struct v4l2_fract exposure_time; struct v4l2_fract shutter_speed; __u32 aperture; __u32 focal_length; __s32 exposure_bias; __u32 iso_speed; __u32 flash_fire; __u32 brightness; }; struct v4l2_fract exposure_time; 曝光時間:分數(shù)類型,例如numerator = 1,denominator = 200,則表示1/200秒的曝光時間。 struct v4l2_fract shutter_speed; 快門速度:分數(shù)類型,例如numerator = 1,denominator = 200,則表示1/200秒的快門速度。(實際上和曝光時間數(shù)值相同) __u32 aperture; 光圈大?。篎Number,例如aperture = 22,則表示,光圈大小為2.2,即FNumber = 22/10; __u32 focal_length; 焦距:例如focal_length = 1400,則表示焦距為14mm,即FocalLength = 1400/100( mm); __s32 exposure_bias; 曝光補償:范圍 -4~4 __u32 iso_speed; 感光速度:50~3200 __u32 flash_fire; 閃光燈是否開啟:flash_fire = 1 表示閃光燈開啟,flash_fire = 0 表示閃光燈未開啟。 __u32 brightness; 圖像亮度:0~255. 使用示例: int V4L2CameraDevice::getExifInfo(struct isp_exif_attribute *exif_attri) { int ret = -1; if (mCameraFd == NULL) { return 0xFF000000; } ret = ioctl(mCameraFd, VIDIOC_ISP_EXIF_REQ, exif_attri); return ret; }
4 模塊使用范例
4.1 測試 demo
模塊使用的 demo 的代碼位于 drivers/media/platform/sunxi-vin/vin_test/mplane_image;此目錄下可以直接 make 生成 demo;把 demo 推到機器里面執(zhí)行便可以獲取指定 video 節(jié)點的圖像。推薦在 pc 上創(chuàng)建 bat 批處理文件,使用 adb 命令完成一系列抓圖的動作,bat 內(nèi)容參考如下,不同機器請注意修改 push 進去的路徑:
del .result*.bin adb root adb remount adb shell "mkdir /vendor/extsd/" adb shell "mkdir /vendor/extsd/result" adb shell rm /vendor/extsd/result/*.bin adb push demo路徑csi_test_mplane /vendor/extsd/csi_test1 adb shell chmod 777 /vendor/extsd/csi_test1 adb shell "cd /vendor/extsd/ && ./csi_test1 0 0 1920 1080 ./result 1 20000 60 0" adb shell ls /vendor/extsd/result adb pull /vendor/extsd/result pause
最后會在 bat 指令的文件夾生成 result 文件夾里面保存二進制的圖像數(shù)據(jù) *.bin 文件;可用 RawViewer 等軟件查看圖像數(shù)據(jù)。demo 參數(shù)說明:0 0 1920 1080 ./result 1 20000 60 0,分別表示 video0,set_input index0,目標分辨率寬,目標分辨率高,bin 文件保存路徑、圖像格式(如 NV21,具體含義可以看 demo 代碼的 s_fmt 參數(shù))、采集幀數(shù)(幀數(shù)大于 10000 即為常開節(jié)點)、目標幀率、和是否開啟 wdr。
4.2 調(diào)用流程
圖 4-1: CSI 調(diào)用流程
5 FAQ
5.1 調(diào)試方法
5.1.1 調(diào)試節(jié)點
圖 5-1: vi 節(jié)點
當系統(tǒng)打開 DEBUG_FS 編譯宏時,可以 cat /sys/kernel/debug/mpp/vi 查看;否則可以
cat /sys/devices/platform/soc@2900000/2000800.vind/vi。
vi 節(jié)點保存的是當前或上一次工作(當前沒有工作)的狀態(tài)。下面對 vi 節(jié)點的關鍵信息進行說明。
CSI_TOP、CSI_ISP 分別是對應 CSI、和 ISP 的工作頻率;input 一行表示 CSI 接收到的圖片尺寸,fmt 表示輸入數(shù)據(jù)的格式;
output 表示 CSI 出尺寸,如果使用了縮放或者裁剪,那么輸入輸出尺寸會不一致,fmt 表示數(shù)據(jù)的輸出格式;
最后一行分別表示平均幀間隔、最大幀間隔、最小幀間隔,可以計算得出幀率,調(diào)試幀率時可以參考。
5.1.2 settle time
方式一:修改對應 sensor 驅(qū)動中的 sensor_probe 函數(shù),可以添加或修改 info->time_hs 的值即可。
圖 5-2: info->time_hs
方式二:通過 mipi 子設備的 settle_time 節(jié)點在線進行修改,settle_time 節(jié)點路徑:/sys/devices/platform/soc/5800800.vind/5810100.mipi。
進入節(jié)點路徑后,可以看到當前目錄下存在 settle_time 節(jié)點:
圖 5-3: settle time 節(jié)點
可以通過 cat、echo 命令,對 settle_time 節(jié)點進行讀寫操作:
圖 5-4: settle time 節(jié)點讀寫
調(diào)整策略:settle time 的值慢慢增大調(diào)整,調(diào)大直到不能出圖,再取一個略低于最大值的數(shù)值即可。調(diào)整范圍:0x00-0xff。
5.1.3 信號狀態(tài)
介紹如何觀測 SOC 主控的接收數(shù)據(jù)的信號狀態(tài),分別對 MIPI 和并口做出說明。
5.1.3.1 MIPI
MIPI 傳輸模式有兩種:
LP(Low-Power)模式:用于傳輸控制信號,最高速率 10 MHz。
HS(High-Speed)模式:用于高速傳輸數(shù)據(jù),以 MIPI DPHY V1.1 版本為例,速率范圍 [80Mbps - 1.5Gbps] per Lane。
可以通過查看 user manual MIPI PHY 部分寄存器,觀測 SOC 識別到的 clock lane 和 data lane 的 LP、HS 狀態(tài)。
5.1.3.2 并口
對于并口接口的 sensor,可以查看 user manual CSI PARSER 部分的 parser signal 寄存器,觀測 sensor 端 PCLK、DATA 的信號狀態(tài)。以此判斷 parser 是否有識別到 sensor 端發(fā)送的數(shù)據(jù)。
5.2 常見問題
5.2.1 I2C 不通
如下圖打印:
圖 5-5: i2c 不通
【分析步驟一】:確認供電、MCLK、i2c 上拉等外圍電路信號是否正常。使用萬用表測量板子上AVDD、DVDD、IOVDD 供電電壓、MCLK 頻率、幅度、RESET、PWDN 的電平是否符合要求。
【分析步驟二】:確認 i2c 地址,TWI 通道是否和原理圖一致。
【分析步驟三】:以上都正常就用示波器或者邏輯分析儀測量分析主控發(fā)出 i2c 波形是否正確、有無回應;最后可以考慮 sensor 損壞或者接口錯位等問題。
5.2.2 sensor 不出圖
【分析步驟一】:確認 chip id 和 datasheet 上一致。
在對應 sensor 驅(qū)動的 sensor_detect 函數(shù)中讀 chip id 寄存器,這一步也能檢驗 i2c 的讀寫是否正確。
【分析步驟二】:確認配置已經(jīng)配置到 sensor 里。
可以把寫進去的寄存器讀出來和寫入值對比是否一致。
【分析步驟三】:確認配置正確并且 sensor 已經(jīng)輸出圖像。
和原廠確認寄存器配置、用示波器測量 sensor 端的 mipi 數(shù)據(jù) lane 和時鐘 lane 波形,分析是否正在發(fā)送數(shù)據(jù)。
【分析步驟四】:確認 SOC 是否接收到 sensor 數(shù)據(jù)。
mipi 的 clock lane 存在兩種工作模式,一種是連續(xù)時鐘模式,傳輸過程不會切換 LP 狀態(tài);另一種是非連續(xù)時鐘信號模式,每傳輸完一幀圖像數(shù)據(jù),幀 blanking 時將會切換為 LP 狀態(tài)。目前大部分 MIPI sensor 一般都是非連續(xù)時鐘模式。
如果 sensor 是連續(xù)時鐘模式,要保證 MIPI 在 sensor 之前初始化,需要在 sensor 驅(qū)動 sensor_probe() 中配置 info->stream_seq = MIPI_BEFORE_SENSOR;
如果 sensor 是非連續(xù)時鐘模式,可以通過判斷 SOC 識別到的 LP、HS 模式狀態(tài)是否在不斷切換,來間接判斷 SOC 的 MIPI 的接收狀態(tài)。
查看 user manual MIPI PHY 部分寄存器,觀測 clock lane 和 data lane 的 LP、HS 狀態(tài)是否有在不斷切換,有則說明 MIPI 已經(jīng)接收到了 sensor 發(fā)送的數(shù)據(jù)。如果沒有切換則說明 MIPI 沒有正確接收 sensor 數(shù)據(jù)。此時應該檢查 MIPI 相關配置是否正確。
【分析步驟五】:嘗試修改 settle time。
如果可以確定 sensor 已經(jīng)在正確發(fā)送數(shù)據(jù),只是 MIPI 這邊一直接收不到導致無法出圖,可以嘗試修改 settle time(參考調(diào)試方法章節(jié))。
5.2.3 已出圖但畫面是綠色或者粉紅色
一般是 YUYV 順序反了,可以修改 sensor 驅(qū)動中 sensor_formats 結(jié)構(gòu)體的 mbus_code 參數(shù),修改 YUV 順序即可。
5.2.4 I2c 已通,但是讀所有 sensor 寄存器值都為 0
【分析步驟一】檢查 i2c 通訊 addr 和 data 的位寬。
檢查 sensor 驅(qū)動中 cci_drv 結(jié)構(gòu)體中定義的值是否符合 datasheet 要求。
【分析步驟二】檢查 i2c 通訊數(shù)據(jù)大小端是否不一致。
可以在讀 sensor id 時把地址高低位相反來快速驗證一下。
5.2.5 畫面旋轉(zhuǎn) 180 度
可以修改 board.dts 里面的 hflip 和 vflip 來解決,如果畫面和人眼成 90 度的話,只能通過修改 sensor 配置來解決(只有部分 sensor 支持)。
5.2.6 沒有 video 節(jié)點
【問題解析】沒有加載 ko 或者 ko 加載失敗。
【分析步驟一】檢查模塊加載順序是否正確。
lsmod 看一下模塊是否加載正確,如果報的錯誤是 [VIN_ERR]registering gc2355_mipi, No such device! 則表明 sensor 模塊 gc2355_mipi 沒有加載。
【分析步驟二】檢查 board.dts 文件配置是否配置了 vind0,且 status 為 okay。
【分析步驟三】如果是加載失敗檢查加載失敗的原始是 i2c 不通還是沒有 ko。
i2c 不通參考前面的分析,沒有 ko 請檢查是否有對應的驅(qū)動并且在 Makefile 中使能了編譯。
-
Linux
+關注
關注
87文章
11261瀏覽量
209227 -
MIPI
+關注
關注
11文章
310瀏覽量
48601 -
CSI
+關注
關注
1文章
36瀏覽量
50972 -
編譯
+關注
關注
0文章
655瀏覽量
32845
發(fā)布評論請先 登錄
相關推薦
評論