Overview of the V4L2 driver framework(二)
来源:互联网 发布:windows文件夹清理 编辑:程序博客网 时间:2024/04/19 23:46
struct v4l2_device
------------------
Each device instanceis represented by a struct v4l2_device (v4l2-device.h). Very simple devices canjust allocate this struct, but most of the time you would embed this structinside a larger struct.
You must registerthe device instance:
每个设备实例由structv4l2_device(v4l2-device.h)表示。非常简单的设备可以只分配这个结构,但大多数时候你会把这个结构体嵌入一个更大的结构体。
您必须注册设备实例:
v4l2_device_register(structdevice *dev, struct v4l2_device *v4l2_dev);
Registration willinitialize the v4l2_device struct. If the dev->driver_data field is NULL, itwill be linked to v4l2_dev.
Drivers that wantintegration with the media device framework need to set dev->driver_datamanually to point to the driver-specific device structure that embed the structv4l2_device instance. This is achieved by a dev_set_drvdata() call beforeregistering the V4L2 device instance. They must also set the struct v4l2_devicemdev field to point to a properly initialized and registered media_deviceinstance.
If v4l2_dev->nameis empty then it will be set to a value derived from dev (driver name followedby the bus_id, to be precise). If you set it up before callingv4l2_device_register then it will be untouched. If dev is NULL, then you *must*setup v4l2_dev->name before calling v4l2_device_register.
You can usev4l2_device_set_name() to set the name based on a driver name and adriver-global atomic_t instance. This will generate names like ivtv0, ivtv1,etc. If the name ends with a digit, then it will insert a dash: cx18-0, cx18-1,etc. This function returns the instance number.
The first 'dev'argument is normally the struct device pointer of a pci_dev, usb_interface orplatform_device. It is rare for dev to be NULL, but it happens with ISA devicesor when one device creates multiple PCI devices, thus making it impossible toassociate v4l2_dev with a particular parent.
You can also supplya notify() callback that can be called by sub-devices to notify you of events.Whether you need to set this depends on the sub-device. Any notifications asub-device supports must be defined in a header in include/media/<subdevice>.h.
注册将初始化v4l2_device结构。如果dev-> driver_data字段为NULL,它将链接到v4l2_dev。
需要与媒体设备框架集成的驱动程序需要手动设置dev-> driver_data,以指向嵌入structv4l2_device实例的驱动程序特定的设备结构。这是通过在注册V4L2设备实例之前调用dev_set_drvdata()实现的。它们还必须将struct v4l2_device mdev字段设置为指向正确初始化和注册的media_device实例。
如果v4l2_dev->name为空,那么它将被设置为从dev(驱动程序名称,后跟bus_id,精确地)派生的值。如果你在调用v4l2_device_register之前设置它,它将是不变的。如果dev是NULL,那么你必须在调用v4l2_device_register之前设置v4l2_dev->name。
您可以使用v4l2_device_set_name()根据驱动程序名称和驱动程序全局atomic_t实例设置名称。这将生成名称,如ivtv0,ivtv1等。如果名称以一个数字结尾,则它将插入一个破折号:cx18-0,cx18-1等。此函数返回实例号。
第一个“dev”参数通常是pci_dev,usb_interface或platform_device的struct设备指针。 dev很少为NULL,但它发生在ISA设备或一个设备创建多个PCI设备时,因此不可能将v4l2_dev与特定的父进程关联。
您还可以提供一个notify()回调,可以由子设备调用以通知您事件。是否需要设置这取决于子设备。子设备支持的任何通知必须在include / media / <subdevice> .h中的标题中定义。
You unregister with:
您注销:
v4l2_device_unregister(structv4l2_device *v4l2_dev);
If thedev->driver_data field points to v4l2_dev, it will be reset to NULL.Unregistering will also automatically unregister all subdevs from the device.
If you have ahotpluggable device (e.g. a USB device), then when a disconnect happens theparent device becomes invalid. Since v4l2_device has a pointer to that parentdevice it has to be cleared as well to mark that the parent is gone. To do thiscall:
如果dev->driver_data字段指向v4l2_dev,它将被重置为NULL。注销动作也会自动从设备中注销所有子设备。
如果您有热插拔设备(例如USB设备),则当发生断开连接时,父设备将无效。因为v4l2_device有一个指向该父设备的指针,它必须被清除以标记父设备已经走了。要执行此调用:
v4l2_device_disconnect(structv4l2_device *v4l2_dev);
This does *not*unregister the subdevs, so you still need to call the v4l2_device_unregister()function for that. If your driver is not hotpluggable, then there is no need tocall v4l2_device_disconnect().
Sometimes you needto iterate over all devices registered by a specific driver. This is usuallythe case if multiple device drivers use the same hardware. E.g. the ivtvfbdriver is a framebuffer driver that uses the ivtv hardware. The same is truefor alsa drivers for example.
You can iterate overall registered devices as follows:
这*不*注销子变量,所以你仍然需要调用v4l2_device_unregister()函数。如果您的驱动程序不可热插拔,则无需调用v4l2_device_disconnect()。
有时,您需要遍历由特定驱动程序注册的所有设备。如果多个设备驱动程序使用相同的硬件,通常是这种情况。例如。 ivtvfb驱动程序是使用ivtv硬件的framebuffer驱动程序。例如,alsa驱动程序也是如此。
您可以遍历所有注册的设备,如下所示:
static intcallback(struct device *dev, void *p)
{
structv4l2_device *v4l2_dev = dev_get_drvdata(dev);
/*test if this device was inited */
if(v4l2_dev == NULL)
return0;
...
return0;
}
int iterate(void *p)
{
structdevice_driver *drv;
interr;
/*Find driver 'ivtv' on the PCI bus.
pci_bus_type is a global. For USB busses useusb_bus_type. */
drv= driver_find("ivtv", &pci_bus_type);
/*iterate over all ivtv device instances */
err= driver_for_each_device(drv, NULL, p, callback);
put_driver(drv);
returnerr;
}
Sometimes you needto keep a running counter of the device instance. This is commonly used to mapa device instance to an index of a module option array.
The recommendedapproach is as follows:
有时您需要保留设备实例的运行计数器。这通常用于将设备实例映射到模块选项数组的索引。
推荐方法如下:
static atomic_tdrv_instance = ATOMIC_INIT(0);
static intdrv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
...
state->instance= atomic_inc_return(&drv_instance) - 1;
}
If you have multipledevice nodes then it can be difficult to know when it is safe to unregisterv4l2_device for hotpluggable devices. For this purpose v4l2_device hasrefcounting support. The refcount is increased whenever video_register_deviceis called and it is decreased whenever that device node is released. When therefcount reaches zero, then the v4l2_device release() callback is called. Youcan do your final cleanup there.
If other devicenodes (e.g. ALSA) are created, then you can increase and decrease the refcountmanually as well by calling:
如果您有多个设备节点,那么可能很难知道何时安全地注销可热插拔设备的v4l2_device。 为此,v4l2_device具有引用计数支持。 每当调用video_register_device时,引用计数都会增加,并且只要设备节点被释放,引用计数就会减少。当引用计数达到零时,则调用v4l2_devicerelease()回调。 你可以在那里做最后的清理。
如果创建了其他设备节点(例如ALSA),则可以通过调用以手动方式增加和减少引用计数:
voidv4l2_device_get(struct v4l2_device *v4l2_dev);
or:
intv4l2_device_put(struct v4l2_device *v4l2_dev);
Since the initialrefcount is 1 you also need to call v4l2_device_put in the disconnect()callback (for USB devices) or in the remove() callback (for e.g. PCI devices),otherwise the refcount will never reach 0.
由于初始引用计数为1,还需要在disconnect()回调(对于USB设备)或remove()回调(例如PCI设备)中调用v4l2_device_put,否则引用计数永远不会达到0。
- Overview of the V4L2 driver framework(二)
- Overview of the V4L2 driver framework (v4l2_device)
- Overview of the V4L2 driver framework(一)
- Overview of the .NET Framework
- V4L2 driver framework
- Overview of webapp framework
- Overview of Enhancement Framework
- Overview of Spring Framework
- Overview of the Book
- Swift 学习笔记 UITableView (二)Overview of the table View API
- overview of hevc (二)
- Overview of the Financial Accounting
- Overview of the CATIA MMLs
- overview of the TableView API
- 3.1. Overview of the Patterns
- v4l2 编程接口(二) — driver
- v4l2 编程接口(二) — driver
- v4l2 编程接口(二) — driver
- MyBatis 源码分析——介绍
- jquery对象和DOM对象相互转换
- 【C++】指针(4):指针数组
- P1064 金明的预算方案
- 堆排序Heap_Sort
- Overview of the V4L2 driver framework(二)
- js 自动更新年份
- [java基础]匿名内部类的使用
- simpson积分公式
- 【C++】指针(5):指向指针的指针
- MyBatis 源码分析——配置信息
- 【BZOJ1036】[ZJOI2008]树的统计Count(树链剖分+线段树)
- 深入浅出 React Native:使用 JavaScript 构建原生应用
- leetcode_middle_12_445. Add Two Numbers II