ops是由此通知器的所有者提供的一组回调,由异步核心在等待在此通知器中的子设备被探测时调用。
v4l2_dev是注册此通知器的桥接驱动程序的 V4L2 父级。
sd,如果此通知器是由子设备注册的,将指向此子设备。我们在这里不讨论这种情况。
subdevs是应该通知此通知器的注册者(桥接驱动程序或另一个子设备驱动程序)的子设备数组。
waiting是此通知器中等待被探测的子设备的列表。
done是实际绑定到此通知器的子设备的列表。
num_subdevs是**subdevs中子设备的数量。
list在注册此通知器时由异步核心使用,以将此通知器链接到通知器的全局列表notifier_list。
子设备注册不再依赖于桥接可用性,只需调用v4l2_async_register_subdev()方法即可。但是,在注册自身之前,桥接驱动程序将不得不执行以下操作:
为以后使用分配一个通知程序。{BANNED}最佳好将此通知程序嵌入较大的设备状态数据结构中。此通知程序对象是struct v4l2_async_notifier类型。
解析其端口节点并为其中指定的每个传感器(或 IP 块)创建一个异步子设备(struct v4l2_async_subdev),并且它需要进行操作:
当桥接驱动程序调用v4l2_async_notifier_register()时,异步核心会迭代notifier->subdevs数组中的异步子设备。对于每个异步子设备,核心会检查asd->match_type值是否为V4L2_ASYNC_MATCH_FWNODE。如果适用,异步核心会通过比较 fwnodes 来确保asd不在notifier->waiting列表或notifier->done列表中。这可以确保asd尚未为fwnode设置,并且它尚不存在于给定的通知器中。如果asd尚未知晓,则将其添加到notifier->waiting中。之后,异步核心将测试notifier->waiting列表中的所有异步子设备,以与subdev_list中存在的所有子设备进行匹配。subdev_list是“类似”孤立子设备的列表,这些子设备是在其桥接驱动程序(因此在其通知器)之前注册的。异步核心使用每个当前asd的asd->match值进行匹配。如果匹配发生(asd->match回调返回 true),则当前异步子设备(来自notifier->waiting)和当前子设备(来自subdev_list)将被绑定,异步子设备将从notifier->waiting列表中移除,子设备将使用v4l2_device_register_subdev()注册到 V4L2 核心,并且子设备将从全局subdev_list列表移动到notifier->done列表中。
{BANNED}最佳后,被注册的实际通知器将被添加到全局通知器列表notifier_list中,以便在以后使用时,可以在异步核心中注册新的子设备时进行匹配尝试。
当子设备驱动程序调用v4l2_async_register_subdev()时,异步核心会尝试将当前子设备notifier_list全局列表中存在的每个通知器中等待的所有异步子设备进行匹配。如果没有匹配发生,这意味着尚未探测到此子设备的桥接,子设备将被添加到全局子设备列表subdev_list中。如果发生匹配,子设备将根本不会添加到此列表中。
还要记住,匹配测试是在struct v4l2_subdev类型的子设备和struct v4l2_async_subdev类型的异步子设备之间严格发生的一些标准的比较。
struct v4l2_async_notifier_operations {
int (*bound)(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *subdev,
struct v4l2_async_subdev *asd);
int (*complete)(struct v4l2_async_notifier *notifier);
void (*unbind)(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *subdev,
struct v4l2_async_subdev *asd);
};
bound:如果设置,异步核心将在成功的子设备探测后由其(子设备)驱动程序调用此回调。这也意味着异步子设备已成功匹配此子设备。此回调将以发起匹配的通知器以及匹配的子设备(subdev)和异步子设备(asd)作为参数。大多数驱动程序在这里只是打印调试消息。但是,您可以在这里对子设备进行额外的设置-即v4l2_subdev_call()。如果一切正常,它应该返回一个正值;否则,子设备将被注销。
unbind在从系统中移除子设备时被调用。除了在这里打印调试消息外,桥接驱动程序还必须取消注册视频设备,如果未绑定的子设备对其正常工作是必需的-即video_unregister_device()。
complete在通知器中没有更多的异步子设备等待时被调用。异步核心可以检测到notifier->waiting列表为空(这意味着子设备已经成功探测并全部移动到notifier->done列表中)。完成回调仅对根通知器执行。注册了通知器的子设备不会调用其.complete回调。根通知器通常是由桥接设备注册的。
通常在notifier.complete回调中注册实际的视频设备,因为所有子设备都将被注册,且/dev/videoX的存在意味着它确实可用。.complete回调也适用于注册实际视频设备的子节点,并通过v4l2_device_register_subdev_nodes()和media_device_register()注册媒体设备。
请注意,v4l2_device_register_subdev_nodes()将为每个标有V4L2_SUBDEV_FL_HAS_DEVNODE标志的subdev对象创建一个设备节点(实际上是/dev/v4l2-subdevX)。