diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-07-17 18:25:27 (GMT) |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-07-17 19:30:35 (GMT) |
commit | 4c21d4fb1b16eaaa6462e76a0eb6b70235a966ea (patch) | |
tree | 8c44dcb4b853243766bd42ffd3ee557ad69ec39d /Documentation/media/kapi | |
parent | f6ebc2d341b57b233368ae8d6a0e4087e724cb10 (diff) | |
download | linux-4c21d4fb1b16eaaa6462e76a0eb6b70235a966ea.tar.xz |
[media] doc-rst: do a poor man's conversion of v4l2-framework
Make Sphinx happy with v4l2-framework.rst by putting all C
code inside code-block.
Please note that this is a poor man ReST conversion, as several
of those blocks should actually be converted to use :cpp:func:,
pointing to the kAPI auto-generated documentation.
The problem is that we currently lack kernel-doc documentation
for most of the stuff described there.
So, let's do a poor man's conversion. We should later address
this.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'Documentation/media/kapi')
-rw-r--r-- | Documentation/media/kapi/v4l2-framework.rst | 358 |
1 files changed, 230 insertions, 128 deletions
diff --git a/Documentation/media/kapi/v4l2-framework.rst b/Documentation/media/kapi/v4l2-framework.rst index cbefc79..740875d 100644 --- a/Documentation/media/kapi/v4l2-framework.rst +++ b/Documentation/media/kapi/v4l2-framework.rst @@ -57,6 +57,8 @@ All drivers have the following structure: This is a rough schematic of how it all relates: +.. code-block:: none + device instances | +-sub-device instances @@ -88,6 +90,8 @@ would embed this struct inside a larger struct. You must register the device instance: +.. code-block:: none + v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); Registration will initialize the v4l2_device struct. If the dev->driver_data @@ -103,7 +107,7 @@ and registered media_device instance. If v4l2_dev->name is empty then it will be set to a value derived from dev (driver name followed by the bus_id, to be precise). If you set it up before calling v4l2_device_register then it will be untouched. If dev is NULL, then -you *must* setup v4l2_dev->name before calling v4l2_device_register. +you **must** setup v4l2_dev->name before calling v4l2_device_register. You can use v4l2_device_set_name() to set the name based on a driver name and a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1, @@ -122,6 +126,8 @@ include/media/<subdevice>.h. You unregister with: +.. code-block:: none + v4l2_device_unregister(struct v4l2_device *v4l2_dev); If the dev->driver_data field points to v4l2_dev, it will be reset to NULL. @@ -132,6 +138,8 @@ happens the parent device becomes invalid. Since 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: +.. code-block:: none + v4l2_device_disconnect(struct v4l2_device *v4l2_dev); This does *not* unregister the subdevs, so you still need to call the @@ -145,43 +153,47 @@ hardware. The same is true for alsa drivers for example. You can iterate over all registered devices as follows: -static int callback(struct device *dev, void *p) -{ - struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); +.. code-block:: none - /* test if this device was inited */ - if (v4l2_dev == NULL) - return 0; - ... - return 0; -} + static int callback(struct device *dev, void *p) + { + struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); -int iterate(void *p) -{ - struct device_driver *drv; - int err; + /* test if this device was inited */ + if (v4l2_dev == NULL) + return 0; + ... + return 0; + } - /* 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; -} + 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: -static atomic_t drv_instance = ATOMIC_INIT(0); +.. code-block:: none -static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) -{ - ... - state->instance = atomic_inc_return(&drv_instance) - 1; -} + 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 safe to unregister v4l2_device for hotpluggable devices. For this purpose @@ -193,11 +205,15 @@ callback is called. You can do your final cleanup there. If other device nodes (e.g. ALSA) are created, then you can increase and decrease the refcount manually as well by calling: -void v4l2_device_get(struct v4l2_device *v4l2_dev); +.. code-block:: none + + void v4l2_device_get(struct v4l2_device *v4l2_dev); or: -int v4l2_device_put(struct v4l2_device *v4l2_dev); +.. code-block:: none + + int v4l2_device_put(struct v4l2_device *v4l2_dev); Since the initial refcount 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. @@ -249,35 +265,37 @@ may be NULL if the subdev driver does not support anything from that category. It looks like this: -struct v4l2_subdev_core_ops { - int (*log_status)(struct v4l2_subdev *sd); - int (*init)(struct v4l2_subdev *sd, u32 val); - ... -}; +.. code-block:: none -struct v4l2_subdev_tuner_ops { - ... -}; + struct v4l2_subdev_core_ops { + int (*log_status)(struct v4l2_subdev *sd); + int (*init)(struct v4l2_subdev *sd, u32 val); + ... + }; -struct v4l2_subdev_audio_ops { - ... -}; + struct v4l2_subdev_tuner_ops { + ... + }; -struct v4l2_subdev_video_ops { - ... -}; + struct v4l2_subdev_audio_ops { + ... + }; -struct v4l2_subdev_pad_ops { - ... -}; + struct v4l2_subdev_video_ops { + ... + }; + + struct v4l2_subdev_pad_ops { + ... + }; -struct v4l2_subdev_ops { - const struct v4l2_subdev_core_ops *core; - const struct v4l2_subdev_tuner_ops *tuner; - const struct v4l2_subdev_audio_ops *audio; - const struct v4l2_subdev_video_ops *video; - const struct v4l2_subdev_pad_ops *video; -}; + struct v4l2_subdev_ops { + const struct v4l2_subdev_core_ops *core; + const struct v4l2_subdev_tuner_ops *tuner; + const struct v4l2_subdev_audio_ops *audio; + const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_pad_ops *video; + }; The core ops are common to all subdevs, the other categories are implemented depending on the sub-device. E.g. a video device is unlikely to support the @@ -288,6 +306,8 @@ to add new ops and categories. A sub-device driver initializes the v4l2_subdev struct using: +.. code-block:: none + v4l2_subdev_init(sd, &ops); Afterwards you need to initialize subdev->name with a unique name and set the @@ -297,6 +317,8 @@ If integration with the media framework is needed, you must initialize the media_entity struct embedded in the v4l2_subdev struct (entity field) by calling media_entity_pads_init(), if the entity has pads: +.. code-block:: none + struct media_pad *pads = &my_sd->pads; int err; @@ -311,6 +333,8 @@ subdev device node (if any) is opened/closed. Don't forget to cleanup the media entity before the sub-device is destroyed: +.. code-block:: none + media_entity_cleanup(&sd->entity); If the subdev driver intends to process video and integrate with the media @@ -351,6 +375,8 @@ run-time bridge-subdevice interaction is in both cases the same. In the synchronous case a device (bridge) driver needs to register the v4l2_subdev with the v4l2_device: +.. code-block:: none + int err = v4l2_device_register_subdev(v4l2_dev, sd); This can fail if the subdev module disappeared before it could be registered. @@ -362,16 +388,22 @@ entity will be automatically registered with the media device. You can unregister a sub-device using: +.. code-block:: none + v4l2_device_unregister_subdev(sd); Afterwards the subdev module can be unloaded and sd->dev == NULL. You can call an ops function either directly: +.. code-block:: none + err = sd->ops->core->g_std(sd, &norm); but it is better and easier to use this macro: +.. code-block:: none + err = v4l2_subdev_call(sd, core, g_std, &norm); The macro will to the right NULL pointer checks and returns -ENODEV if subdev @@ -380,11 +412,15 @@ NULL, or the actual result of the subdev->ops->core->g_std ops. It is also possible to call all or a subset of the sub-devices: +.. code-block:: none + v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm); Any subdev that does not support this ops is skipped and error results are ignored. If you want to check for errors use this: +.. code-block:: none + err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm); Any error except -ENOIOCTLCMD will exit the loop with that error. If no @@ -509,13 +545,17 @@ you can just create a v4l2_subdev directly. A typical state struct would look like this (where 'chipname' is replaced by the name of the chip): -struct chipname_state { - struct v4l2_subdev sd; - ... /* additional state fields */ -}; +.. code-block:: none + + struct chipname_state { + struct v4l2_subdev sd; + ... /* additional state fields */ + }; Initialize the v4l2_subdev struct as follows: +.. code-block:: none + v4l2_i2c_subdev_init(&state->sd, client, subdev_ops); This function will fill in all the fields of v4l2_subdev and ensure that the @@ -524,17 +564,23 @@ v4l2_subdev and i2c_client both point to one another. You should also add a helper inline function to go from a v4l2_subdev pointer to a chipname_state struct: -static inline struct chipname_state *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct chipname_state, sd); -} +.. code-block:: none + + static inline struct chipname_state *to_state(struct v4l2_subdev *sd) + { + return container_of(sd, struct chipname_state, sd); + } Use this to go from the v4l2_subdev struct to the i2c_client struct: +.. code-block:: none + struct i2c_client *client = v4l2_get_subdevdata(sd); And this to go from an i2c_client to a v4l2_subdev struct: +.. code-block:: none + struct v4l2_subdev *sd = i2c_get_clientdata(client); Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback @@ -550,8 +596,10 @@ from the remove() callback ensures that this is always done correctly. The bridge driver also has some helper functions it can use: -struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, - "module_foo", "chipid", 0x36, NULL); +.. code-block:: none + + struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, + "module_foo", "chipid", 0x36, NULL); This loads the given module (can be NULL if no module needs to be loaded) and calls i2c_new_device() with the given i2c_adapter and chip/address arguments. @@ -581,15 +629,17 @@ are probed. For example: this will probe for address 0x10: -struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, - "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10)); +.. code-block:: none + + struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, + "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10)); v4l2_i2c_new_subdev_board uses an i2c_board_info struct which is passed to the i2c driver and replaces the irq, platform_data and addr arguments. If the subdev supports the s_config core ops, then that op is called with the irq and platform_data arguments after the subdev was setup. The older -v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with +v4l2_i2c_new_(probed\_)subdev functions will call s_config as well, but with irq set to 0 and platform_data set to NULL. struct video_device @@ -601,6 +651,8 @@ dynamically or embedded in a larger struct. To allocate it dynamically use: +.. code-block:: none + struct video_device *vdev = video_device_alloc(); if (vdev == NULL) @@ -611,6 +663,8 @@ To allocate it dynamically use: If you embed it in a larger struct, then you must set the release() callback to your own function: +.. code-block:: none + struct video_device *vdev = &my_vdev->vdev; vdev->release = my_vdev_release; @@ -684,7 +738,9 @@ In some cases you want to tell the core that a function you had specified in your v4l2_ioctl_ops should be ignored. You can mark such ioctls by calling this function before video_device_register is called: -void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd); +.. code-block:: none + + void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd); This tends to be needed if based on external factors (e.g. which card is being used) you want to turns off certain features in v4l2_ioctl_ops without @@ -697,6 +753,8 @@ If integration with the media framework is needed, you must initialize the media_entity struct embedded in the video_device struct (entity field) by calling media_entity_pads_init(): +.. code-block:: none + struct media_pad *pad = &my_vdev->pad; int err; @@ -752,6 +810,8 @@ video_device registration Next you register the video device: this will create the character device for you. +.. code-block:: none + err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (err) { video_device_release(vdev); /* or kfree(my_vdev); */ @@ -827,16 +887,18 @@ file operations. It is a bitmask and the following bits can be set: -0x01: Log the ioctl name and error code. VIDIOC_(D)QBUF ioctls are only logged - if bit 0x08 is also set. -0x02: Log the ioctl name arguments and error code. VIDIOC_(D)QBUF ioctls are - only logged if bit 0x08 is also set. -0x04: Log the file operations open, release, read, write, mmap and - get_unmapped_area. The read and write operations are only logged if - bit 0x08 is also set. -0x08: Log the read and write file operations and the VIDIOC_QBUF and - VIDIOC_DQBUF ioctls. -0x10: Log the poll file operation. +.. code-block:: none + + 0x01: Log the ioctl name and error code. VIDIOC_(D)QBUF ioctls are only logged + if bit 0x08 is also set. + 0x02: Log the ioctl name arguments and error code. VIDIOC_(D)QBUF ioctls are + only logged if bit 0x08 is also set. + 0x04: Log the file operations open, release, read, write, mmap and + get_unmapped_area. The read and write operations are only logged if + bit 0x08 is also set. + 0x08: Log the read and write file operations and the VIDIOC_QBUF and + VIDIOC_DQBUF ioctls. + 0x10: Log the poll file operation. video_device cleanup -------------------- @@ -845,6 +907,8 @@ When the video device nodes have to be removed, either during the unload of the driver or because the USB device was disconnected, then you should unregister them: +.. code-block:: none + video_unregister_device(vdev); This will remove the device nodes from sysfs (causing udev to remove them @@ -861,6 +925,8 @@ callback is called and you can do the final cleanup there. Don't forget to cleanup the media entity associated with the video device if it has been initialized: +.. code-block:: none + media_entity_cleanup(&vdev->entity); This can be done from the release callback. @@ -875,31 +941,41 @@ There are a few useful helper functions: You can set/get driver private data in the video_device struct using: -void *video_get_drvdata(struct video_device *vdev); -void video_set_drvdata(struct video_device *vdev, void *data); +.. code-block:: none + + void *video_get_drvdata(struct video_device *vdev); + void video_set_drvdata(struct video_device *vdev, void *data); Note that you can safely call video_set_drvdata() before calling video_register_device(). And this function: -struct video_device *video_devdata(struct file *file); +.. code-block:: none + + struct video_device *video_devdata(struct file *file); returns the video_device belonging to the file struct. The video_drvdata function combines video_get_drvdata with video_devdata: -void *video_drvdata(struct file *file); +.. code-block:: none + + void *video_drvdata(struct file *file); You can go from a video_device struct to the v4l2_device struct using: -struct v4l2_device *v4l2_dev = vdev->v4l2_dev; +.. code-block:: none + + struct v4l2_device *v4l2_dev = vdev->v4l2_dev; - Device node name The video_device node kernel name can be retrieved using -const char *video_device_node_name(struct video_device *vdev); +.. code-block:: none + + const char *video_device_node_name(struct video_device *vdev); The name is used as a hint by userspace tools such as udev. The function should be used where possible instead of accessing the video_device::num and @@ -943,64 +1019,74 @@ v4l2_fh_del+v4l2_fh_exit in release(). Drivers can extract their own file handle structure by using the container_of macro. Example: -struct my_fh { - int blah; - struct v4l2_fh fh; -}; +.. code-block:: none -... - -int my_open(struct file *file) -{ - struct my_fh *my_fh; - struct video_device *vfd; - int ret; + struct my_fh { + int blah; + struct v4l2_fh fh; + }; ... - my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL); + int my_open(struct file *file) + { + struct my_fh *my_fh; + struct video_device *vfd; + int ret; - ... + ... - v4l2_fh_init(&my_fh->fh, vfd); + my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL); - ... + ... - file->private_data = &my_fh->fh; - v4l2_fh_add(&my_fh->fh); - return 0; -} + v4l2_fh_init(&my_fh->fh, vfd); -int my_release(struct file *file) -{ - struct v4l2_fh *fh = file->private_data; - struct my_fh *my_fh = container_of(fh, struct my_fh, fh); + ... - ... - v4l2_fh_del(&my_fh->fh); - v4l2_fh_exit(&my_fh->fh); - kfree(my_fh); - return 0; -} + file->private_data = &my_fh->fh; + v4l2_fh_add(&my_fh->fh); + return 0; + } + + int my_release(struct file *file) + { + struct v4l2_fh *fh = file->private_data; + struct my_fh *my_fh = container_of(fh, struct my_fh, fh); + + ... + v4l2_fh_del(&my_fh->fh); + v4l2_fh_exit(&my_fh->fh); + kfree(my_fh); + return 0; + } Below is a short description of the v4l2_fh functions used: -void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) +.. code-block:: none + + void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) Initialise the file handle. This *MUST* be performed in the driver's v4l2_file_operations->open() handler. -void v4l2_fh_add(struct v4l2_fh *fh) +.. code-block:: none + + void v4l2_fh_add(struct v4l2_fh *fh) Add a v4l2_fh to video_device file handle list. Must be called once the file handle is completely initialized. -void v4l2_fh_del(struct v4l2_fh *fh) +.. code-block:: none + + void v4l2_fh_del(struct v4l2_fh *fh) Unassociate the file handle from video_device(). The file handle exit function may now be called. -void v4l2_fh_exit(struct v4l2_fh *fh) +.. code-block:: none + + void v4l2_fh_exit(struct v4l2_fh *fh) Uninitialise the file handle. After uninitialisation the v4l2_fh memory can be freed. @@ -1008,12 +1094,16 @@ void v4l2_fh_exit(struct v4l2_fh *fh) If struct v4l2_fh is not embedded, then you can use these helper functions: -int v4l2_fh_open(struct file *filp) +.. code-block:: none + + int v4l2_fh_open(struct file *filp) This allocates a struct v4l2_fh, initializes it and adds it to the struct video_device associated with the file struct. -int v4l2_fh_release(struct file *filp) +.. code-block:: none + + int v4l2_fh_release(struct file *filp) This deletes it from the struct video_device associated with the file struct, uninitialised the v4l2_fh and frees it. @@ -1027,11 +1117,15 @@ when the last file handle closes. Two helper functions were added to check whether the v4l2_fh struct is the only open filehandle of the associated device node: -int v4l2_fh_is_singular(struct v4l2_fh *fh) +.. code-block:: none + + int v4l2_fh_is_singular(struct v4l2_fh *fh) Returns 1 if the file handle is the only open file handle, else 0. -int v4l2_fh_is_singular_file(struct file *filp) +.. code-block:: none + + int v4l2_fh_is_singular_file(struct file *filp) Same, but it calls v4l2_fh_is_singular with filp->private_data. @@ -1075,15 +1169,19 @@ fast. Useful functions: -void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev) +.. code-block:: none + + void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev) Queue events to video device. The driver's only responsibility is to fill in the type and the data fields. The other fields will be filled in by V4L2. -int v4l2_event_subscribe(struct v4l2_fh *fh, - struct v4l2_event_subscription *sub, unsigned elems, - const struct v4l2_subscribed_event_ops *ops) +.. code-block:: none + + int v4l2_event_subscribe(struct v4l2_fh *fh, + struct v4l2_event_subscription *sub, unsigned elems, + const struct v4l2_subscribed_event_ops *ops) The video_device->ioctl_ops->vidioc_subscribe_event must check the driver is able to produce events with specified event id. Then it calls @@ -1102,8 +1200,10 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, All 4 callbacks are optional, if you don't want to specify any callbacks the ops argument itself maybe NULL. -int v4l2_event_unsubscribe(struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) +.. code-block:: none + + int v4l2_event_unsubscribe(struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) vidioc_unsubscribe_event in struct v4l2_ioctl_ops. A driver may use v4l2_event_unsubscribe() directly unless it wants to be involved in @@ -1112,7 +1212,9 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, The special type V4L2_EVENT_ALL may be used to unsubscribe all events. The drivers may want to handle this in a special way. -int v4l2_event_pending(struct v4l2_fh *fh) +.. code-block:: none + + int v4l2_event_pending(struct v4l2_fh *fh) Returns the number of pending events. Useful when implementing poll. |