9.1.5. pvrusb2 驱动程序

作者:Mike Isely <isely@pobox.com>

9.1.5.1. 背景

此驱动程序适用于“Hauppauge WinTV PVR USB 2.0”,这是一款 USB 2.0 托管的电视调谐器。 此驱动程序正在开发中。 它的历史始于 Björn Danielsson <pvrusb2@dax.nu> 的逆向工程工作,其网页可在此处找到:http://pvrusb2.dax.nu/

由此,Aurelien Alleaume <slts@free.fr> 开始努力创建与 video4linux 兼容的驱动程序。 我从 Aurelien 的最后已知快照开始,并将驱动程序发展到现在的状态。

有关此驱动程序的更多信息,请访问:https://www.isely.net/pvrusb2.html

此驱动程序具有很强的层分离。 它们大致是

  1. 与设备的底层线协议实现。

  2. I2C 适配器实现和 V4L 中其他地方实现的相应 I2C 客户端驱动程序。

  3. 高级硬件驱动程序实现,它协调所有活动,以确保设备的正确运行。

  4. 一个“上下文”层,用于管理驱动程序的实例化、设置、拆卸、仲裁以及与高级接口的交互,因为设备热插拔到系统中。

  5. 将驱动程序连接到各种已发布的 Linux API(V4L、sysfs,未来可能还有 DVB)的高级接口。

最重要的剪切层是顶层 2 层之间。 为了确保任何类型的可设想的 API 都可以放在核心驱动程序的顶部,驱动程序进行了大量工作。 (是的,驱动程序在内部利用 V4L 来完成其工作,但这与驱动程序发布到外部世界的 API 没有任何关系。)该架构允许不同的 API 同时访问该驱动程序。 我对 API 有很强的公平感,并且认为将实现和接口彼此隔离是一个良好的设计原则。 因此,虽然现在 V4L 高级接口是最完整的,但 sysfs 高级接口对于类似的功能也能很好地工作,并且我现在看不到任何理由说明为什么不可能生成可以与 V4L 并排使用的 DVB 高级接口。

9.1.5.2. 构建

构建这些模块基本上只是运行“Make”,但是您需要附近的内核源代码树,并且您可能还需要首先设置一些控制环境变量,以便将它们与该源代码树连接起来。 请参阅此处的 Makefile,以获取解释如何执行此操作的注释。

9.1.5.3. 源文件列表/功能概述

(注意:下面使用的术语“模块”通常指 pvrusb2 驱动程序中松散定义的功能单元,与 Linux 内核的可加载模块的概念无关。)

pvrusb2-audio.[ch] - 这是位于

此驱动程序和 msp3400.ko I2C 客户端驱动程序(可在 V4L 中的其他位置找到)之间的粘合逻辑。

pvrusb2-context.[ch] - 此模块实现驱动程序实例的上下文。

其他所有内容最终都绑定到此处实现的数据结构中,或以其他方式在此处实例化。 热插拔最终在此处协调。 所有高级接口都通过此模块连接到驱动程序。 此模块有助于仲裁每个接口对实际驱动程序核心的访问,并旨在允许通过多个接口的多个实例进行并发访问(因此,例如,您可以通过 sysfs 更改调谐器的频率,同时通过 V4L 将视频流式传输到 mplayer 的实例)。

pvrusb2-debug.h - 此标头定义了一个 printk() 包装器和一个掩码

调试位定义,用于可以在驱动程序中启用的各种调试消息。

pvrusb2-debugifc.[ch] - 此模块实现了一个粗略的命令行

面向驱动程序的调试界面。 除了作为实现手动固件提取过程的一部分(请参阅前面提到的 pvrusb2 网站)之外,可能只有我使用过它。 它主要是一个调试辅助工具。

pvrusb2-eeprom.[ch] - 这是位于

驱动程序和 tveeprom.ko 模块之间的粘合逻辑,该模块本身在 V4L 中的其他位置实现。

pvrusb2-encoder.[ch] - 此模块实现了与

与 pvrusb2 设备中的 Conexant mpeg2 编码器芯片交互所需的所有协议。 它是 ivtv 中相应逻辑的粗略回显,但是设计目标(严格隔离)和物理层(通过 USB 而不是 PCI 代理)的不同足以使此实现必须完全不同。

pvrusb2-hdw-internal.h - 此标头定义了核心数据结构

在驱动程序中用于跟踪与硬件控制相关的所有内部状态。 核心硬件处理模块之外的任何人都不得使用此标头。 对驱动程序的所有外部访问都应通过高级接口之一(例如 V4L、sysfs 等),实际上,即使这些高级接口也仅限于 pvrusb2-hdw.h 中定义的 API,而不是此标头。

pvrusb2-hdw.h - 此标头定义了完整的内部 API,用于

控制硬件。 高级接口(例如 V4L、sysfs)将通过此处工作。

pvrusb2-hdw.c - 此模块实现各种逻辑位,

处理特定 pvrusb2 设备的总体控制。 (pvrusb2 设备的策略、实例化和仲裁属于 pvrusb-context 的管辖范围,而不是此处)。

pvrusb2-i2c-chips-*.c - 这些模块实现了粘合逻辑,以

将各种 I2C 模块连接并配置为连接到 I2C 总线。 此文件有两个版本。 “v4l2”版本旨在与 V4L 一起在树中使用,我们在其中仅实现对于纯 V4L 环境有意义的逻辑。 “all”版本旨在在 V4L 之外使用,在那里我们可能会遇到来自 ivtv 或旧内核快照的其他可能“具有挑战性”的模块(甚至独立快照中的支持模块)。

pvrusb2-i2c-cmd-v4l1.[ch] - 此模块实现了通用 V4L1

兼容的 I2C 模块命令。 在这里,pvrusb2 驱动程序内部的状态更改被转换为 V4L1 命令,这些命令又被发送到各种 I2C 模块。

pvrusb2-i2c-cmd-v4l2.[ch] - 此模块实现了通用 V4L2

兼容的 I2C 模块命令。 在这里,pvrusb2 驱动程序内部的状态更改被转换为 V4L2 命令,这些命令又被发送到各种 I2C 模块。

pvrusb2-i2c-core.[ch] - 此模块提供了一个实现

内核友好的 I2C 适配器驱动程序,其他外部 I2C 客户端驱动程序(例如 msp3400、tuner、lirc)可以通过该驱动程序连接和操作 pvrusb2 设备中的相应芯片。 通过此处,其他 V4L 模块可以访问此驱动程序以操作特定部分(这些模块又由粘合逻辑驱动,该粘合逻辑由 pvrusb2-hdw 协调,由 pvrusb2-context 分配,然后最终通过高级接口之一提供给用户)。

pvrusb2-io.[ch] - 此模块实现了一个非常低级的

传输缓冲区环,需要该缓冲区才能从设备流式传输数据。 此模块是非常低级的。 它仅操作缓冲区,并且不尝试定义任何策略或机制来说明如何使用这些缓冲区。

pvrusb2-ioread.[ch] - 此模块分层在 pvrusb2-io.[ch] 之上

以提供可由 read() 系统调用 I/O 样式使用的流式传输 API。 目前,这是 pvrusb2-io.[ch] 之上的唯一层,但是此处的底层架构旨在允许使用其他模块实现其他 I/O 样式,例如 mmap() 的缓冲区或更奇特的缓冲区。

pvrusb2-main.c - 这是驱动程序的顶层。 模块级别

和 USB 核心入口点位于此处。 这是我们的“main”。

pvrusb2-sysfs.[ch] - 这是将

pvrusb2 驱动程序连接到 sysfs 的高级接口。 通过此接口,您可以对驱动程序执行所有操作,但实际上无法流式传输数据。

pvrusb2-tuner.[ch] - 这是位于

驱动程序和 tuner.ko I2C 客户端驱动程序(可在 V4L 中的其他位置找到)之间的粘合逻辑。

pvrusb2-util.h - 此标头定义了一些常用的宏

在整个驱动程序中使用。 这些宏实际上并非特定于驱动程序,但它们必须放在某个地方。

pvrusb2-v4l2.[ch] - 这是将

pvrusb2 驱动程序连接到 video4linux 的高级接口。 通过此处,V4L 应用程序可以以常用的 V4L 方式打开和操作驱动程序。 请注意,所有 V4L 功能仅通过此处发布,而不在其他任何地方发布。

pvrusb2-video-*.[ch] - 这是位于

驱动程序和 saa711x.ko I2C 客户端驱动程序(可在 V4L 中的其他位置找到)之间的粘合逻辑。 请注意,saa711x.ko 过去在 ivtv 中称为 saa7115.ko。 有两个版本,一个版本是根据找到的特定 saa711[5x].ko 选择的。

pvrusb2.h - 此标头包含编译时可调参数

(目前,驱动程序几乎没有需要调整的内容)。