一、 設(shè)備節(jié)點(diǎn)、模塊、拓?fù)浣Y(jié)構(gòu)關(guān)系
拓?fù)浣Y(jié)構(gòu)是我們了解MIPI-CSI內(nèi)部模塊以及與攝像頭連接關(guān)系的最直觀最便捷的方法。
1. 如何表示拓?fù)浣Y(jié)構(gòu)?
file視角
v4l2視角
來自:
參考文檔《RKISP_Driver_User_Manual_v1.3.pdf》
- 模塊之間相互獨(dú)立,通過struct media_entity來進(jìn)行抽象,通常會將struct media_entity嵌入到其他結(jié)構(gòu)中,以支持media framework功能;entity模塊包含struct media_pad,pad可以認(rèn)為是端口,與其他模塊進(jìn)行聯(lián)系的媒介,針對特定模塊來說它是確定的;pad通過struct media_link來建立連接,指定source和sink,即可將通路建立起來;各個模塊之間最終建立一條數(shù)據(jù)流,便是一條pipeline了,同一條pipeline中的模塊,可以根據(jù)前一個模塊查找到下一個模塊,因此也可以很方便進(jìn)行遍歷,并做進(jìn)一步的設(shè)置操作;
2. 設(shè)備節(jié)點(diǎn)-------少media的
在/sys/class/video4linux/下可以找到v4l2相關(guān)的設(shè)備節(jié)點(diǎn):
rk3568_r:/?#?ls?sys/class/video4linux
ls?sys/class/video4linux
v4l-subdev0??v4l-subdev2??video1??video3??video5??video7
v4l-subdev1??video0???????video2??video4??video6??video8
rk3568_r:/?#?cat?sys/class/video4linux/video0/dev
cat?sys/class/video4linux/video0/dev
81:0
rk3568_r:/?#?cat?sys/class/video4linux/video0/name
cat?sys/class/video4linux/video0/name
rkisp_mainpath
udev文件系統(tǒng)會為我們在dev/目錄下創(chuàng)建一個video0節(jié)點(diǎn),即dev/video0
用戶可以打開dev/video0節(jié)點(diǎn),通過IOCTL命令和內(nèi)核空間進(jìn)行通信。
rk3568_r:/?#?ls?/dev/video*?-l
ls?/dev/video*?-l
crw-rw----?1?media?camera?81,???0?2022-11-09?17:06?/dev/video0
crw-rw----?1?media?camera?81,???1?2022-11-09?17:06?/dev/video1
crw-rw----?1?media?camera?81,???2?2022-11-09?17:06?/dev/video2
crw-rw----?1?media?camera?81,???3?2022-11-09?17:06?/dev/video3
crw-rw----?1?media?camera?81,???4?2022-11-09?17:06?/dev/video4
crw-rw----?1?media?camera?81,???5?2022-11-09?17:06?/dev/video5
crw-rw----?1?media?camera?81,???6?2022-11-09?17:06?/dev/video6
crw-rw----?1?media?camera?81,???7?2022-11-09?17:06?/dev/video7
crw-rw----?1?media?camera?81,???8?2022-11-09?17:06?/dev/video8
rk3568_r:/?#?ls?/dev/v4l-sub*?-l
ls?/dev/v4l-sub*?-l
crw-rw-rw-?1?media?camera?81,???9?2022-11-09?17:06?/dev/v4l-subdev0
crw-rw-rw-?1?media?camera?81,??10?2022-11-09?17:06?/dev/v4l-subdev1
crw-rw-rw-?1?media?camera?81,??11?2022-11-09?17:06?/dev/v4l-subdev2
3. 拓?fù)浣Y(jié)構(gòu)圖
命令media-ctl可以查看拓?fù)浣Y(jié)構(gòu)圖
rk3568_r:/?#?media-ctl?-d?/dev/media0?-p??????????????????
media-ctl?-d?/dev/media0?-p???????????????????????????????
Opening?media?device?/dev/media0??????????????????????????
Enumerating?entities??????????????????????????????????????
Found?13?entities?????????????????????????????????????????
Enumerating?pads?and?links????????????????????????????????
Media?controller?API?version?0.0.255??????????????????????
??????????????????????????????????????????????????????????
Media?device?information??????????????????????????????????
------------------------??????????????????????????????????
driver??????????rkisp-vir0????????????????????????????????
model???????????rkisp0????????????????????????????????????
serial????????????????????????????????????????????????????
bus?info??????????????????????????????????????????????????
hw?revision?????0x0???????????????????????????????????????
driver?version??0.0.255???????????????????????????????????
??????????????????????????????????????????????????????????
Device?topology???????????????????????????????????????????
-?entity?1:?rkisp-isp-subdev?(4?pads,?7?links)????????????
????????????type?V4L2?subdev?subtype?Unknown??????????????
????????????device?node?name?/dev/v4l-subdev0?????????????
????????pad0:?Sink????????????????????????????????????????
????????????????[fmt:SBGGR10/4224x3136????????????????????
?????????????????crop.bounds:(0,0)/4096x3072??????????????
?????????????????crop:(0,0)/4096x3072]????????????????????
????????????????<-?"rkisp-csi-subdev":1?[]????????????????
????????????????<-?"rkisp_rawrd0_m":0?[]??????????????????
????????????????<-?"rkisp_rawrd2_s":0?[]??????????????????
????????pad1:?Sink????????????????????????????????????????
????????????????<-?"rkisp-input-params":0?[]??????????????
????????pad2:?Source??????????????????????????????????????
????????????????[fmt:YUYV2X8/4096x3072????????????????????
?????????????????crop.bounds:(0,0)/4096x3072??????????????
?????????????????crop:(0,0)/4096x3072]????????????????????
????????????????->?"rkisp_mainpath":0?[]??????????????????
????????????????->?"rkisp_selfpath":0?[]??????????????????
????????pad3:?Source??????????????????????????????????????
????????????????->?"rkisp-statistics":0?[]????????????????
??????????????????????????????????????????????????????????
-?entity?6:?rkisp-csi-subdev?(6?pads,?5?links)????????????
????????????type?V4L2?subdev?subtype?Unknown??????????????
????????????device?node?name?/dev/v4l-subdev1?????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rockchip-csi2-dphy0":1?[]?????????????
????????pad1:?Source??????????????????????????????????????
????????????????->?"rkisp-isp-subdev":0?[]????????????????
????????pad2:?Source??????????????????????????????????????
????????????????->?"rkisp_rawwr0":0?[]????????????????????
????????pad3:?Source??????????????????????????????????????
????????pad4:?Source??????????????????????????????????????
????????????????->?"rkisp_rawwr2":0?[]????????????????????
????????pad5:?Source??????????????????????????????????????
????????????????->?"rkisp_rawwr3":0?[]????????????????????
??????????????????????????????????????????????????????????
-?entity?13:?rkisp_mainpath?(1?pad,?1?link)???????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video0?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-isp-subdev":2?[]????????????????
??????????????????????????????????????????????????????????
-?entity?19:?rkisp_selfpath?(1?pad,?1?link)???????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video1?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-isp-subdev":2?[]????????????????
??????????????????????????????????????????????????????????
-?entity?25:?rkisp_rawwr0?(1?pad,?1?link)?????????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video2?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-csi-subdev":2?[]????????????????
??????????????????????????????????????????????????????????
-?entity?31:?rkisp_rawwr2?(1?pad,?1?link)?????????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video3?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-csi-subdev":4?[]????????????????
??????????????????????????????????????????????????????????
-?entity?37:?rkisp_rawwr3?(1?pad,?1?link)?????????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video4?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-csi-subdev":5?[]????????????????
??????????????????????????????????????????????????????????
-?entity?43:?rkisp_rawrd0_m?(1?pad,?1?link)???????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video5?????????????????
????????pad0:?Source??????????????????????????????????????
????????????????->?"rkisp-isp-subdev":0?[]????????????????
??????????????????????????????????????????????????????????
-?entity?49:?rkisp_rawrd2_s?(1?pad,?1?link)???????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video6?????????????????
????????pad0:?Source??????????????????????????????????????
????????????????->?"rkisp-isp-subdev":0?[]????????????????
??????????????????????????????????????????????????????????
-?entity?55:?rkisp-statistics?(1?pad,?1?link)?????????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video7?????????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"rkisp-isp-subdev":3?[]????????????????
??????????????????????????????????????????????????????????
-?entity?61:?rkisp-input-params?(1?pad,?1?link)???????????
?????????????type?Node?subtype?V4L????????????????????????
?????????????device?node?name?/dev/video8?????????????????
????????pad0:?Source??????????????????????????????????????
????????????????->?"rkisp-isp-subdev":1?[]????????????????
??????????????????????????????????????????????????????????
-?entity?67:?rockchip-csi2-dphy0?(2?pads,?2?links)????????
?????????????type?V4L2?subdev?subtype?Unknown?????????????
?????????????device?node?name?/dev/v4l-subdev2????????????
????????pad0:?Sink????????????????????????????????????????
????????????????<-?"m00_b_ov13850?4-0010":0?[]????????????
????????pad1:?Source??????????????????????????????????????
????????????????->?"rkisp-csi-subdev":0?[]????????????????
??????????????????????????????????????????????????????????
-?entity?70:?m00_b_ov13850?4-0010?(1?pad,?1?link)?????????
?????????????type?V4L2?subdev?subtype?Sensor??????????????
?????????????device?node?name?/dev/v4l-subdev3????????????
????????pad0:?Source??????????????????????????????????????
????????????????[fmt:SBGGR10/4224x3136]???????????????????
????????????????->?"rockchip-csi2-dphy0":0?[]??????????????????????????????????????????????????????????????
下面是根據(jù)顯示內(nèi)容繪制的拓?fù)鋱D:
拓?fù)浣Y(jié)構(gòu)
該圖中各個entity對應(yīng)的設(shè)備節(jié)點(diǎn)名稱已經(jīng)標(biāo)注。模塊的上方的黃色pad默認(rèn)是source pad,下方的黃色pad是sink pad
字符設(shè)備類型主要有兩種(只考慮攝像頭):
- /dev/videox ?(x取值0~8) (所有設(shè)備共用主設(shè)備號81,次設(shè)備號區(qū)分)/dev/v4l-subdevx ? (x取值0~3)
video設(shè)備主要用于圖像操作,必須創(chuàng)建結(jié)構(gòu)體struct video_device變量,
v4l-subdev設(shè)備主要對應(yīng)sensor等具體從設(shè)備,必須創(chuàng)建struct ?v4l2_subdev變量,
內(nèi)部的isp和csi、csi-dphy也都需要注冊為subdev
這些entity由media_entity模塊負(fù)責(zé)維護(hù),將他們連接起來。
4. 模塊功能
這些entity瑞芯微已經(jīng)設(shè)定了他們各自的功能:
這些entity我們可以理解為一個個功能模塊。
這些功能模塊有的用于驅(qū)動csi、有的驅(qū)動isp、有的用于預(yù)覽圖像、有的用于統(tǒng)計(jì)視頻信息、有的用于配置參數(shù)。
這些功能模塊,并不是都一定每個camera控制器都有的,有一些是通用的,比如,mainpath、selfpath,有一些要完全看SoC設(shè)計(jì),即使瑞芯微的SoC,不同型號,差別也不小。所以具體問題要具體分析,不可教條。
v4l2只定義了基本架構(gòu),定義好了回調(diào)函數(shù)接口,要實(shí)現(xiàn)模塊具體功能只需要填充好對應(yīng)的回調(diào)函數(shù)即可,應(yīng)用層通過這些字符設(shè)備文件和對應(yīng)的ioctrl命令,就可以實(shí)現(xiàn)相應(yīng)的功能。
二、 如何描述拓?fù)洌?/h2>
1. struct rkisp_device
rk3568的camera控制器使用結(jié)構(gòu)體struct rkisp_device管理所有的資源。
/*
?*?struct?rkisp_device?-?ISP?platform?device
?*?@base_addr:?base?register?address
?*?@active_sensor:?sensor?in-use,?set?when?streaming?on
?*?@isp_sdev:?ISP?sub-device
?*?@cap_dev:?image?capture?device
?*?@stats_vdev:?ISP?statistics?output?device
?*?@params_vdev:?ISP?input?parameters?device
?*?@dmarx_dev:?image?input?device
?*?@csi_dev:?mipi?csi?device
?*?@br_dev:?bridge?of?isp?and?ispp?device
?*/
struct?rkisp_device?{
????struct?list_head?list;
????void?__iomem?*base_addr;
????struct?device?*dev;
????char?name[128];
????void?*sw_base_addr;
????struct?rkisp_hw_dev?*hw_dev;?????
????struct?v4l2_device?v4l2_dev;
????struct?v4l2_ctrl_handler?ctrl_handler;
????struct?media_device?media_dev;
????struct?v4l2_async_notifier?notifier;
????struct?v4l2_subdev?*subdevs[RKISP_SD_MAX];
????struct?rkisp_sensor_info?*active_sensor;
????struct?rkisp_sensor_info?sensors[RKISP_MAX_SENSOR];
????int?num_sensors;
????struct?rkisp_isp_subdev?isp_sdev;
????struct?rkisp_capture_device?cap_dev;
????struct?rkisp_isp_stats_vdev?stats_vdev;
????struct?rkisp_isp_params_vdev?params_vdev;
????struct?rkisp_dmarx_device?dmarx_dev;
????struct?rkisp_csi_device?csi_dev;
????struct?rkisp_bridge_device?br_dev;
????struct?rkisp_luma_vdev?luma_vdev;
????struct?proc_dir_entry?*procfs;
????struct?rkisp_pipeline?pipe;
????enum?rkisp_isp_ver?isp_ver;
????struct?rkisp_emd_data?emd_data_fifo[RKISP_EMDDATA_FIFO_MAX];
????unsigned?int?emd_data_idx;
????unsigned?int?emd_vc;
????unsigned?int?emd_dt;
????int?vs_irq;
????struct?gpio_desc?*vs_irq_gpio;
????struct?rkisp_hdr?hdr;
????unsigned?int?isp_state;
????unsigned?int?isp_err_cnt;
????unsigned?int?isp_isr_cnt;
????unsigned?int?isp_inp;
????struct?mutex?apilock;?/*?mutex?to?serialize?the?calls?of?stream?*/
????struct?mutex?iqlock;?/*?mutex?to?serialize?the?calls?of?iq?*/
????wait_queue_head_t?sync_onoff;
????dma_addr_t?resmem_addr;
????phys_addr_t?resmem_pa;
????size_t?resmem_size;
????int?dev_id;
????unsigned?int?skip_frame;
????unsigned?int?irq_ends;
????unsigned?int?irq_ends_mask;
????bool?send_fbcgain;
????struct?rkisp_ispp_buf?*cur_fbcgain;
????struct?rkisp_buffer?*cur_spbuf;
????bool?is_thunderboot;
????struct?kfifo?rdbk_kfifo;
????spinlock_t?rdbk_lock;
????int?rdbk_cnt;
????int?rdbk_cnt_x1;
????int?rdbk_cnt_x2;
????int?rdbk_cnt_x3;
????u32?rd_mode;
????u8?filt_state[RDBK_F_MAX];
};
其中與isp2.1拓?fù)浣Y(jié)構(gòu)相關(guān)的的幾個結(jié)構(gòu)體成員以及他們之間的關(guān)系:
成員 | 含義 | 拓?fù)鋱D中的entity | 設(shè)備名 |
---|---|---|---|
void __iomem *base_addr | 基地址 | - | - |
struct rkisp_sensor_info *active_sensor; | 正在使用的sensor | - | - |
struct rkisp_isp_subdev isp_sdev; | isp模塊 | rkisp-isp-subdev | v4l-subdev0 |
struct rkisp_capture_device cap_dev; | capture模塊, 維護(hù)struct vb2_v4l2_buffer | 對應(yīng)拓?fù)鋱D中的rkisp_mainpath、rkisp_selfpath、rkisp_rawwr0、rkisp_rawwr2、rkisp_rawwr3 | video0~video4 |
struct rkisp_isp_stats_vdev stats_vdev; | 數(shù)據(jù)統(tǒng)計(jì)模塊 | rkisp-statistics | video7 |
struct rkisp_isp_params_vdev params_vdev; | 參數(shù)配置模塊 | rkisp-input-params | video8 |
struct rkisp_dmarx_device dmarx_dev; | dma數(shù)據(jù)接收模塊 | rkisp_rawrd0_m、rkisp_rawrd2_s | video5、video6 |
struct rkisp_csi_device csi_dev; | csi的sub device從設(shè)備 | rkisp-csi-subdev | v4l-subdev1 |
struct rkisp_bridge_device br_dev; | 橋接模塊備,isp2.0中有 | - | - |
enum rkisp_isp_ver isp_ver; | isp版本號,rk3568是2.1 | - | - |
2. 舉例1:rkisp-csi-subdev注冊到拓?fù)浣Y(jié)構(gòu)中
要添加到拓?fù)浣Y(jié)構(gòu)中,表示該模塊的結(jié)構(gòu)體中包含成員struct media_pad ,它和struct v4l2_subdev中的 struct media_entity entity;共同生成拓?fù)浣Y(jié)構(gòu)。
rkisp-csi-subdev設(shè)備結(jié)構(gòu)體定義如下:
struct?rkisp_csi_device?{
?struct?rkisp_device?*ispdev;
?struct?v4l2_subdev?sd;
?struct?media_pad?pads[CSI_PAD_MAX];
?struct?sink_info?sink[CSI_PAD_MAX?-?1];
?int?max_pad;
?u32?err_cnt;
?u32?irq_cnt;
?u8?mipi_di[CSI_PAD_MAX?-?1];
?u8?tx_first[HDR_DMA_MAX];
};
參考第二節(jié)的拓?fù)鋱D中 entity6 :
由上圖可知,該模塊有6個pad,pad屬性定義如下
#define?MEDIA_PAD_FL_SINK???(1?<<?0)
#define?MEDIA_PAD_FL_SOURCE???(1?<<?1)
#define?MEDIA_PAD_FL_MUST_CONNECT??(1?<<?2)
pad的名稱定義如下:
enum?rkisp_csi_pad?{
?CSI_SINK?=?0,
?CSI_SRC_CH0,
?CSI_SRC_CH1,
?CSI_SRC_CH2,
?CSI_SRC_CH3,
?CSI_SRC_CH4,
?CSI_PAD_MAX
};
isp的in pad
//isp的in?pad
enum?rkisp_isp_inp?{
?INP_INVAL?=?0,
?INP_RAWRD0?=?BIT(0),
?INP_RAWRD1?=?BIT(1),
?INP_RAWRD2?=?BIT(2),
?INP_CSI?=?BIT(4),
?INP_DVP?=?BIT(5),
?INP_DMARX_ISP?=?BIT(6),
?INP_LVDS?=?BIT(7),
?INP_CIF?=?BIT(8),
};
根據(jù)該拓?fù)鋱D,pads[0] 為sink ,pads[1~5] 均為source
以下是驅(qū)動中pad初始化代碼:
rkisp_register_csi_subdev()
{
?……
?v4l2_subdev_init(sd,?&rkisp_csi_ops);
?sd->flags?|=?V4L2_SUBDEV_FL_HAS_DEVNODE;??//是否需要子節(jié)點(diǎn)
?sd->entity.ops?=?&rkisp_csi_media_ops;
?sd->entity.function?=?MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
?snprintf(sd->name,?sizeof(sd->name),?CSI_DEV_NAME);//名字前綴,#define?CSI_DEV_NAME?DRIVER_NAME?"-csi-subdev"
?csi_dev->pads[CSI_SINK].flags?=
??MEDIA_PAD_FL_SINK?|?MEDIA_PAD_FL_MUST_CONNECT;?//pad0屬性
?csi_dev->pads[CSI_SRC_CH0].flags?=
??MEDIA_PAD_FL_SOURCE?|?MEDIA_PAD_FL_MUST_CONNECT;?//pad1屬性
?csi_dev->max_pad?=?CSI_SRC_CH0?+?1;
?if?(dev->isp_ver?==?ISP_V20?||?dev->isp_ver?==?ISP_V21)?{
??csi_dev->max_pad?=?CSI_PAD_MAX;
??csi_dev->pads[CSI_SRC_CH1].flags?=?MEDIA_PAD_FL_SOURCE;//pad2屬性
??csi_dev->pads[CSI_SRC_CH2].flags?=?MEDIA_PAD_FL_SOURCE;//pad3屬性
??csi_dev->pads[CSI_SRC_CH3].flags?=?MEDIA_PAD_FL_SOURCE;//pad4屬性
??csi_dev->pads[CSI_SRC_CH4].flags?=?MEDIA_PAD_FL_SOURCE;//pad5屬性
?}
?ret?=?media_entity_pads_init(&sd->entity,?csi_dev->max_pad,
?????????csi_dev->pads);
????……
}
一些關(guān)鍵的宏匯總:
//各個模塊對應(yīng)的名字
【kerneldriversmediaplatformrockchipispdev.h】
#define?DRIVER_NAME?"rkisp"
#define?ISP_VDEV_NAME?DRIVER_NAME??"_ispdev"
#define?SP_VDEV_NAME?DRIVER_NAME???"_selfpath"
#define?MP_VDEV_NAME?DRIVER_NAME???"_mainpath"
#define?DMA_VDEV_NAME?DRIVER_NAME??"_dmapath"
#define?RAW_VDEV_NAME?DRIVER_NAME??"_rawpath"
#define?DMATX0_VDEV_NAME?DRIVER_NAME?"_rawwr0"
#define?DMATX1_VDEV_NAME?DRIVER_NAME?"_rawwr1"
#define?DMATX2_VDEV_NAME?DRIVER_NAME?"_rawwr2"
#define?DMATX3_VDEV_NAME?DRIVER_NAME?"_rawwr3"
#define?DMARX0_VDEV_NAME?DRIVER_NAME?"_rawrd0_m"
#define?DMARX1_VDEV_NAME?DRIVER_NAME?"_rawrd1_l"
#define?DMARX2_VDEV_NAME?DRIVER_NAME?"_rawrd2_s"
#define?GRP_ID_SENSOR???BIT(0)
#define?GRP_ID_MIPIPHY???BIT(1)
#define?GRP_ID_ISP????BIT(2)
#define?GRP_ID_ISP_MP???BIT(3)
#define?GRP_ID_ISP_SP???BIT(4)
#define?GRP_ID_ISP_DMARX??BIT(5)
#define?GRP_ID_ISP_BRIDGE??BIT(6)
#define?GRP_ID_CSI????BIT(7)
//pad的屬性
[kernelincludeuapilinuxmedia.h]
#define?MEDIA_PAD_FL_SINK????(1?<<?0)
#define?MEDIA_PAD_FL_SOURCE????(1?<<?1)
#define?MEDIA_PAD_FL_MUST_CONNECT??(1?<<?2)
由代碼可得,拓?fù)潢P(guān)系由csi_dev->pads描述。
最終調(diào)用函數(shù)media_entity_pads_init()注冊。
rkisp_register_platform_subdevs()
?isp_subdev_notifier()
??v4l2_async_notifier_parse_fwnode_endpoints()
???__v4l2_async_notifier_parse_fwnode_endpoints()
???{
????for?(?fwnode?=?fwnode_graph_get_next_endpoint())
????{
?????dev_fwnode?=?fwnode_graph_get_port_parent(fwnode);
?????is_available?=?fwnode_device_is_available(dev_fwnode);
?????fwnode_handle_put(dev_fwnode);
??????fwnode_graph_parse_endpoint(fwnode,?&ep);
????}
????for?(?fwnode?=?fwnode_graph_get_next_endpoint())
????{
?????dev_fwnode?=?fwnode_graph_get_port_parent(fwnode);
?????is_available?=?fwnode_device_is_available(dev_fwnode);
?????fwnode_handle_put(dev_fwnode);
??????fwnode_graph_parse_endpoint(fwnode,?&ep);
?????v4l2_async_notifier_fwnode_parse_endpoint();
????}?
????fwnode_handle_put(fwnode);???
???}
大家也可以試著去分析其他的模塊。
三、設(shè)備樹如何描述攝像頭拓?fù)浣Y(jié)構(gòu)?
1. 設(shè)備樹說明文檔
瑞芯微MIPI-CSI設(shè)備樹節(jié)點(diǎn)屬性說明參考內(nèi)核說明文檔:
[kernelDocumentationdevicetreebindingsmedia]
video-interfaces.txt?????????????關(guān)于sensor節(jié)點(diǎn)屬性的說明,接口類型,
rockchip-isp1.txt????????????????isp模塊屬性說明
rockchip-mipi-dphy.txt???????????dphy模塊的說明
kernelDocumentationdevicetreebindingsmediai2covxxxxxx.txt??ov系列的攝像設(shè)備樹說明
這些文檔中有關(guān)于port、remote-endpoint等節(jié)點(diǎn)的詳細(xì)說明,如果不是廠家,我們只需要搞懂?dāng)z像頭拓?fù)浣Y(jié)構(gòu)即可。
2. ov13850
我們移植的攝像頭為ov13850,他的連接關(guān)系如下:
- 數(shù)據(jù)通道通過mipi接口連接到rk3568的mipi通道0Camera控制器的csi2-dphy0模塊負(fù)責(zé)從mipi通道中接收數(shù)據(jù)幀
外設(shè)攝像頭拓?fù)潢P(guān)系由設(shè)備樹來描述,內(nèi)核會自動解析并幫我們自動注冊。
千言萬語,不如一圖:
由上圖可得:
- 攝像頭ov13850設(shè)備樹只有一個port子節(jié)點(diǎn),所以pad為0,out表示該pad是source padremote-endpoint屬性表示該pad連接的上游模塊的pad名字:mipi_in_ucam0,而模塊csi2_dphy0中包含pad:mipi_in_ucam0,所以ov13850連接到該模塊csi2_dphy0 port0節(jié)點(diǎn)的mipi_in_ucam0設(shè)備,通過remote-endpoint即可知道該pad所連接的是設(shè)備ov13850的pad綜上可得csi2_dphy0的pad0(sink pad)連接的ov13850的pad0(source pad)