Documentation/translations/zh_CN/video4linux/v4l2-framework.txt

Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt

File Facts

System
Linux kernel
Corpus path
Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
Extension
.txt
Size
39044 bytes
Lines
959
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct device_driver *drv;
	int err;

	/* 在PCI 总线上查找ivtv驱动。
	   pci_bus_type是全局的. 对于USB总线使用usb_bus_type。 */
	drv = driver_find("ivtv", &pci_bus_type);
	/* 遍历所有的ivtv设备实例 */
	err = driver_for_each_device(drv, NULL, p, callback);
	put_driver(drv);
	return err;
}

有时你需要一个设备实例的运行计数。这个通常用于映射一个设备实例到一个
模块选择数组的索引。

推荐方法如下:

static atomic_t drv_instance = ATOMIC_INIT(0);

static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
	...
	state->instance = atomic_inc_return(&drv_instance) - 1;
}

如果你有多个设备节点,对于热插拔设备,知道何时注销 v4l2_device 结构体
就比较困难。为此 v4l2_device 有引用计数支持。当调用 video_register_device
时增加引用计数,而设备节点释放时减小引用计数。当引用计数为零,则
v4l2_device 的release() 回调将被执行。你就可以在此时做最后的清理工作。

如果创建了其他设备节点(比如 ALSA),则你可以通过以下函数手动增减
引用计数:

void v4l2_device_get(struct v4l2_device *v4l2_dev);

或:

int v4l2_device_put(struct v4l2_device *v4l2_dev);

由于引用技术初始化为 1 ,你也需要在 disconnect() 回调(对于 USB 设备)中
调用 v4l2_device_put,或者 remove() 回调(例如对于 PCI 设备),否则
引用计数将永远不会为 0 。

v4l2_subdev结构体
------------------

许多驱动需要与子设备通信。这些设备可以完成各种任务,但通常他们负责
音视频复用和编解码。如网络摄像头的子设备通常是传感器和摄像头控制器。

这些一般为 I2C 接口设备,但并不一定都是。为了给驱动提供调用子设备的
统一接口,v4l2_subdev 结构体(v4l2-subdev.h)产生了。

每个子设备驱动都必须有一个 v4l2_subdev 结构体。这个结构体可以单独
代表一个简单的子设备,也可以嵌入到一个更大的结构体中,与更多设备状态
信息保存在一起。通常有一个下级设备结构体(比如:i2c_client)包含了
内核创建的设备数据。建议使用 v4l2_set_subdevdata() 将这个结构体的
指针保存在 v4l2_subdev 的私有数据域(dev_priv)中。这使得通过 v4l2_subdev
找到实际的低层总线特定设备数据变得容易。

你同时需要一个从低层结构体获取 v4l2_subdev 指针的方法。对于常用的
i2c_client 结构体,i2c_set_clientdata() 函数可用于保存一个 v4l2_subdev
指针;对于其他总线你可能需要使用其他相关函数。

桥驱动中也应保存每个子设备的私有数据,比如一个指向特定桥的各设备私有
数据的指针。为此 v4l2_subdev 结构体提供主机私有数据域(host_priv),
并可通过 v4l2_get_subdev_hostdata() 和 v4l2_set_subdev_hostdata()
访问。

从总线桥驱动的视角,驱动加载子设备模块并以某种方式获得 v4l2_subdev
结构体指针。对于 i2c 总线设备相对简单:调用 i2c_get_clientdata()。

Annotation

Implementation Notes