147 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3V4L2 device instance4--------------------5 6Each device instance is represented by a struct v4l2_device.7Very simple devices can just allocate this struct, but most of the time you8would embed this struct inside a larger struct.9 10You must register the device instance by calling:11 12 :c:func:`v4l2_device_register <v4l2_device_register>`13 (dev, :c:type:`v4l2_dev <v4l2_device>`).14 15Registration will initialize the :c:type:`v4l2_device` struct. If the16dev->driver_data field is ``NULL``, it will be linked to17:c:type:`v4l2_dev <v4l2_device>` argument.18 19Drivers that want integration with the media device framework need to set20dev->driver_data manually to point to the driver-specific device structure21that embed the struct v4l2_device instance. This is achieved by a22``dev_set_drvdata()`` call before registering the V4L2 device instance.23They must also set the struct v4l2_device mdev field to point to a24properly initialized and registered :c:type:`media_device` instance.25 26If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a27value derived from dev (driver name followed by the bus_id, to be precise).28If you set it up before calling :c:func:`v4l2_device_register` then it will29be untouched. If dev is ``NULL``, then you **must** setup30:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling31:c:func:`v4l2_device_register`.32 33You can use :c:func:`v4l2_device_set_name` to set the name based on a driver34name and a driver-global atomic_t instance. This will generate names like35``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert36a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.37 38The first ``dev`` argument is normally the ``struct device`` pointer of a39``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to40be ``NULL``, but it happens with ISA devices or when one device creates41multiple PCI devices, thus making it impossible to associate42:c:type:`v4l2_dev <v4l2_device>` with a particular parent.43 44You can also supply a ``notify()`` callback that can be called by sub-devices45to notify you of events. Whether you need to set this depends on the46sub-device. Any notifications a sub-device supports must be defined in a header47in ``include/media/subdevice.h``.48 49V4L2 devices are unregistered by calling:50 51 :c:func:`v4l2_device_unregister`52 (:c:type:`v4l2_dev <v4l2_device>`).53 54If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,55it will be reset to ``NULL``. Unregistering will also automatically unregister56all subdevs from the device.57 58If you have a hotpluggable device (e.g. a USB device), then when a disconnect59happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a60pointer to that parent device it has to be cleared as well to mark that the61parent is gone. To do this call:62 63 :c:func:`v4l2_device_disconnect`64 (:c:type:`v4l2_dev <v4l2_device>`).65 66This does *not* unregister the subdevs, so you still need to call the67:c:func:`v4l2_device_unregister` function for that. If your driver is not68hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`.69 70Sometimes you need to iterate over all devices registered by a specific71driver. This is usually the case if multiple device drivers use the same72hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv73hardware. The same is true for alsa drivers for example.74 75You can iterate over all registered devices as follows:76 77.. code-block:: c78 79 static int callback(struct device *dev, void *p)80 {81 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);82 83 /* test if this device was inited */84 if (v4l2_dev == NULL)85 return 0;86 ...87 return 0;88 }89 90 int iterate(void *p)91 {92 struct device_driver *drv;93 int err;94 95 /* Find driver 'ivtv' on the PCI bus.96 pci_bus_type is a global. For USB buses use usb_bus_type. */97 drv = driver_find("ivtv", &pci_bus_type);98 /* iterate over all ivtv device instances */99 err = driver_for_each_device(drv, NULL, p, callback);100 put_driver(drv);101 return err;102 }103 104Sometimes you need to keep a running counter of the device instance. This is105commonly used to map a device instance to an index of a module option array.106 107The recommended approach is as follows:108 109.. code-block:: c110 111 static atomic_t drv_instance = ATOMIC_INIT(0);112 113 static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)114 {115 ...116 state->instance = atomic_inc_return(&drv_instance) - 1;117 }118 119If you have multiple device nodes then it can be difficult to know when it is120safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this121purpose :c:type:`v4l2_device` has refcounting support. The refcount is122increased whenever :c:func:`video_register_device` is called and it is123decreased whenever that device node is released. When the refcount reaches124zero, then the :c:type:`v4l2_device` release() callback is called. You can125do your final cleanup there.126 127If other device nodes (e.g. ALSA) are created, then you can increase and128decrease the refcount manually as well by calling:129 130 :c:func:`v4l2_device_get`131 (:c:type:`v4l2_dev <v4l2_device>`).132 133or:134 135 :c:func:`v4l2_device_put`136 (:c:type:`v4l2_dev <v4l2_device>`).137 138Since the initial refcount is 1 you also need to call139:c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)140or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount141will never reach 0.142 143v4l2_device functions and data structures144^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^145 146.. kernel-doc:: include/media/v4l2-device.h147