1. 程式人生 > >V4L2 soc-camera 資料結構

V4L2 soc-camera 資料結構

static LIST_HEAD(hosts)
所有的host都在hosts指向的連結串列上

static LIST_HEAD(devices);
所有soc camera device都掛在devices指向的連結串列上。

系統內可能有多個soc_camera_host,每個soc_camera_host可以對應1 ~ n個soc_camera_device。每個soc_camera_device通過soc_camera_video_start函式建立裝置節點/dev/videoX

soc_camera_host對應著系統camera處理模組,儘管理論上可以有多個camera host,但是大部分系統僅有一個camera host

在soc_camera_host_register中呼叫v4l2_device_register為這個soc_camera_host註冊一個v4l2_device裝置。

在soc_camera_probe中呼叫soc_camera_init_i2c,為soc_camera_device註冊一個v4l2_subdev,我們從soc_camera_probe程式碼可以看出,只有i2C的裝置可以使用這種方式,對於非I2C裝置來說,需要soc_camera_link提供add_device來增加子裝置。

soc_camera_host, soc_camera_device,v4l2_device,v4l2_subdev關係如下:

  • 理論上系統內可以有多個soc_camera_host,物理上soc_camera_host就是系統的camera處理模組驅動
  • 一個soc_camera_host可以對應多個soc_camera_device,物理上soc_camera_device是一個camera介面,每個soc_camera_host對應一個v4l2_dev
  • 每個soc_camera_device,系統會為他們建立裝置節點/dev/videoX。
  • 每個soc_camera_device有多個v4l2_subdev,物理上v4l2_subdev可以是sensor,video AD晶片
  • v4l2_subdev可以通過i2c掛接到v4l2_device,也可以通過soc_camera_link提供的add_device來增加,這依賴於sensor和video AD晶片掛接到MCU camera介面的方式。
struct soc_camera_device {
    struct list_head list;
    struct device dev;
    struct device *pdev;        /* Platform device */
    s32 user_width;
    s32 user_height;
    enum v4l2_colorspace colorspace;
    unsigned char iface;        /* Host number */
    unsigned char devnum;       /* Device number per host */
    struct soc_camera_sense *sense; /* See comment in struct definition */
    struct soc_camera_ops *ops;
    struct video_device *vdev;
    const struct soc_camera_format_xlate *current_fmt;
    struct soc_camera_format_xlate *user_formats;
    int num_user_formats;
    enum v4l2_field field;      /* Preserve field over close() */
    void *host_priv;        /* Per-device host private data */
    /* soc_camera.c private count. Only accessed with .video_lock held */
    int use_count;
    struct mutex video_lock;    /* Protects device data */
    struct file *streamer;      /* stream owner */
    struct videobuf_queue vb_vidq;
};

每一個soc_camera_device都會對應一個/dev/videoX裝置節點,除非在soc_camera_probe時失敗。

@list:soc_came_device通過這個成員連線到全域性devices連結串列上

@pdev:每一個soc_camera_device,都會有一個platform device,pdev就是這個platform device結構的dev成員

@user_width, @user_height:這個camera的預設width和height

@iface:camera bus id,也是host id,一個host可以對應多個soc_camera_device

@devnum:device number,每個soc_camera_device都會自動分配一個device number

@ops:操作集合,sensor,video AD(也許還有host)驅動要實現這個介面

@use_count:soc camera使用計數,每次開啟這個裝置加1,關閉則減1

soc_camera_host

struct soc_camera_host {
    struct v4l2_device v4l2_dev;
    struct list_head list;
    unsigned char nr;               /* Host number */
    void *priv;
    const char *drv_name;
    struct soc_camera_host_ops *ops;
}

@v4l2_dev:每個host都是一個v4l2_device

@list:soc_camera_host通過這個成員連結到全域性hosts連結串列上

@nr:host number,每個host介面對應一個host

@priv:一般存放平臺特定的camera引數,比如irq,DMA

struct soc_camera_ops {
    int (*suspend)(struct soc_camera_device *, pm_message_t state);
    int (*resume)(struct soc_camera_device *);
    unsigned long (*query_bus_param)(struct soc_camera_device *);
    int (*set_bus_param)(struct soc_camera_device *, unsigned long);
    int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
    const struct v4l2_queryctrl *controls;
    int num_controls;
};  
這個是由sensor,video AD或者host實現的回撥函式集。

@suspend,@resume:系統休眠喚醒時的回撥函式,如果不考慮電源管理,可以不實現這兩個函式

@query_bus_param:獲取sensor和host之間的匯流排資訊,比如HSYNC VSYNC極性,資料匯流排寬度,資料線極性等

@set_bus_param:設定sensor和host之間的匯流排引數。

@enum_input:列舉給定的input number,上層通過@v4l2_input->index指定要檢視哪個input,一般可以不實現。

@controls:controls

@num_controls:@controls數目