~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/driver-api/media/v4l2-device.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/driver-api/media/v4l2-device.rst (Version linux-6.12-rc7) and /Documentation/driver-api/media/v4l2-device.rst (Version linux-5.11.22)


  1 .. SPDX-License-Identifier: GPL-2.0                 1 .. SPDX-License-Identifier: GPL-2.0
  2                                                     2 
  3 V4L2 device instance                                3 V4L2 device instance
  4 --------------------                                4 --------------------
  5                                                     5 
  6 Each device instance is represented by a struc      6 Each device instance is represented by a struct v4l2_device.
  7 Very simple devices can just allocate this str      7 Very simple devices can just allocate this struct, but most of the time you
  8 would embed this struct inside a larger struct      8 would embed this struct inside a larger struct.
  9                                                     9 
 10 You must register the device instance by calli     10 You must register the device instance by calling:
 11                                                    11 
 12         :c:func:`v4l2_device_register <v4l2_de     12         :c:func:`v4l2_device_register <v4l2_device_register>`
 13         (dev, :c:type:`v4l2_dev <v4l2_device>`     13         (dev, :c:type:`v4l2_dev <v4l2_device>`).
 14                                                    14 
 15 Registration will initialize the :c:type:`v4l2     15 Registration will initialize the :c:type:`v4l2_device` struct. If the
 16 dev->driver_data field is ``NULL``, it will be     16 dev->driver_data field is ``NULL``, it will be linked to
 17 :c:type:`v4l2_dev <v4l2_device>` argument.         17 :c:type:`v4l2_dev <v4l2_device>` argument.
 18                                                    18 
 19 Drivers that want integration with the media d     19 Drivers that want integration with the media device framework need to set
 20 dev->driver_data manually to point to the driv     20 dev->driver_data manually to point to the driver-specific device structure
 21 that embed the struct v4l2_device instance. Th     21 that embed the struct v4l2_device instance. This is achieved by a
 22 ``dev_set_drvdata()`` call before registering      22 ``dev_set_drvdata()`` call before registering the V4L2 device instance.
 23 They must also set the struct v4l2_device mdev     23 They must also set the struct v4l2_device mdev field to point to a
 24 properly initialized and registered :c:type:`m     24 properly initialized and registered :c:type:`media_device` instance.
 25                                                    25 
 26 If :c:type:`v4l2_dev <v4l2_device>`\ ->name is     26 If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
 27 value derived from dev (driver name followed b     27 value derived from dev (driver name followed by the bus_id, to be precise).
 28 If you set it up before  calling :c:func:`v4l2     28 If you set it up before  calling :c:func:`v4l2_device_register` then it will
 29 be untouched. If dev is ``NULL``, then you **m     29 be untouched. If dev is ``NULL``, then you **must** setup
 30 :c:type:`v4l2_dev <v4l2_device>`\ ->name befor     30 :c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
 31 :c:func:`v4l2_device_register`.                    31 :c:func:`v4l2_device_register`.
 32                                                    32 
 33 You can use :c:func:`v4l2_device_set_name` to      33 You can use :c:func:`v4l2_device_set_name` to set the name based on a driver
 34 name and a driver-global atomic_t instance. Th     34 name and a driver-global atomic_t instance. This will generate names like
 35 ``ivtv0``, ``ivtv1``, etc. If the name ends wi     35 ``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert
 36 a dash: ``cx18-0``, ``cx18-1``, etc. This func     36 a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.
 37                                                    37 
 38 The first ``dev`` argument is normally the ``s     38 The first ``dev`` argument is normally the ``struct device`` pointer of a
 39 ``pci_dev``, ``usb_interface`` or ``platform_d     39 ``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to
 40 be ``NULL``, but it happens with ISA devices o     40 be ``NULL``, but it happens with ISA devices or when one device creates
 41 multiple PCI devices, thus making it impossibl     41 multiple PCI devices, thus making it impossible to associate
 42 :c:type:`v4l2_dev <v4l2_device>` with a partic     42 :c:type:`v4l2_dev <v4l2_device>` with a particular parent.
 43                                                    43 
 44 You can also supply a ``notify()`` callback th     44 You can also supply a ``notify()`` callback that can be called by sub-devices
 45 to notify you of events. Whether you need to s     45 to notify you of events. Whether you need to set this depends on the
 46 sub-device. Any notifications a sub-device sup     46 sub-device. Any notifications a sub-device supports must be defined in a header
 47 in ``include/media/subdevice.h``.                  47 in ``include/media/subdevice.h``.
 48                                                    48 
 49 V4L2 devices are unregistered by calling:          49 V4L2 devices are unregistered by calling:
 50                                                    50 
 51         :c:func:`v4l2_device_unregister`           51         :c:func:`v4l2_device_unregister`
 52         (:c:type:`v4l2_dev <v4l2_device>`).        52         (:c:type:`v4l2_dev <v4l2_device>`).
 53                                                    53 
 54 If the dev->driver_data field points to :c:typ     54 If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,
 55 it will be reset to ``NULL``. Unregistering wi     55 it will be reset to ``NULL``. Unregistering will also automatically unregister
 56 all subdevs from the device.                       56 all subdevs from the device.
 57                                                    57 
 58 If you have a hotpluggable device (e.g. a USB      58 If you have a hotpluggable device (e.g. a USB device), then when a disconnect
 59 happens the parent device becomes invalid. Sin     59 happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a
 60 pointer to that parent device it has to be cle     60 pointer to that parent device it has to be cleared as well to mark that the
 61 parent is gone. To do this call:                   61 parent is gone. To do this call:
 62                                                    62 
 63         :c:func:`v4l2_device_disconnect`           63         :c:func:`v4l2_device_disconnect`
 64         (:c:type:`v4l2_dev <v4l2_device>`).        64         (:c:type:`v4l2_dev <v4l2_device>`).
 65                                                    65 
 66 This does *not* unregister the subdevs, so you     66 This does *not* unregister the subdevs, so you still need to call the
 67 :c:func:`v4l2_device_unregister` function for      67 :c:func:`v4l2_device_unregister` function for that. If your driver is not
 68 hotpluggable, then there is no need to call :c     68 hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`.
 69                                                    69 
 70 Sometimes you need to iterate over all devices     70 Sometimes you need to iterate over all devices registered by a specific
 71 driver. This is usually the case if multiple d     71 driver. This is usually the case if multiple device drivers use the same
 72 hardware. E.g. the ivtvfb driver is a framebuf     72 hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
 73 hardware. The same is true for alsa drivers fo     73 hardware. The same is true for alsa drivers for example.
 74                                                    74 
 75 You can iterate over all registered devices as     75 You can iterate over all registered devices as follows:
 76                                                    76 
 77 .. code-block:: c                                  77 .. code-block:: c
 78                                                    78 
 79         static int callback(struct device *dev     79         static int callback(struct device *dev, void *p)
 80         {                                          80         {
 81                 struct v4l2_device *v4l2_dev =     81                 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
 82                                                    82 
 83                 /* test if this device was ini     83                 /* test if this device was inited */
 84                 if (v4l2_dev == NULL)              84                 if (v4l2_dev == NULL)
 85                         return 0;                  85                         return 0;
 86                 ...                                86                 ...
 87                 return 0;                          87                 return 0;
 88         }                                          88         }
 89                                                    89 
 90         int iterate(void *p)                       90         int iterate(void *p)
 91         {                                          91         {
 92                 struct device_driver *drv;         92                 struct device_driver *drv;
 93                 int err;                           93                 int err;
 94                                                    94 
 95                 /* Find driver 'ivtv' on the P     95                 /* Find driver 'ivtv' on the PCI bus.
 96                 pci_bus_type is a global. For      96                 pci_bus_type is a global. For USB buses use usb_bus_type. */
 97                 drv = driver_find("ivtv", &pci     97                 drv = driver_find("ivtv", &pci_bus_type);
 98                 /* iterate over all ivtv devic     98                 /* iterate over all ivtv device instances */
 99                 err = driver_for_each_device(d     99                 err = driver_for_each_device(drv, NULL, p, callback);
100                 put_driver(drv);                  100                 put_driver(drv);
101                 return err;                       101                 return err;
102         }                                         102         }
103                                                   103 
104 Sometimes you need to keep a running counter o    104 Sometimes you need to keep a running counter of the device instance. This is
105 commonly used to map a device instance to an i    105 commonly used to map a device instance to an index of a module option array.
106                                                   106 
107 The recommended approach is as follows:           107 The recommended approach is as follows:
108                                                   108 
109 .. code-block:: c                                 109 .. code-block:: c
110                                                   110 
111         static atomic_t drv_instance = ATOMIC_    111         static atomic_t drv_instance = ATOMIC_INIT(0);
112                                                   112 
113         static int drv_probe(struct pci_dev *p    113         static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
114         {                                         114         {
115                 ...                               115                 ...
116                 state->instance = atomic_inc_r    116                 state->instance = atomic_inc_return(&drv_instance) - 1;
117         }                                         117         }
118                                                   118 
119 If you have multiple device nodes then it can     119 If you have multiple device nodes then it can be difficult to know when it is
120 safe to unregister :c:type:`v4l2_device` for h    120 safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this
121 purpose :c:type:`v4l2_device` has refcounting     121 purpose :c:type:`v4l2_device` has refcounting support. The refcount is
122 increased whenever :c:func:`video_register_dev    122 increased whenever :c:func:`video_register_device` is called and it is
123 decreased whenever that device node is release    123 decreased whenever that device node is released. When the refcount reaches
124 zero, then the :c:type:`v4l2_device` release()    124 zero, then the :c:type:`v4l2_device` release() callback is called. You can
125 do your final cleanup there.                      125 do your final cleanup there.
126                                                   126 
127 If other device nodes (e.g. ALSA) are created,    127 If other device nodes (e.g. ALSA) are created, then you can increase and
128 decrease the refcount manually as well by call    128 decrease the refcount manually as well by calling:
129                                                   129 
130         :c:func:`v4l2_device_get`                 130         :c:func:`v4l2_device_get`
131         (:c:type:`v4l2_dev <v4l2_device>`).       131         (:c:type:`v4l2_dev <v4l2_device>`).
132                                                   132 
133 or:                                               133 or:
134                                                   134 
135         :c:func:`v4l2_device_put`                 135         :c:func:`v4l2_device_put`
136         (:c:type:`v4l2_dev <v4l2_device>`).       136         (:c:type:`v4l2_dev <v4l2_device>`).
137                                                   137 
138 Since the initial refcount is 1 you also need     138 Since the initial refcount is 1 you also need to call
139 :c:func:`v4l2_device_put` in the ``disconnect(    139 :c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)
140 or in the ``remove()`` callback (for e.g. PCI     140 or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount
141 will never reach 0.                               141 will never reach 0.
142                                                   142 
143 v4l2_device functions and data structures         143 v4l2_device functions and data structures
144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^         144 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
145                                                   145 
146 .. kernel-doc:: include/media/v4l2-device.h       146 .. kernel-doc:: include/media/v4l2-device.h
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php