v4l2_device

介绍

日期作者说明
2024/04/04Manfredxxc初版

内核版本:kernel-4.1.15
参考源码:drivers/media/platform/omap3isp/isp.c



在v4l2框架里struct v4l2_device代表了一个video设备;相应的,struct v4l2_subdev代表video设备下的子设备,如csi、isp、sensor等

下图是v4l2_devicev4l2_subdev之间的拓扑结构示例,所有的子设备都链接在链表上(v4l2_device->subdevs
在这里插入图片描述

输入设备

数据类型简要说明

struct v4l2_device一般嵌入一个更大的私有结构体,构成一个video输入设备

struct isp_device {
    struct v4l2_device v4l2_dev; // 该结构体的嵌入,构成一个omap3isp设备
	struct v4l2_async_notifier notifier; // 用于异步注册v4l2_device
	struct media_device media_dev; // 用于media framework
	struct device *dev;
}

struct v4l2_device {
    struct device *dev; // 赋值为isp->dev
    struct list_head *subdevs; // 由子设备组成的链表
}

API简要说明

v4l2_device_register

  • 描述:注册一个v4l2输入设备,让@dev->driver_data 指向 @v4l2_dev
  • 原型:int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)

子设备

数据结构简要说明

struct v4l2_subdev一般嵌入到一个更大的私有结构体,构成一个子设备

struct isp_csi2_device {
    struct v4l2_subdev subdev; // 该结构体的嵌入,构成一个csi2子设备
}

struct v4l2_subdev {
#if defined(CONFIG_MEDIA_CONTROLLER)
	struct media_entity entity;
#endif
	struct list_head list; // 子设备链表
	u32 flags; // I2C|SPI|DEVNODE|EVENTS 标记子设备类型(i2c/spi)| 需要创建子设备节点/dev/v4l-subdev<X> | 子设备可创建事件
	struct v4l2_device *v4l2_dev; // 指向绑定的v4l2_device
	const struct v4l2_subdev_ops *ops; // 子设备支持的操作
	const struct v4l2_subdev_internal_ops *internal_ops; // 内部操作 registered | unregistered | open | close | release 时触发
	char name[V4L2_SUBDEV_NAME_SIZE]; // 唯一的子设备名
	u32 grp_id; // 归类子设备
	void *dev_priv; // 指向私有数据 v4l2_set_subdevdata()/v4l2_get_subdevdata()
	void *host_priv; // 指向子设备连接的设备使用的私有数据 v4l2_set_subdev_hostdata()/v4l2_get_subdev_hostdata()
}

API简要说明

v4l2_subdev_init

  • 描述:初始化一个struct v4l2_subdev
  • 原型:void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)

v4l2_device_register_subdev

  • 描述:向v4l2输入设备注册一个子设备
  • 原型:int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, struct v4l2_subdev *sd)
  • 参数:NA
    1. sd->ctrl_hander纳入v4l2_dev统一管理
    2. 注册一个media_entity
    3. 调用sd->internal_ops->registered(sd)(如果存在)
    4. sd链接到v4l2_dev->subdevs

层次结构

访问

video输入设备(struct isp)、子设备(struct isp_csi2_device)、v4l2_dev(struct v4l2_device)、sd(struct v4l2_subdev)

  1. v4l2_dev => sd
    按子设备名遍历链表即可
  2. v4l2_dev => 输入设备
    container_of(v4l2_dev, struct isp, v4l2_dev)
  3. sd => v4l2_dev
    sd->v4l2_dev
  4. sd => 子设备
    v4l2_get_subdevdata(sd)

信息交流

  1. 访问子设备并执行相应操作
    v4l2_device_call_all
    • 描述:对符合条件(@group_id == sd->grpid)的子设备调用o->f(args)
    • 原型:v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)
  2. 子设备通知v4l2_dev
    需要实现v4l2_dev->notify(),子设备在需要时调用v4l2_subdev_notify()通知v4l2_dev
    v4l2_subdev_notify
    • 描述:通知v4l2_device
    • 原型:static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, unsigned int notification, void *arg)
    • 参数:
      • @sd:指向&struct v4l2_subdev
      • @notification:驱动自定义的通知类型
      • @arg:配合@notification使用的参数
    • 使用:在v4l2_dev->notify()中,根据notification执行不同的操作

节点注册

节点注册最终都是通过调用__video_register_device(),需要一个struct video_device,会根据vfl_devnode_type创建不同类型的节点
存在如下类型:

  1. video
  2. vbi
  3. ratio
  4. v4l-subdev
  5. swradio
  6. v4l-touch

本文主要分析v4l2_device/subdev,这里提下v4l-subdev类型节点的注册:
v4l2_device_register_subdev_nodes

  • 描述:为该v4l2_dev上的所有标记为V4L2_SUBDEV_FL_HAD_DEVNODE的子设备创建节点/dev/v4l-subdev
  • 原型:int __must_check v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
  • 不需要用户提供fops:open/close使用sd->internal_ops->open/close,其余由v4l2核心层支持
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值