Blame view
Documentation/media/kapi/v4l2-device.rst
5.45 KB
f6fa883bb [media] doc-rst: ... |
1 2 |
V4L2 device instance -------------------- |
5de379a2f [media] v4l2-devi... |
3 |
|
02ca08b8a [media] v4l2-devi... |
4 |
Each device instance is represented by a struct :c:type:`v4l2_device`. |
5de379a2f [media] v4l2-devi... |
5 6 |
Very simple devices can just allocate this struct, but most of the time you would embed this struct inside a larger struct. |
02ca08b8a [media] v4l2-devi... |
7 |
You must register the device instance by calling: |
5de379a2f [media] v4l2-devi... |
8 |
|
7b998bae0 [media] doc-rst: ... |
9 |
:c:func:`v4l2_device_register <v4l2_device_register>` |
02ca08b8a [media] v4l2-devi... |
10 |
(dev, :c:type:`v4l2_dev <v4l2_device>`). |
5de379a2f [media] v4l2-devi... |
11 |
|
02ca08b8a [media] v4l2-devi... |
12 13 14 |
Registration will initialize the :c:type:`v4l2_device` struct. If the dev->driver_data field is ``NULL``, it will be linked to :c:type:`v4l2_dev <v4l2_device>` argument. |
5de379a2f [media] v4l2-devi... |
15 16 17 |
Drivers that want integration with the media device framework need to set dev->driver_data manually to point to the driver-specific device structure |
02ca08b8a [media] v4l2-devi... |
18 19 20 21 22 23 24 |
that embed the struct :c:type:`v4l2_device` instance. This is achieved by a ``dev_set_drvdata()`` call before registering the V4L2 device instance. They must also set the struct :c:type:`v4l2_device` mdev field to point to a properly initialized and registered :c:type:`media_device` instance. If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a value derived from dev (driver name followed by the bus_id, to be precise). |
7b998bae0 [media] doc-rst: ... |
25 |
If you set it up before calling :c:func:`v4l2_device_register` then it will |
02ca08b8a [media] v4l2-devi... |
26 27 |
be untouched. If dev is ``NULL``, then you **must** setup :c:type:`v4l2_dev <v4l2_device>`\ ->name before calling |
7b998bae0 [media] doc-rst: ... |
28 |
:c:func:`v4l2_device_register`. |
02ca08b8a [media] v4l2-devi... |
29 |
|
7b998bae0 [media] doc-rst: ... |
30 |
You can use :c:func:`v4l2_device_set_name` to set the name based on a driver |
02ca08b8a [media] v4l2-devi... |
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
name and a driver-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`` or ``platform_device``. It is rare for dev to be ``NULL``, but it happens with ISA devices or when one device creates multiple PCI devices, thus making it impossible to associate :c:type:`v4l2_dev <v4l2_device>` with a particular parent. You can also supply a ``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 a sub-device supports must be defined in a header in ``include/media/subdevice.h``. V4L2 devices are unregistered by calling: |
7b998bae0 [media] doc-rst: ... |
47 |
:c:func:`v4l2_device_unregister` |
02ca08b8a [media] v4l2-devi... |
48 49 50 51 52 |
(:c:type:`v4l2_dev <v4l2_device>`). If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`, it will be reset to ``NULL``. Unregistering will also automatically unregister all subdevs from the device. |
5de379a2f [media] v4l2-devi... |
53 54 |
If you have a hotpluggable device (e.g. a USB device), then when a disconnect |
02ca08b8a [media] v4l2-devi... |
55 56 57 |
happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a pointer to that parent device it has to be cleared as well to mark that the parent is gone. To do this call: |
5de379a2f [media] v4l2-devi... |
58 |
|
7b998bae0 [media] doc-rst: ... |
59 |
:c:func:`v4l2_device_disconnect` |
02ca08b8a [media] v4l2-devi... |
60 |
(:c:type:`v4l2_dev <v4l2_device>`). |
5de379a2f [media] v4l2-devi... |
61 62 |
This does *not* unregister the subdevs, so you still need to call the |
7b998bae0 [media] doc-rst: ... |
63 64 |
:c:func:`v4l2_device_unregister` function for that. If your driver is not hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`. |
5de379a2f [media] v4l2-devi... |
65 66 67 68 69 70 71 |
Sometimes you need to iterate over all devices registered by a specific driver. This is usually the case if multiple device drivers use the same hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv hardware. The same is true for alsa drivers for example. You can iterate over all registered devices as follows: |
02ca08b8a [media] v4l2-devi... |
72 |
.. code-block:: c |
5de379a2f [media] v4l2-devi... |
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
static int callback(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); /* test if this device was inited */ if (v4l2_dev == NULL) return 0; ... return 0; } int iterate(void *p) { struct device_driver *drv; int err; /* Find driver 'ivtv' on the PCI bus. pci_bus_type is a global. For USB busses use usb_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); return err; } Sometimes you need to keep a running counter of the device instance. This is commonly used to map a device instance to an index of a module option array. The recommended approach is as follows: |
02ca08b8a [media] v4l2-devi... |
103 |
.. code-block:: c |
5de379a2f [media] v4l2-devi... |
104 105 106 107 108 109 110 111 112 113 |
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; } If you have multiple device nodes then it can be difficult to know when it is |
02ca08b8a [media] v4l2-devi... |
114 115 |
safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this purpose :c:type:`v4l2_device` has refcounting support. The refcount is |
7b998bae0 [media] doc-rst: ... |
116 |
increased whenever :c:func:`video_register_device` is called and it is |
02ca08b8a [media] v4l2-devi... |
117 118 119 |
decreased whenever that device node is released. When the refcount reaches zero, then the :c:type:`v4l2_device` release() callback is called. You can do your final cleanup there. |
5de379a2f [media] v4l2-devi... |
120 121 122 |
If other device nodes (e.g. ALSA) are created, then you can increase and decrease the refcount manually as well by calling: |
7b998bae0 [media] doc-rst: ... |
123 |
:c:func:`v4l2_device_get` |
02ca08b8a [media] v4l2-devi... |
124 |
(:c:type:`v4l2_dev <v4l2_device>`). |
5de379a2f [media] v4l2-devi... |
125 126 |
or: |
7b998bae0 [media] doc-rst: ... |
127 |
:c:func:`v4l2_device_put` |
02ca08b8a [media] v4l2-devi... |
128 |
(:c:type:`v4l2_dev <v4l2_device>`). |
5de379a2f [media] v4l2-devi... |
129 |
|
02ca08b8a [media] v4l2-devi... |
130 |
Since the initial refcount is 1 you also need to call |
7b998bae0 [media] doc-rst: ... |
131 |
:c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices) |
02ca08b8a [media] v4l2-devi... |
132 133 |
or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount will never reach 0. |
5de379a2f [media] v4l2-devi... |
134 |
|
f6fa883bb [media] doc-rst: ... |
135 136 |
v4l2_device functions and data structures ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
587598740 [media] doc-rst: ... |
137 138 |
.. kernel-doc:: include/media/v4l2-device.h |