media: docs: kAPI docs: move them to driver-api
All those documents describe the media driver API. So, move them to the right place within the Kernel documentation. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
474
Documentation/driver-api/media/cec-core.rst
Normal file
474
Documentation/driver-api/media/cec-core.rst
Normal file
@@ -0,0 +1,474 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CEC Kernel Support
|
||||
==================
|
||||
|
||||
The CEC framework provides a unified kernel interface for use with HDMI CEC
|
||||
hardware. It is designed to handle a multiple types of hardware (receivers,
|
||||
transmitters, USB dongles). The framework also gives the option to decide
|
||||
what to do in the kernel driver and what should be handled by userspace
|
||||
applications. In addition it integrates the remote control passthrough
|
||||
feature into the kernel's remote control framework.
|
||||
|
||||
|
||||
The CEC Protocol
|
||||
----------------
|
||||
|
||||
The CEC protocol enables consumer electronic devices to communicate with each
|
||||
other through the HDMI connection. The protocol uses logical addresses in the
|
||||
communication. The logical address is strictly connected with the functionality
|
||||
provided by the device. The TV acting as the communication hub is always
|
||||
assigned address 0. The physical address is determined by the physical
|
||||
connection between devices.
|
||||
|
||||
The CEC framework described here is up to date with the CEC 2.0 specification.
|
||||
It is documented in the HDMI 1.4 specification with the new 2.0 bits documented
|
||||
in the HDMI 2.0 specification. But for most of the features the freely available
|
||||
HDMI 1.3a specification is sufficient:
|
||||
|
||||
http://www.microprocessor.org/HDMISpecification13a.pdf
|
||||
|
||||
|
||||
CEC Adapter Interface
|
||||
---------------------
|
||||
|
||||
The struct cec_adapter represents the CEC adapter hardware. It is created by
|
||||
calling cec_allocate_adapter() and deleted by calling cec_delete_adapter():
|
||||
|
||||
.. c:function::
|
||||
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv,
|
||||
const char *name, u32 caps, u8 available_las);
|
||||
|
||||
.. c:function::
|
||||
void cec_delete_adapter(struct cec_adapter *adap);
|
||||
|
||||
To create an adapter you need to pass the following information:
|
||||
|
||||
ops:
|
||||
adapter operations which are called by the CEC framework and that you
|
||||
have to implement.
|
||||
|
||||
priv:
|
||||
will be stored in adap->priv and can be used by the adapter ops.
|
||||
Use cec_get_drvdata(adap) to get the priv pointer.
|
||||
|
||||
name:
|
||||
the name of the CEC adapter. Note: this name will be copied.
|
||||
|
||||
caps:
|
||||
capabilities of the CEC adapter. These capabilities determine the
|
||||
capabilities of the hardware and which parts are to be handled
|
||||
by userspace and which parts are handled by kernelspace. The
|
||||
capabilities are returned by CEC_ADAP_G_CAPS.
|
||||
|
||||
available_las:
|
||||
the number of simultaneous logical addresses that this
|
||||
adapter can handle. Must be 1 <= available_las <= CEC_MAX_LOG_ADDRS.
|
||||
|
||||
To obtain the priv pointer use this helper function:
|
||||
|
||||
.. c:function::
|
||||
void *cec_get_drvdata(const struct cec_adapter *adap);
|
||||
|
||||
To register the /dev/cecX device node and the remote control device (if
|
||||
CEC_CAP_RC is set) you call:
|
||||
|
||||
.. c:function::
|
||||
int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
|
||||
|
||||
where parent is the parent device.
|
||||
|
||||
To unregister the devices call:
|
||||
|
||||
.. c:function::
|
||||
void cec_unregister_adapter(struct cec_adapter *adap);
|
||||
|
||||
Note: if cec_register_adapter() fails, then call cec_delete_adapter() to
|
||||
clean up. But if cec_register_adapter() succeeded, then only call
|
||||
cec_unregister_adapter() to clean up, never cec_delete_adapter(). The
|
||||
unregister function will delete the adapter automatically once the last user
|
||||
of that /dev/cecX device has closed its file handle.
|
||||
|
||||
|
||||
Implementing the Low-Level CEC Adapter
|
||||
--------------------------------------
|
||||
|
||||
The following low-level adapter operations have to be implemented in
|
||||
your driver:
|
||||
|
||||
.. c:type:: struct cec_adap_ops
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct cec_adap_ops
|
||||
{
|
||||
/* Low-level callbacks */
|
||||
int (*adap_enable)(struct cec_adapter *adap, bool enable);
|
||||
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
|
||||
int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
|
||||
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
|
||||
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
|
||||
u32 signal_free_time, struct cec_msg *msg);
|
||||
void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
|
||||
void (*adap_free)(struct cec_adapter *adap);
|
||||
|
||||
/* Error injection callbacks */
|
||||
...
|
||||
|
||||
/* High-level callbacks */
|
||||
...
|
||||
};
|
||||
|
||||
The seven low-level ops deal with various aspects of controlling the CEC adapter
|
||||
hardware:
|
||||
|
||||
|
||||
To enable/disable the hardware:
|
||||
|
||||
.. c:function::
|
||||
int (*adap_enable)(struct cec_adapter *adap, bool enable);
|
||||
|
||||
This callback enables or disables the CEC hardware. Enabling the CEC hardware
|
||||
means powering it up in a state where no logical addresses are claimed. This
|
||||
op assumes that the physical address (adap->phys_addr) is valid when enable is
|
||||
true and will not change while the CEC adapter remains enabled. The initial
|
||||
state of the CEC adapter after calling cec_allocate_adapter() is disabled.
|
||||
|
||||
Note that adap_enable must return 0 if enable is false.
|
||||
|
||||
|
||||
To enable/disable the 'monitor all' mode:
|
||||
|
||||
.. c:function::
|
||||
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
|
||||
|
||||
If enabled, then the adapter should be put in a mode to also monitor messages
|
||||
that not for us. Not all hardware supports this and this function is only
|
||||
called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
|
||||
(some hardware may always be in 'monitor all' mode).
|
||||
|
||||
Note that adap_monitor_all_enable must return 0 if enable is false.
|
||||
|
||||
|
||||
To enable/disable the 'monitor pin' mode:
|
||||
|
||||
.. c:function::
|
||||
int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
|
||||
|
||||
If enabled, then the adapter should be put in a mode to also monitor CEC pin
|
||||
changes. Not all hardware supports this and this function is only called if
|
||||
the CEC_CAP_MONITOR_PIN capability is set. This callback is optional
|
||||
(some hardware may always be in 'monitor pin' mode).
|
||||
|
||||
Note that adap_monitor_pin_enable must return 0 if enable is false.
|
||||
|
||||
|
||||
To program a new logical address:
|
||||
|
||||
.. c:function::
|
||||
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
|
||||
|
||||
If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses
|
||||
are to be erased. Otherwise the given logical address should be programmed.
|
||||
If the maximum number of available logical addresses is exceeded, then it
|
||||
should return -ENXIO. Once a logical address is programmed the CEC hardware
|
||||
can receive directed messages to that address.
|
||||
|
||||
Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID.
|
||||
|
||||
|
||||
To transmit a new message:
|
||||
|
||||
.. c:function::
|
||||
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
|
||||
u32 signal_free_time, struct cec_msg *msg);
|
||||
|
||||
This transmits a new message. The attempts argument is the suggested number of
|
||||
attempts for the transmit.
|
||||
|
||||
The signal_free_time is the number of data bit periods that the adapter should
|
||||
wait when the line is free before attempting to send a message. This value
|
||||
depends on whether this transmit is a retry, a message from a new initiator or
|
||||
a new message for the same initiator. Most hardware will handle this
|
||||
automatically, but in some cases this information is needed.
|
||||
|
||||
The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to
|
||||
microseconds (one data bit period is 2.4 ms).
|
||||
|
||||
|
||||
To log the current CEC hardware status:
|
||||
|
||||
.. c:function::
|
||||
void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
|
||||
|
||||
This optional callback can be used to show the status of the CEC hardware.
|
||||
The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status
|
||||
|
||||
To free any resources when the adapter is deleted:
|
||||
|
||||
.. c:function::
|
||||
void (*adap_free)(struct cec_adapter *adap);
|
||||
|
||||
This optional callback can be used to free any resources that might have been
|
||||
allocated by the driver. It's called from cec_delete_adapter.
|
||||
|
||||
|
||||
Your adapter driver will also have to react to events (typically interrupt
|
||||
driven) by calling into the framework in the following situations:
|
||||
|
||||
When a transmit finished (successfully or otherwise):
|
||||
|
||||
.. c:function::
|
||||
void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
|
||||
u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
|
||||
|
||||
or:
|
||||
|
||||
.. c:function::
|
||||
void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
|
||||
|
||||
The status can be one of:
|
||||
|
||||
CEC_TX_STATUS_OK:
|
||||
the transmit was successful.
|
||||
|
||||
CEC_TX_STATUS_ARB_LOST:
|
||||
arbitration was lost: another CEC initiator
|
||||
took control of the CEC line and you lost the arbitration.
|
||||
|
||||
CEC_TX_STATUS_NACK:
|
||||
the message was nacked (for a directed message) or
|
||||
acked (for a broadcast message). A retransmission is needed.
|
||||
|
||||
CEC_TX_STATUS_LOW_DRIVE:
|
||||
low drive was detected on the CEC bus. This indicates that
|
||||
a follower detected an error on the bus and requested a
|
||||
retransmission.
|
||||
|
||||
CEC_TX_STATUS_ERROR:
|
||||
some unspecified error occurred: this can be one of ARB_LOST
|
||||
or LOW_DRIVE if the hardware cannot differentiate or something
|
||||
else entirely. Some hardware only supports OK and FAIL as the
|
||||
result of a transmit, i.e. there is no way to differentiate
|
||||
between the different possible errors. In that case map FAIL
|
||||
to CEC_TX_STATUS_NACK and not to CEC_TX_STATUS_ERROR.
|
||||
|
||||
CEC_TX_STATUS_MAX_RETRIES:
|
||||
could not transmit the message after trying multiple times.
|
||||
Should only be set by the driver if it has hardware support for
|
||||
retrying messages. If set, then the framework assumes that it
|
||||
doesn't have to make another attempt to transmit the message
|
||||
since the hardware did that already.
|
||||
|
||||
The hardware must be able to differentiate between OK, NACK and 'something
|
||||
else'.
|
||||
|
||||
The \*_cnt arguments are the number of error conditions that were seen.
|
||||
This may be 0 if no information is available. Drivers that do not support
|
||||
hardware retry can just set the counter corresponding to the transmit error
|
||||
to 1, if the hardware does support retry then either set these counters to
|
||||
0 if the hardware provides no feedback of which errors occurred and how many
|
||||
times, or fill in the correct values as reported by the hardware.
|
||||
|
||||
Be aware that calling these functions can immediately start a new transmit
|
||||
if there is one pending in the queue. So make sure that the hardware is in
|
||||
a state where new transmits can be started *before* calling these functions.
|
||||
|
||||
The cec_transmit_attempt_done() function is a helper for cases where the
|
||||
hardware never retries, so the transmit is always for just a single
|
||||
attempt. It will call cec_transmit_done() in turn, filling in 1 for the
|
||||
count argument corresponding to the status. Or all 0 if the status was OK.
|
||||
|
||||
When a CEC message was received:
|
||||
|
||||
.. c:function::
|
||||
void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
|
||||
|
||||
Speaks for itself.
|
||||
|
||||
Implementing the interrupt handler
|
||||
----------------------------------
|
||||
|
||||
Typically the CEC hardware provides interrupts that signal when a transmit
|
||||
finished and whether it was successful or not, and it provides and interrupt
|
||||
when a CEC message was received.
|
||||
|
||||
The CEC driver should always process the transmit interrupts first before
|
||||
handling the receive interrupt. The framework expects to see the cec_transmit_done
|
||||
call before the cec_received_msg call, otherwise it can get confused if the
|
||||
received message was in reply to the transmitted message.
|
||||
|
||||
Optional: Implementing Error Injection Support
|
||||
----------------------------------------------
|
||||
|
||||
If the CEC adapter supports Error Injection functionality, then that can
|
||||
be exposed through the Error Injection callbacks:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct cec_adap_ops {
|
||||
/* Low-level callbacks */
|
||||
...
|
||||
|
||||
/* Error injection callbacks */
|
||||
int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
|
||||
bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
|
||||
|
||||
/* High-level CEC message callback */
|
||||
...
|
||||
};
|
||||
|
||||
If both callbacks are set, then an ``error-inj`` file will appear in debugfs.
|
||||
The basic syntax is as follows:
|
||||
|
||||
Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the
|
||||
line was reached, then the whole line is ignored. Otherwise a command is expected.
|
||||
|
||||
This basic parsing is done in the CEC Framework. It is up to the driver to decide
|
||||
what commands to implement. The only requirement is that the command ``clear`` without
|
||||
any arguments must be implemented and that it will remove all current error injection
|
||||
commands.
|
||||
|
||||
This ensures that you can always do ``echo clear >error-inj`` to clear any error
|
||||
injections without having to know the details of the driver-specific commands.
|
||||
|
||||
Note that the output of ``error-inj`` shall be valid as input to ``error-inj``.
|
||||
So this must work:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ cat error-inj >einj.txt
|
||||
$ cat einj.txt >error-inj
|
||||
|
||||
The first callback is called when this file is read and it should show the
|
||||
the current error injection state:
|
||||
|
||||
.. c:function::
|
||||
int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
|
||||
|
||||
It is recommended that it starts with a comment block with basic usage
|
||||
information. It returns 0 for success and an error otherwise.
|
||||
|
||||
The second callback will parse commands written to the ``error-inj`` file:
|
||||
|
||||
.. c:function::
|
||||
bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
|
||||
|
||||
The ``line`` argument points to the start of the command. Any leading
|
||||
spaces or tabs have already been skipped. It is a single line only (so there
|
||||
are no embedded newlines) and it is 0-terminated. The callback is free to
|
||||
modify the contents of the buffer. It is only called for lines containing a
|
||||
command, so this callback is never called for empty lines or comment lines.
|
||||
|
||||
Return true if the command was valid or false if there were syntax errors.
|
||||
|
||||
Implementing the High-Level CEC Adapter
|
||||
---------------------------------------
|
||||
|
||||
The low-level operations drive the hardware, the high-level operations are
|
||||
CEC protocol driven. The following high-level callbacks are available:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct cec_adap_ops {
|
||||
/* Low-level callbacks */
|
||||
...
|
||||
|
||||
/* Error injection callbacks */
|
||||
...
|
||||
|
||||
/* High-level CEC message callback */
|
||||
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
|
||||
};
|
||||
|
||||
The received() callback allows the driver to optionally handle a newly
|
||||
received CEC message
|
||||
|
||||
.. c:function::
|
||||
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
|
||||
|
||||
If the driver wants to process a CEC message, then it can implement this
|
||||
callback. If it doesn't want to handle this message, then it should return
|
||||
-ENOMSG, otherwise the CEC framework assumes it processed this message and
|
||||
it will not do anything with it.
|
||||
|
||||
|
||||
CEC framework functions
|
||||
-----------------------
|
||||
|
||||
CEC Adapter drivers can call the following CEC framework functions:
|
||||
|
||||
.. c:function::
|
||||
int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
|
||||
bool block);
|
||||
|
||||
Transmit a CEC message. If block is true, then wait until the message has been
|
||||
transmitted, otherwise just queue it and return.
|
||||
|
||||
.. c:function::
|
||||
void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
|
||||
bool block);
|
||||
|
||||
Change the physical address. This function will set adap->phys_addr and
|
||||
send an event if it has changed. If cec_s_log_addrs() has been called and
|
||||
the physical address has become valid, then the CEC framework will start
|
||||
claiming the logical addresses. If block is true, then this function won't
|
||||
return until this process has finished.
|
||||
|
||||
When the physical address is set to a valid value the CEC adapter will
|
||||
be enabled (see the adap_enable op). When it is set to CEC_PHYS_ADDR_INVALID,
|
||||
then the CEC adapter will be disabled. If you change a valid physical address
|
||||
to another valid physical address, then this function will first set the
|
||||
address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
|
||||
|
||||
.. c:function::
|
||||
void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
|
||||
const struct edid *edid);
|
||||
|
||||
A helper function that extracts the physical address from the edid struct
|
||||
and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
|
||||
if the EDID did not contain a physical address or edid was a NULL pointer.
|
||||
|
||||
.. c:function::
|
||||
int cec_s_log_addrs(struct cec_adapter *adap,
|
||||
struct cec_log_addrs *log_addrs, bool block);
|
||||
|
||||
Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS
|
||||
is set. If block is true, then wait until the logical addresses have been
|
||||
claimed, otherwise just queue it and return. To unconfigure all logical
|
||||
addresses call this function with log_addrs set to NULL or with
|
||||
log_addrs->num_log_addrs set to 0. The block argument is ignored when
|
||||
unconfiguring. This function will just return if the physical address is
|
||||
invalid. Once the physical address becomes valid, then the framework will
|
||||
attempt to claim these logical addresses.
|
||||
|
||||
CEC Pin framework
|
||||
-----------------
|
||||
|
||||
Most CEC hardware operates on full CEC messages where the software provides
|
||||
the message and the hardware handles the low-level CEC protocol. But some
|
||||
hardware only drives the CEC pin and software has to handle the low-level
|
||||
CEC protocol. The CEC pin framework was created to handle such devices.
|
||||
|
||||
Note that due to the close-to-realtime requirements it can never be guaranteed
|
||||
to work 100%. This framework uses highres timers internally, but if a
|
||||
timer goes off too late by more than 300 microseconds wrong results can
|
||||
occur. In reality it appears to be fairly reliable.
|
||||
|
||||
One advantage of this low-level implementation is that it can be used as
|
||||
a cheap CEC analyser, especially if interrupts can be used to detect
|
||||
CEC pin transitions from low to high or vice versa.
|
||||
|
||||
.. kernel-doc:: include/media/cec-pin.h
|
||||
|
||||
CEC Notifier framework
|
||||
----------------------
|
||||
|
||||
Most drm HDMI implementations have an integrated CEC implementation and no
|
||||
notifier support is needed. But some have independent CEC implementations
|
||||
that have their own driver. This could be an IP block for an SoC or a
|
||||
completely separate chip that deals with the CEC pin. For those cases a
|
||||
drm driver can install a notifier and use the notifier to inform the
|
||||
CEC driver about changes in the physical address.
|
||||
|
||||
.. kernel-doc:: include/media/cec-notifier.h
|
||||
85
Documentation/driver-api/media/csi2.rst
Normal file
85
Documentation/driver-api/media/csi2.rst
Normal file
@@ -0,0 +1,85 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
MIPI CSI-2
|
||||
==========
|
||||
|
||||
CSI-2 is a data bus intended for transferring images from cameras to
|
||||
the host SoC. It is defined by the `MIPI alliance`_.
|
||||
|
||||
.. _`MIPI alliance`: http://www.mipi.org/
|
||||
|
||||
Transmitter drivers
|
||||
-------------------
|
||||
|
||||
CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to
|
||||
provide the CSI-2 receiver with information on the CSI-2 bus
|
||||
configuration. These include the V4L2_CID_LINK_FREQ and
|
||||
V4L2_CID_PIXEL_RATE controls and
|
||||
(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These
|
||||
interface elements must be present on the sub-device represents the
|
||||
CSI-2 transmitter.
|
||||
|
||||
The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
|
||||
frequency (and not the symbol rate) of the link. The
|
||||
V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel
|
||||
rate the transmitter uses. The
|
||||
:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
|
||||
ability to start and stop the stream.
|
||||
|
||||
The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
|
||||
|
||||
pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
|
||||
|
||||
where
|
||||
|
||||
.. list-table:: variables in pixel rate calculation
|
||||
:header-rows: 1
|
||||
|
||||
* - variable or constant
|
||||
- description
|
||||
* - link_freq
|
||||
- The value of the V4L2_CID_LINK_FREQ integer64 menu item.
|
||||
* - nr_of_lanes
|
||||
- Number of data lanes used on the CSI-2 link. This can
|
||||
be obtained from the OF endpoint configuration.
|
||||
* - 2
|
||||
- Two bits are transferred per clock cycle per lane.
|
||||
* - bits_per_sample
|
||||
- Number of bits per sample.
|
||||
|
||||
The transmitter drivers must, if possible, configure the CSI-2
|
||||
transmitter to *LP-11 mode* whenever the transmitter is powered on but
|
||||
not active, and maintain *LP-11 mode* until stream on. Only at stream
|
||||
on should the transmitter activate the clock on the clock lane and
|
||||
transition to *HS mode*.
|
||||
|
||||
Some transmitters do this automatically but some have to be explicitly
|
||||
programmed to do so, and some are unable to do so altogether due to
|
||||
hardware constraints.
|
||||
|
||||
Stopping the transmitter
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A transmitter stops sending the stream of images as a result of
|
||||
calling the ``.s_stream()`` callback. Some transmitters may stop the
|
||||
stream at a frame boundary whereas others stop immediately,
|
||||
effectively leaving the current frame unfinished. The receiver driver
|
||||
should not make assumptions either way, but function properly in both
|
||||
cases.
|
||||
|
||||
Receiver drivers
|
||||
----------------
|
||||
|
||||
Before the receiver driver may enable the CSI-2 transmitter by using
|
||||
the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
|
||||
the transmitter up by using the
|
||||
:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
|
||||
place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
|
||||
directly.
|
||||
|
||||
Formats
|
||||
-------
|
||||
|
||||
The media bus pixel codes document parallel formats. Should the pixel data be
|
||||
transported over a serial bus, the media bus pixel code that describes a
|
||||
parallel format that transfers a sample on a single clock cycle is used.
|
||||
6
Documentation/driver-api/media/dtv-ca.rst
Normal file
6
Documentation/driver-api/media/dtv-ca.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV Conditional Access kABI
|
||||
----------------------------------
|
||||
|
||||
.. kernel-doc:: include/media/dvb_ca_en50221.h
|
||||
62
Documentation/driver-api/media/dtv-common.rst
Normal file
62
Documentation/driver-api/media/dtv-common.rst
Normal file
@@ -0,0 +1,62 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV Common functions
|
||||
---------------------------
|
||||
|
||||
Math functions
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Provide some commonly-used math functions, usually required in order to
|
||||
estimate signal strength and signal to noise measurements in dB.
|
||||
|
||||
.. kernel-doc:: include/media/dvb_math.h
|
||||
|
||||
|
||||
DVB devices
|
||||
~~~~~~~~~~~
|
||||
|
||||
Those functions are responsible for handling the DVB device nodes.
|
||||
|
||||
.. kernel-doc:: include/media/dvbdev.h
|
||||
|
||||
Digital TV Ring buffer
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Those routines implement ring buffers used to handle digital TV data and
|
||||
copy it from/to userspace.
|
||||
|
||||
.. note::
|
||||
|
||||
1) For performance reasons read and write routines don't check buffer sizes
|
||||
and/or number of bytes free/available. This has to be done before these
|
||||
routines are called. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/* write @buflen: bytes */
|
||||
free = dvb_ringbuffer_free(rbuf);
|
||||
if (free >= buflen)
|
||||
count = dvb_ringbuffer_write(rbuf, buffer, buflen);
|
||||
else
|
||||
/* do something */
|
||||
|
||||
/* read min. 1000, max. @bufsize: bytes */
|
||||
avail = dvb_ringbuffer_avail(rbuf);
|
||||
if (avail >= 1000)
|
||||
count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
|
||||
else
|
||||
/* do something */
|
||||
|
||||
2) If there is exactly one reader and one writer, there is no need
|
||||
to lock read or write operations.
|
||||
Two or more readers must be locked against each other.
|
||||
Flushing the buffer counts as a read operation.
|
||||
Resetting the buffer counts as a read and write operation.
|
||||
Two or more writers must be locked against each other.
|
||||
|
||||
.. kernel-doc:: include/media/dvb_ringbuffer.h
|
||||
|
||||
Digital TV VB2 handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/media/dvb_vb2.h
|
||||
39
Documentation/driver-api/media/dtv-core.rst
Normal file
39
Documentation/driver-api/media/dtv-core.rst
Normal file
@@ -0,0 +1,39 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV (DVB) devices
|
||||
------------------------
|
||||
|
||||
Digital TV devices are implemented by several different drivers:
|
||||
|
||||
- A bridge driver that is responsible to talk with the bus where the other
|
||||
devices are connected (PCI, USB, SPI), bind to the other drivers and
|
||||
implement the digital demux logic (either in software or in hardware);
|
||||
|
||||
- Frontend drivers that are usually implemented as two separate drivers:
|
||||
|
||||
- A tuner driver that implements the logic which commands the part of
|
||||
the hardware responsible for tuning into a digital TV transponder or
|
||||
physical channel. The output of a tuner is usually a baseband or
|
||||
Intermediate Frequency (IF) signal;
|
||||
|
||||
- A demodulator driver (a.k.a "demod") that implements the logic which
|
||||
commands the digital TV decoding hardware. The output of a demod is
|
||||
a digital stream, with multiple audio, video and data channels typically
|
||||
multiplexed using MPEG Transport Stream [#f1]_.
|
||||
|
||||
On most hardware, the frontend drivers talk with the bridge driver using an
|
||||
I2C bus.
|
||||
|
||||
.. [#f1] Some standards use TCP/IP for multiplexing data, like DVB-H (an
|
||||
abandoned standard, not used anymore) and ATSC version 3.0 current
|
||||
proposals. Currently, the DVB subsystem doesn't implement those standards.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
dtv-common
|
||||
dtv-frontend
|
||||
dtv-demux
|
||||
dtv-ca
|
||||
dtv-net
|
||||
84
Documentation/driver-api/media/dtv-demux.rst
Normal file
84
Documentation/driver-api/media/dtv-demux.rst
Normal file
@@ -0,0 +1,84 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV Demux kABI
|
||||
---------------------
|
||||
|
||||
Digital TV Demux
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The Kernel Digital TV Demux kABI defines a driver-internal interface for
|
||||
registering low-level, hardware specific driver to a hardware independent
|
||||
demux layer. It is only of interest for Digital TV device driver writers.
|
||||
The header file for this kABI is named ``demux.h`` and located in
|
||||
``include/media``.
|
||||
|
||||
The demux kABI should be implemented for each demux in the system. It is
|
||||
used to select the TS source of a demux and to manage the demux resources.
|
||||
When the demux client allocates a resource via the demux kABI, it receives
|
||||
a pointer to the kABI of that resource.
|
||||
|
||||
Each demux receives its TS input from a DVB front-end or from memory, as
|
||||
set via this demux kABI. In a system with more than one front-end, the kABI
|
||||
can be used to select one of the DVB front-ends as a TS source for a demux,
|
||||
unless this is fixed in the HW platform.
|
||||
|
||||
The demux kABI only controls front-ends regarding to their connections with
|
||||
demuxes; the kABI used to set the other front-end parameters, such as
|
||||
tuning, are devined via the Digital TV Frontend kABI.
|
||||
|
||||
The functions that implement the abstract interface demux should be defined
|
||||
static or module private and registered to the Demux core for external
|
||||
access. It is not necessary to implement every function in the struct
|
||||
:c:type:`dmx_demux`. For example, a demux interface might support Section filtering,
|
||||
but not PES filtering. The kABI client is expected to check the value of any
|
||||
function pointer before calling the function: the value of ``NULL`` means
|
||||
that the function is not available.
|
||||
|
||||
Whenever the functions of the demux API modify shared data, the
|
||||
possibilities of lost update and race condition problems should be
|
||||
addressed, e.g. by protecting parts of code with mutexes.
|
||||
|
||||
Note that functions called from a bottom half context must not sleep.
|
||||
Even a simple memory allocation without using ``GFP_ATOMIC`` can result in a
|
||||
kernel thread being put to sleep if swapping is needed. For example, the
|
||||
Linux Kernel calls the functions of a network device interface from a
|
||||
bottom half context. Thus, if a demux kABI function is called from network
|
||||
device code, the function must not sleep.
|
||||
|
||||
Demux Callback API
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This kernel-space API comprises the callback functions that deliver filtered
|
||||
data to the demux client. Unlike the other DVB kABIs, these functions are
|
||||
provided by the client and called from the demux code.
|
||||
|
||||
The function pointers of this abstract interface are not packed into a
|
||||
structure as in the other demux APIs, because the callback functions are
|
||||
registered and used independent of each other. As an example, it is possible
|
||||
for the API client to provide several callback functions for receiving TS
|
||||
packets and no callbacks for PES packets or sections.
|
||||
|
||||
The functions that implement the callback API need not be re-entrant: when
|
||||
a demux driver calls one of these functions, the driver is not allowed to
|
||||
call the function again before the original call returns. If a callback is
|
||||
triggered by a hardware interrupt, it is recommended to use the Linux
|
||||
bottom half mechanism or start a tasklet instead of making the callback
|
||||
function call directly from a hardware interrupt.
|
||||
|
||||
This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()`
|
||||
callbacks.
|
||||
|
||||
Digital TV Demux device registration functions and data structures
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/media/dmxdev.h
|
||||
|
||||
High-level Digital TV demux interface
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/media/dvb_demux.h
|
||||
|
||||
Driver-internal low-level hardware specific driver demux interface
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/media/demux.h
|
||||
445
Documentation/driver-api/media/dtv-frontend.rst
Normal file
445
Documentation/driver-api/media/dtv-frontend.rst
Normal file
@@ -0,0 +1,445 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV Frontend kABI
|
||||
------------------------
|
||||
|
||||
Digital TV Frontend
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Digital TV Frontend kABI defines a driver-internal interface for
|
||||
registering low-level, hardware specific driver to a hardware independent
|
||||
frontend layer. It is only of interest for Digital TV device driver writers.
|
||||
The header file for this API is named ``dvb_frontend.h`` and located in
|
||||
``include/media/``.
|
||||
|
||||
Demodulator driver
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The demodulator driver is responsible for talking with the decoding part of the
|
||||
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
|
||||
tells what type of digital TV standards are supported, and points to a
|
||||
series of functions that allow the DVB core to command the hardware via
|
||||
the code under ``include/media/dvb_frontend.c``.
|
||||
|
||||
A typical example of such struct in a driver ``foo`` is::
|
||||
|
||||
static struct dvb_frontend_ops foo_ops = {
|
||||
.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
|
||||
.info = {
|
||||
.name = "foo DVB-T/T2/C driver",
|
||||
.caps = FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_QAM_16 |
|
||||
FE_CAN_QAM_32 |
|
||||
FE_CAN_QAM_64 |
|
||||
FE_CAN_QAM_128 |
|
||||
FE_CAN_QAM_256 |
|
||||
FE_CAN_QAM_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_MUTE_TS |
|
||||
FE_CAN_2G_MODULATION,
|
||||
.frequency_min = 42000000, /* Hz */
|
||||
.frequency_max = 1002000000, /* Hz */
|
||||
.symbol_rate_min = 870000,
|
||||
.symbol_rate_max = 11700000
|
||||
},
|
||||
.init = foo_init,
|
||||
.sleep = foo_sleep,
|
||||
.release = foo_release,
|
||||
.set_frontend = foo_set_frontend,
|
||||
.get_frontend = foo_get_frontend,
|
||||
.read_status = foo_get_status_and_stats,
|
||||
.tune = foo_tune,
|
||||
.i2c_gate_ctrl = foo_i2c_gate_ctrl,
|
||||
.get_frontend_algo = foo_get_algo,
|
||||
};
|
||||
|
||||
A typical example of such struct in a driver ``bar`` meant to be used on
|
||||
Satellite TV reception is::
|
||||
|
||||
static const struct dvb_frontend_ops bar_ops = {
|
||||
.delsys = { SYS_DVBS, SYS_DVBS2 },
|
||||
.info = {
|
||||
.name = "Bar DVB-S/S2 demodulator",
|
||||
.frequency_min = 500000, /* KHz */
|
||||
.frequency_max = 2500000, /* KHz */
|
||||
.frequency_stepsize = 0,
|
||||
.symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 45000000,
|
||||
.symbol_rate_tolerance = 500,
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK,
|
||||
},
|
||||
.init = bar_init,
|
||||
.sleep = bar_sleep,
|
||||
.release = bar_release,
|
||||
.set_frontend = bar_set_frontend,
|
||||
.get_frontend = bar_get_frontend,
|
||||
.read_status = bar_get_status_and_stats,
|
||||
.i2c_gate_ctrl = bar_i2c_gate_ctrl,
|
||||
.get_frontend_algo = bar_get_algo,
|
||||
.tune = bar_tune,
|
||||
|
||||
/* Satellite-specific */
|
||||
.diseqc_send_master_cmd = bar_send_diseqc_msg,
|
||||
.diseqc_send_burst = bar_send_burst,
|
||||
.set_tone = bar_set_tone,
|
||||
.set_voltage = bar_set_voltage,
|
||||
};
|
||||
|
||||
.. note::
|
||||
|
||||
#) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
|
||||
frequencies are specified in kHz, while, for terrestrial and cable
|
||||
standards, they're specified in Hz. Due to that, if the same frontend
|
||||
supports both types, you'll need to have two separate
|
||||
:c:type:`dvb_frontend_ops` structures, one for each standard.
|
||||
#) The ``.i2c_gate_ctrl`` field is present only when the hardware has
|
||||
allows controlling an I2C gate (either directly of via some GPIO pin),
|
||||
in order to remove the tuner from the I2C bus after a channel is
|
||||
tuned.
|
||||
#) All new drivers should implement the
|
||||
:ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
|
||||
Yet, there are a number of callbacks meant to get statistics for
|
||||
signal strength, S/N and UCB. Those are there to provide backward
|
||||
compatibility with legacy applications that don't support the DVBv5
|
||||
API. Implementing those callbacks are optional. Those callbacks may be
|
||||
removed in the future, after we have all existing drivers supporting
|
||||
DVBv5 stats.
|
||||
#) Other callbacks are required for satellite TV standards, in order to
|
||||
control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
|
||||
``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
|
||||
|
||||
.. |delta| unicode:: U+00394
|
||||
|
||||
The ``include/media/dvb_frontend.c`` has a kernel thread which is
|
||||
responsible for tuning the device. It supports multiple algorithms to
|
||||
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
|
||||
|
||||
The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
|
||||
doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
|
||||
``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
|
||||
e. g. it will try first to use the specified center frequency ``f``,
|
||||
then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
|
||||
``f`` - 2 x |delta| and so on.
|
||||
|
||||
If the hardware has internally a some sort of zigzag algorithm, you should
|
||||
define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
|
||||
|
||||
.. note::
|
||||
|
||||
The core frontend support also supports
|
||||
a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
|
||||
define its own hardware-assisted algorithm. Very few hardware need to
|
||||
use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
|
||||
function callbacks at struct :c:type:`dvb_frontend_ops`.
|
||||
|
||||
Attaching frontend driver to the bridge driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before using the Digital TV frontend core, the bridge driver should attach
|
||||
the frontend demod, tuner and SEC devices and call
|
||||
:c:func:`dvb_register_frontend()`,
|
||||
in order to register the new frontend at the subsystem. At device
|
||||
detach/removal, the bridge driver should call
|
||||
:c:func:`dvb_unregister_frontend()` to
|
||||
remove the frontend from the core and then :c:func:`dvb_frontend_detach()`
|
||||
to free the memory allocated by the frontend drivers.
|
||||
|
||||
The drivers should also call :c:func:`dvb_frontend_suspend()` as part of
|
||||
their handler for the :c:type:`device_driver`.\ ``suspend()``, and
|
||||
:c:func:`dvb_frontend_resume()` as
|
||||
part of their handler for :c:type:`device_driver`.\ ``resume()``.
|
||||
|
||||
A few other optional functions are provided to handle some special cases.
|
||||
|
||||
.. _dvbv5_stats:
|
||||
|
||||
Digital TV Frontend statistics
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Introduction
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Digital TV frontends provide a range of
|
||||
:ref:`statistics <frontend-stat-properties>` meant to help tuning the device
|
||||
and measuring the quality of service.
|
||||
|
||||
For each statistics measurement, the driver should set the type of scale used,
|
||||
or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
|
||||
time. Drivers should also provide the number of statistics for each type.
|
||||
that's usually 1 for most video standards [#f2]_.
|
||||
|
||||
Drivers should initialize each statistic counters with length and
|
||||
scale at its init code. For example, if the frontend provides signal
|
||||
strength, it should have, on its init code::
|
||||
|
||||
struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
|
||||
|
||||
c->strength.len = 1;
|
||||
c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
|
||||
And, when the statistics got updated, set the scale::
|
||||
|
||||
c->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
c->strength.stat[0].uvalue = strength;
|
||||
|
||||
.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
|
||||
set of statistics. On such cases, len should be equal to 4. The first
|
||||
value corresponds to the global stat; the other ones to each layer, e. g.:
|
||||
|
||||
- c->cnr.stat[0] for global S/N carrier ratio,
|
||||
- c->cnr.stat[1] for Layer A S/N carrier ratio,
|
||||
- c->cnr.stat[2] for layer B S/N carrier ratio,
|
||||
- c->cnr.stat[3] for layer C S/N carrier ratio.
|
||||
|
||||
.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
|
||||
``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
|
||||
|
||||
Groups of statistics
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are several groups of statistics currently supported:
|
||||
|
||||
Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
|
||||
- Measures the signal strength level at the analog part of the tuner or
|
||||
demod.
|
||||
|
||||
- Typically obtained from the gain applied to the tuner and/or frontend
|
||||
in order to detect the carrier. When no carrier is detected, the gain is
|
||||
at the maximum value (so, strength is on its minimal).
|
||||
|
||||
- As the gain is visible through the set of registers that adjust the gain,
|
||||
typically, this statistics is always available [#f3]_.
|
||||
|
||||
- Drivers should try to make it available all the times, as these statistics
|
||||
can be used when adjusting an antenna position and to check for troubles
|
||||
at the cabling.
|
||||
|
||||
.. [#f3] On a few devices, the gain keeps floating if there is no carrier.
|
||||
On such devices, strength report should check first if carrier is
|
||||
detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
|
||||
and otherwise return the lowest possible value.
|
||||
|
||||
Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
|
||||
- Signal to Noise ratio for the main carrier.
|
||||
|
||||
- Signal to Noise measurement depends on the device. On some hardware, it is
|
||||
available when the main carrier is detected. On those hardware, CNR
|
||||
measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
|
||||
see :c:type:`fe_status`).
|
||||
|
||||
On other devices, it requires inner FEC decoding,
|
||||
as the frontend measures it indirectly from other parameters (e. g. after
|
||||
``FE_HAS_VITERBI``, see :c:type:`fe_status`).
|
||||
|
||||
Having it available after inner FEC is more common.
|
||||
|
||||
Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
|
||||
- Those counters measure the number of bits and bit errors errors after
|
||||
the forward error correction (FEC) on the inner coding block
|
||||
(after Viterbi, LDPC or other inner code).
|
||||
|
||||
- Due to its nature, those statistics depend on full coding lock
|
||||
(e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
|
||||
see :c:type:`fe_status`).
|
||||
|
||||
Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
|
||||
- Those counters measure the number of bits and bit errors errors before
|
||||
the forward error correction (FEC) on the inner coding block
|
||||
(before Viterbi, LDPC or other inner code).
|
||||
|
||||
- Not all frontends provide this kind of statistics.
|
||||
|
||||
- Due to its nature, those statistics depend on inner coding lock (e. g.
|
||||
after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
|
||||
|
||||
Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
|
||||
- Those counters measure the number of blocks and block errors errors after
|
||||
the forward error correction (FEC) on the inner coding block
|
||||
(before Viterbi, LDPC or other inner code).
|
||||
|
||||
- Due to its nature, those statistics depend on full coding lock
|
||||
(e. g. after ``FE_HAS_SYNC`` or after
|
||||
``FE_HAS_LOCK``, see :c:type:`fe_status`).
|
||||
|
||||
.. note:: All counters should be monotonically increased as they're
|
||||
collected from the hardware.
|
||||
|
||||
A typical example of the logic that handle status and statistics is::
|
||||
|
||||
static int foo_get_status_and_stats(struct dvb_frontend *fe)
|
||||
{
|
||||
struct foo_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
int rc;
|
||||
enum fe_status *status;
|
||||
|
||||
/* Both status and strength are always available */
|
||||
rc = foo_read_status(fe, &status);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = foo_read_strength(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Check if CNR is available */
|
||||
if (!(fe->status & FE_HAS_CARRIER))
|
||||
return 0;
|
||||
|
||||
rc = foo_read_cnr(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Check if pre-BER stats are available */
|
||||
if (!(fe->status & FE_HAS_VITERBI))
|
||||
return 0;
|
||||
|
||||
rc = foo_get_pre_ber(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Check if post-BER stats are available */
|
||||
if (!(fe->status & FE_HAS_SYNC))
|
||||
return 0;
|
||||
|
||||
rc = foo_get_post_ber(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct dvb_frontend_ops ops = {
|
||||
/* ... */
|
||||
.read_status = foo_get_status_and_stats,
|
||||
};
|
||||
|
||||
Statistics collection
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
On almost all frontend hardware, the bit and byte counts are stored by
|
||||
the hardware after a certain amount of time or after the total bit/block
|
||||
counter reaches a certain value (usually programmable), for example, on
|
||||
every 1000 ms or after receiving 1,000,000 bits.
|
||||
|
||||
So, if you read the registers too soon, you'll end by reading the same
|
||||
value as in the previous reading, causing the monotonic value to be
|
||||
incremented too often.
|
||||
|
||||
Drivers should take the responsibility to avoid too often reads. That
|
||||
can be done using two approaches:
|
||||
|
||||
if the driver have a bit that indicates when a collected data is ready
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Driver should check such bit before making the statistics available.
|
||||
|
||||
An example of such behavior can be found at this code snippet (adapted
|
||||
from mb86a20s driver's logic)::
|
||||
|
||||
static int foo_get_pre_ber(struct dvb_frontend *fe)
|
||||
{
|
||||
struct foo_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int rc, bit_error;
|
||||
|
||||
/* Check if the BER measures are already available */
|
||||
rc = foo_read_u8(state, 0x54);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (!rc)
|
||||
return 0;
|
||||
|
||||
/* Read Bit Error Count */
|
||||
bit_error = foo_read_u32(state, 0x55);
|
||||
if (bit_error < 0)
|
||||
return bit_error;
|
||||
|
||||
/* Read Total Bit Count */
|
||||
rc = foo_read_u32(state, 0x51);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_error.stat[0].uvalue += bit_error;
|
||||
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_count.stat[0].uvalue += rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
If the driver doesn't provide a statistics available check bit
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
A few devices, however, may not provide a way to check if the stats are
|
||||
available (or the way to check it is unknown). They may not even provide
|
||||
a way to directly read the total number of bits or blocks.
|
||||
|
||||
On those devices, the driver need to ensure that it won't be reading from
|
||||
the register too often and/or estimate the total number of bits/blocks.
|
||||
|
||||
On such drivers, a typical routine to get statistics would be like
|
||||
(adapted from dib8000 driver's logic)::
|
||||
|
||||
struct foo_state {
|
||||
/* ... */
|
||||
|
||||
unsigned long per_jiffies_stats;
|
||||
}
|
||||
|
||||
static int foo_get_pre_ber(struct dvb_frontend *fe)
|
||||
{
|
||||
struct foo_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int rc, bit_error;
|
||||
u64 bits;
|
||||
|
||||
/* Check if time for stats was elapsed */
|
||||
if (!time_after(jiffies, state->per_jiffies_stats))
|
||||
return 0;
|
||||
|
||||
/* Next stat should be collected in 1000 ms */
|
||||
state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
|
||||
|
||||
/* Read Bit Error Count */
|
||||
bit_error = foo_read_u32(state, 0x55);
|
||||
if (bit_error < 0)
|
||||
return bit_error;
|
||||
|
||||
/*
|
||||
* On this particular frontend, there's no register that
|
||||
* would provide the number of bits per 1000ms sample. So,
|
||||
* some function would calculate it based on DTV properties
|
||||
*/
|
||||
bits = get_number_of_bits_per_1000ms(fe);
|
||||
|
||||
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_error.stat[0].uvalue += bit_error;
|
||||
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_count.stat[0].uvalue += bits;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Please notice that, on both cases, we're getting the statistics using the
|
||||
:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
|
||||
the frontend core will automatically call this function periodically
|
||||
(usually, 3 times per second, when the frontend is locked).
|
||||
|
||||
That warrants that we won't miss to collect a counter and increment the
|
||||
monotonic stats at the right time.
|
||||
|
||||
Digital TV Frontend functions and types
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/media/dvb_frontend.h
|
||||
6
Documentation/driver-api/media/dtv-net.rst
Normal file
6
Documentation/driver-api/media/dtv-net.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Digital TV Network kABI
|
||||
-----------------------
|
||||
|
||||
.. kernel-doc:: include/media/dvb_net.h
|
||||
38
Documentation/driver-api/media/index.rst
Normal file
38
Documentation/driver-api/media/index.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
===================================
|
||||
Media subsystem kernel internal API
|
||||
===================================
|
||||
|
||||
**Copyright** |copy| 2009-2016 : LinuxTV Developers
|
||||
|
||||
This documentation is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
For more details see the file COPYING in the source distribution of Linux.
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 5
|
||||
:numbered:
|
||||
|
||||
v4l2-core
|
||||
dtv-core
|
||||
rc-core
|
||||
mc-core
|
||||
cec-core
|
||||
csi2
|
||||
309
Documentation/driver-api/media/mc-core.rst
Normal file
309
Documentation/driver-api/media/mc-core.rst
Normal file
@@ -0,0 +1,309 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Media Controller devices
|
||||
------------------------
|
||||
|
||||
Media Controller
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The media controller userspace API is documented in
|
||||
:ref:`the Media Controller uAPI book <media_controller>`. This document focus
|
||||
on the kernel-side implementation of the media framework.
|
||||
|
||||
Abstract media device model
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Discovering a device internal topology, and configuring it at runtime, is one
|
||||
of the goals of the media framework. To achieve this, hardware devices are
|
||||
modelled as an oriented graph of building blocks called entities connected
|
||||
through pads.
|
||||
|
||||
An entity is a basic media hardware building block. It can correspond to
|
||||
a large variety of logical blocks such as physical hardware devices
|
||||
(CMOS sensor for instance), logical hardware devices (a building block
|
||||
in a System-on-Chip image processing pipeline), DMA channels or physical
|
||||
connectors.
|
||||
|
||||
A pad is a connection endpoint through which an entity can interact with
|
||||
other entities. Data (not restricted to video) produced by an entity
|
||||
flows from the entity's output to one or more entity inputs. Pads should
|
||||
not be confused with physical pins at chip boundaries.
|
||||
|
||||
A link is a point-to-point oriented connection between two pads, either
|
||||
on the same entity or on different entities. Data flows from a source
|
||||
pad to a sink pad.
|
||||
|
||||
Media device
|
||||
^^^^^^^^^^^^
|
||||
|
||||
A media device is represented by a struct :c:type:`media_device`
|
||||
instance, defined in ``include/media/media-device.h``.
|
||||
Allocation of the structure is handled by the media device driver, usually by
|
||||
embedding the :c:type:`media_device` instance in a larger driver-specific
|
||||
structure.
|
||||
|
||||
Drivers register media device instances by calling
|
||||
:c:func:`__media_device_register()` via the macro ``media_device_register()``
|
||||
and unregistered by calling :c:func:`media_device_unregister()`.
|
||||
|
||||
Entities
|
||||
^^^^^^^^
|
||||
|
||||
Entities are represented by a struct :c:type:`media_entity`
|
||||
instance, defined in ``include/media/media-entity.h``. The structure is usually
|
||||
embedded into a higher-level structure, such as
|
||||
:c:type:`v4l2_subdev` or :c:type:`video_device`
|
||||
instances, although drivers can allocate entities directly.
|
||||
|
||||
Drivers initialize entity pads by calling
|
||||
:c:func:`media_entity_pads_init()`.
|
||||
|
||||
Drivers register entities with a media device by calling
|
||||
:c:func:`media_device_register_entity()`
|
||||
and unregistered by calling
|
||||
:c:func:`media_device_unregister_entity()`.
|
||||
|
||||
Interfaces
|
||||
^^^^^^^^^^
|
||||
|
||||
Interfaces are represented by a
|
||||
struct :c:type:`media_interface` instance, defined in
|
||||
``include/media/media-entity.h``. Currently, only one type of interface is
|
||||
defined: a device node. Such interfaces are represented by a
|
||||
struct :c:type:`media_intf_devnode`.
|
||||
|
||||
Drivers initialize and create device node interfaces by calling
|
||||
:c:func:`media_devnode_create()`
|
||||
and remove them by calling:
|
||||
:c:func:`media_devnode_remove()`.
|
||||
|
||||
Pads
|
||||
^^^^
|
||||
Pads are represented by a struct :c:type:`media_pad` instance,
|
||||
defined in ``include/media/media-entity.h``. Each entity stores its pads in
|
||||
a pads array managed by the entity driver. Drivers usually embed the array in
|
||||
a driver-specific structure.
|
||||
|
||||
Pads are identified by their entity and their 0-based index in the pads
|
||||
array.
|
||||
|
||||
Both information are stored in the struct :c:type:`media_pad`,
|
||||
making the struct :c:type:`media_pad` pointer the canonical way
|
||||
to store and pass link references.
|
||||
|
||||
Pads have flags that describe the pad capabilities and state.
|
||||
|
||||
``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
|
||||
``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
|
||||
|
||||
.. note::
|
||||
|
||||
One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
|
||||
be set for each pad.
|
||||
|
||||
Links
|
||||
^^^^^
|
||||
|
||||
Links are represented by a struct :c:type:`media_link` instance,
|
||||
defined in ``include/media/media-entity.h``. There are two types of links:
|
||||
|
||||
**1. pad to pad links**:
|
||||
|
||||
Associate two entities via their PADs. Each entity has a list that points
|
||||
to all links originating at or targeting any of its pads.
|
||||
A given link is thus stored twice, once in the source entity and once in
|
||||
the target entity.
|
||||
|
||||
Drivers create pad to pad links by calling:
|
||||
:c:func:`media_create_pad_link()` and remove with
|
||||
:c:func:`media_entity_remove_links()`.
|
||||
|
||||
**2. interface to entity links**:
|
||||
|
||||
Associate one interface to a Link.
|
||||
|
||||
Drivers create interface to entity links by calling:
|
||||
:c:func:`media_create_intf_link()` and remove with
|
||||
:c:func:`media_remove_intf_links()`.
|
||||
|
||||
.. note::
|
||||
|
||||
Links can only be created after having both ends already created.
|
||||
|
||||
Links have flags that describe the link capabilities and state. The
|
||||
valid values are described at :c:func:`media_create_pad_link()` and
|
||||
:c:func:`media_create_intf_link()`.
|
||||
|
||||
Graph traversal
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The media framework provides APIs to iterate over entities in a graph.
|
||||
|
||||
To iterate over all entities belonging to a media device, drivers can use
|
||||
the media_device_for_each_entity macro, defined in
|
||||
``include/media/media-device.h``.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct media_entity *entity;
|
||||
|
||||
media_device_for_each_entity(entity, mdev) {
|
||||
// entity will point to each entity in turn
|
||||
...
|
||||
}
|
||||
|
||||
Drivers might also need to iterate over all entities in a graph that can be
|
||||
reached only through enabled links starting at a given entity. The media
|
||||
framework provides a depth-first graph traversal API for that purpose.
|
||||
|
||||
.. note::
|
||||
|
||||
Graphs with cycles (whether directed or undirected) are **NOT**
|
||||
supported by the graph traversal API. To prevent infinite loops, the graph
|
||||
traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
|
||||
currently defined as 16.
|
||||
|
||||
Drivers initiate a graph traversal by calling
|
||||
:c:func:`media_graph_walk_start()`
|
||||
|
||||
The graph structure, provided by the caller, is initialized to start graph
|
||||
traversal at the given entity.
|
||||
|
||||
Drivers can then retrieve the next entity by calling
|
||||
:c:func:`media_graph_walk_next()`
|
||||
|
||||
When the graph traversal is complete the function will return ``NULL``.
|
||||
|
||||
Graph traversal can be interrupted at any moment. No cleanup function call
|
||||
is required and the graph structure can be freed normally.
|
||||
|
||||
Helper functions can be used to find a link between two given pads, or a pad
|
||||
connected to another pad through an enabled link
|
||||
:c:func:`media_entity_find_link()` and
|
||||
:c:func:`media_entity_remote_pad()`.
|
||||
|
||||
Use count and power handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Due to the wide differences between drivers regarding power management
|
||||
needs, the media controller does not implement power management. However,
|
||||
the struct :c:type:`media_entity` includes a ``use_count``
|
||||
field that media drivers
|
||||
can use to track the number of users of every entity for power management
|
||||
needs.
|
||||
|
||||
The :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
|
||||
media drivers and must not be
|
||||
touched by entity drivers. Access to the field must be protected by the
|
||||
:c:type:`media_device`.\ ``graph_mutex`` lock.
|
||||
|
||||
Links setup
|
||||
^^^^^^^^^^^
|
||||
|
||||
Link properties can be modified at runtime by calling
|
||||
:c:func:`media_entity_setup_link()`.
|
||||
|
||||
Pipelines and media streams
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When starting streaming, drivers must notify all entities in the pipeline to
|
||||
prevent link states from being modified during streaming by calling
|
||||
:c:func:`media_pipeline_start()`.
|
||||
|
||||
The function will mark all entities connected to the given entity through
|
||||
enabled links, either directly or indirectly, as streaming.
|
||||
|
||||
The struct :c:type:`media_pipeline` instance pointed to by
|
||||
the pipe argument will be stored in every entity in the pipeline.
|
||||
Drivers should embed the struct :c:type:`media_pipeline`
|
||||
in higher-level pipeline structures and can then access the
|
||||
pipeline through the struct :c:type:`media_entity`
|
||||
pipe field.
|
||||
|
||||
Calls to :c:func:`media_pipeline_start()` can be nested.
|
||||
The pipeline pointer must be identical for all nested calls to the function.
|
||||
|
||||
:c:func:`media_pipeline_start()` may return an error. In that case,
|
||||
it will clean up any of the changes it did by itself.
|
||||
|
||||
When stopping the stream, drivers must notify the entities with
|
||||
:c:func:`media_pipeline_stop()`.
|
||||
|
||||
If multiple calls to :c:func:`media_pipeline_start()` have been
|
||||
made the same number of :c:func:`media_pipeline_stop()` calls
|
||||
are required to stop streaming.
|
||||
The :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
|
||||
nested stop call.
|
||||
|
||||
Link configuration will fail with ``-EBUSY`` by default if either end of the
|
||||
link is a streaming entity. Links that can be modified while streaming must
|
||||
be marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
|
||||
|
||||
If other operations need to be disallowed on streaming entities (such as
|
||||
changing entities configuration parameters) drivers can explicitly check the
|
||||
media_entity stream_count field to find out if an entity is streaming. This
|
||||
operation must be done with the media_device graph_mutex held.
|
||||
|
||||
Link validation
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Link validation is performed by :c:func:`media_pipeline_start()`
|
||||
for any entity which has sink pads in the pipeline. The
|
||||
:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
|
||||
purpose. In ``link_validate()`` callback, entity driver should check
|
||||
that the properties of the source pad of the connected entity and its own
|
||||
sink pad match. It is up to the type of the entity (and in the end, the
|
||||
properties of the hardware) what matching actually means.
|
||||
|
||||
Subsystems should facilitate link validation by providing subsystem specific
|
||||
helper functions to provide easy access for commonly needed information, and
|
||||
in the end provide a way to use driver-specific callbacks.
|
||||
|
||||
Media Controller Device Allocator API
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When the media device belongs to more than one driver, the shared media
|
||||
device is allocated with the shared struct device as the key for look ups.
|
||||
|
||||
The shared media device should stay in registered state until the last
|
||||
driver unregisters it. In addition, the media device should be released when
|
||||
all the references are released. Each driver gets a reference to the media
|
||||
device during probe, when it allocates the media device. If media device is
|
||||
already allocated, the allocate API bumps up the refcount and returns the
|
||||
existing media device. The driver puts the reference back in its disconnect
|
||||
routine when it calls :c:func:`media_device_delete()`.
|
||||
|
||||
The media device is unregistered and cleaned up from the kref put handler to
|
||||
ensure that the media device stays in registered state until the last driver
|
||||
unregisters the media device.
|
||||
|
||||
**Driver Usage**
|
||||
|
||||
Drivers should use the appropriate media-core routines to manage the shared
|
||||
media device life-time handling the two states:
|
||||
1. allocate -> register -> delete
|
||||
2. get reference to already registered device -> delete
|
||||
|
||||
call :c:func:`media_device_delete()` routine to make sure the shared media
|
||||
device delete is handled correctly.
|
||||
|
||||
**driver probe:**
|
||||
Call :c:func:`media_device_usb_allocate()` to allocate or get a reference
|
||||
Call :c:func:`media_device_register()`, if media devnode isn't registered
|
||||
|
||||
**driver disconnect:**
|
||||
Call :c:func:`media_device_delete()` to free the media_device. Freeing is
|
||||
handled by the kref put handler.
|
||||
|
||||
API Definitions
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/media-device.h
|
||||
|
||||
.. kernel-doc:: include/media/media-devnode.h
|
||||
|
||||
.. kernel-doc:: include/media/media-entity.h
|
||||
|
||||
.. kernel-doc:: include/media/media-request.h
|
||||
|
||||
.. kernel-doc:: include/media/media-dev-allocator.h
|
||||
88
Documentation/driver-api/media/rc-core.rst
Normal file
88
Documentation/driver-api/media/rc-core.rst
Normal file
@@ -0,0 +1,88 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Remote Controller devices
|
||||
-------------------------
|
||||
|
||||
Remote Controller core
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The remote controller core implements infrastructure to receive and send
|
||||
remote controller keyboard keystrokes and mouse events.
|
||||
|
||||
Every time a key is pressed on a remote controller, a scan code is produced.
|
||||
Also, on most hardware, keeping a key pressed for more than a few dozens of
|
||||
milliseconds produce a repeat key event. That's somewhat similar to what
|
||||
a normal keyboard or mouse is handled internally on Linux\ [#f1]_. So, the
|
||||
remote controller core is implemented on the top of the linux input/evdev
|
||||
interface.
|
||||
|
||||
.. [#f1]
|
||||
|
||||
The main difference is that, on keyboard events, the keyboard controller
|
||||
produces one event for a key press and another one for key release. On
|
||||
infrared-based remote controllers, there's no key release event. Instead,
|
||||
an extra code is produced to indicate key repeats.
|
||||
|
||||
However, most of the remote controllers use infrared (IR) to transmit signals.
|
||||
As there are several protocols used to modulate infrared signals, one
|
||||
important part of the core is dedicated to adjust the driver and the core
|
||||
system to support the infrared protocol used by the emitter.
|
||||
|
||||
The infrared transmission is done by blinking a infrared emitter using a
|
||||
carrier. The carrier can be switched on or off by the IR transmitter
|
||||
hardware. When the carrier is switched on, it is called *PULSE*.
|
||||
When the carrier is switched off, it is called *SPACE*.
|
||||
|
||||
In other words, a typical IR transmission can be viewed as a sequence of
|
||||
*PULSE* and *SPACE* events, each with a given duration.
|
||||
|
||||
The carrier parameters (frequency, duty cycle) and the intervals for
|
||||
*PULSE* and *SPACE* events depend on the protocol.
|
||||
For example, the NEC protocol uses a carrier of 38kHz, and transmissions
|
||||
start with a 9ms *PULSE* and a 4.5ms SPACE. It then transmits 16 bits of
|
||||
scan code, being 8 bits for address (usually it is a fixed number for a
|
||||
given remote controller), followed by 8 bits of code. A bit "1" is modulated
|
||||
with 560µs *PULSE* followed by 1690µs *SPACE* and a bit "0" is modulated
|
||||
with 560µs *PULSE* followed by 560µs *SPACE*.
|
||||
|
||||
At receiver, a simple low-pass filter can be used to convert the received
|
||||
signal in a sequence of *PULSE/SPACE* events, filtering out the carrier
|
||||
frequency. Due to that, the receiver doesn't care about the carrier's
|
||||
actual frequency parameters: all it has to do is to measure the amount
|
||||
of time it receives *PULSE/SPACE* events.
|
||||
So, a simple IR receiver hardware will just provide a sequence of timings
|
||||
for those events to the Kernel. The drivers for hardware with such kind of
|
||||
receivers are identified by ``RC_DRIVER_IR_RAW``, as defined by
|
||||
:c:type:`rc_driver_type`\ [#f2]_. Other hardware come with a
|
||||
microcontroller that decode the *PULSE/SPACE* sequence and return scan
|
||||
codes to the Kernel. Such kind of receivers are identified
|
||||
by ``RC_DRIVER_SCANCODE``.
|
||||
|
||||
.. [#f2]
|
||||
|
||||
The RC core also supports devices that have just IR emitters,
|
||||
without any receivers. Right now, all such devices work only in
|
||||
raw TX mode. Such kind of hardware is identified as
|
||||
``RC_DRIVER_IR_RAW_TX``.
|
||||
|
||||
When the RC core receives events produced by ``RC_DRIVER_IR_RAW`` IR
|
||||
receivers, it needs to decode the IR protocol, in order to obtain the
|
||||
corresponding scan code. The protocols supported by the RC core are
|
||||
defined at enum :c:type:`rc_proto`.
|
||||
|
||||
When the RC code receives a scan code (either directly, by a driver
|
||||
of the type ``RC_DRIVER_SCANCODE``, or via its IR decoders), it needs
|
||||
to convert into a Linux input event code. This is done via a mapping
|
||||
table.
|
||||
|
||||
The Kernel has support for mapping tables available on most media
|
||||
devices. It also supports loading a table in runtime, via some
|
||||
sysfs nodes. See the :ref:`RC userspace API <Remote_controllers_Intro>`
|
||||
for more details.
|
||||
|
||||
Remote controller data structures and functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/rc-core.h
|
||||
|
||||
.. kernel-doc:: include/media/rc-map.h
|
||||
5
Documentation/driver-api/media/v4l2-async.rst
Normal file
5
Documentation/driver-api/media/v4l2-async.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 async kAPI
|
||||
^^^^^^^^^^^^^^^
|
||||
.. kernel-doc:: include/media/v4l2-async.h
|
||||
31
Documentation/driver-api/media/v4l2-clocks.rst
Normal file
31
Documentation/driver-api/media/v4l2-clocks.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 clocks
|
||||
-----------
|
||||
|
||||
.. attention::
|
||||
|
||||
This is a temporary API and it shall be replaced by the generic
|
||||
clock API, when the latter becomes widely available.
|
||||
|
||||
Many subdevices, like camera sensors, TV decoders and encoders, need a clock
|
||||
signal to be supplied by the system. Often this clock is supplied by the
|
||||
respective bridge device. The Linux kernel provides a Common Clock Framework for
|
||||
this purpose. However, it is not (yet) available on all architectures. Besides,
|
||||
the nature of the multi-functional (clock, data + synchronisation, I2C control)
|
||||
connection of subdevices to the system might impose special requirements on the
|
||||
clock API usage. E.g. V4L2 has to support clock provider driver unregistration
|
||||
while a subdevice driver is holding a reference to the clock. For these reasons
|
||||
a V4L2 clock helper API has been developed and is provided to bridge and
|
||||
subdevice drivers.
|
||||
|
||||
The API consists of two parts: two functions to register and unregister a V4L2
|
||||
clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
|
||||
a clock object, similar to the respective generic clock API calls:
|
||||
v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
|
||||
v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
|
||||
clock operations that will be called when clock users invoke respective API
|
||||
methods.
|
||||
|
||||
It is expected that once the CCF becomes available on all relevant
|
||||
architectures this API will be removed.
|
||||
8
Documentation/driver-api/media/v4l2-common.rst
Normal file
8
Documentation/driver-api/media/v4l2-common.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 common functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-common.h
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-ioctl.h
|
||||
823
Documentation/driver-api/media/v4l2-controls.rst
Normal file
823
Documentation/driver-api/media/v4l2-controls.rst
Normal file
@@ -0,0 +1,823 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 Controls
|
||||
=============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The V4L2 control API seems simple enough, but quickly becomes very hard to
|
||||
implement correctly in drivers. But much of the code needed to handle controls
|
||||
is actually not driver specific and can be moved to the V4L core framework.
|
||||
|
||||
After all, the only part that a driver developer is interested in is:
|
||||
|
||||
1) How do I add a control?
|
||||
2) How do I set the control's value? (i.e. s_ctrl)
|
||||
|
||||
And occasionally:
|
||||
|
||||
3) How do I get the control's value? (i.e. g_volatile_ctrl)
|
||||
4) How do I validate the user's proposed control value? (i.e. try_ctrl)
|
||||
|
||||
All the rest is something that can be done centrally.
|
||||
|
||||
The control framework was created in order to implement all the rules of the
|
||||
V4L2 specification with respect to controls in a central place. And to make
|
||||
life as easy as possible for the driver developer.
|
||||
|
||||
Note that the control framework relies on the presence of a struct
|
||||
:c:type:`v4l2_device` for V4L2 drivers and struct :c:type:`v4l2_subdev` for
|
||||
sub-device drivers.
|
||||
|
||||
|
||||
Objects in the framework
|
||||
------------------------
|
||||
|
||||
There are two main objects:
|
||||
|
||||
The :c:type:`v4l2_ctrl` object describes the control properties and keeps
|
||||
track of the control's value (both the current value and the proposed new
|
||||
value).
|
||||
|
||||
:c:type:`v4l2_ctrl_handler` is the object that keeps track of controls. It
|
||||
maintains a list of v4l2_ctrl objects that it owns and another list of
|
||||
references to controls, possibly to controls owned by other handlers.
|
||||
|
||||
|
||||
Basic usage for V4L2 and sub-device drivers
|
||||
-------------------------------------------
|
||||
|
||||
1) Prepare the driver:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
||||
1.1) Add the handler to your driver's top-level struct:
|
||||
|
||||
For V4L2 drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct foo_dev {
|
||||
...
|
||||
struct v4l2_device v4l2_dev;
|
||||
...
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
...
|
||||
};
|
||||
|
||||
For sub-device drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct foo_dev {
|
||||
...
|
||||
struct v4l2_subdev sd;
|
||||
...
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
...
|
||||
};
|
||||
|
||||
1.2) Initialize the handler:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
|
||||
|
||||
The second argument is a hint telling the function how many controls this
|
||||
handler is expected to handle. It will allocate a hashtable based on this
|
||||
information. It is a hint only.
|
||||
|
||||
1.3) Hook the control handler into the driver:
|
||||
|
||||
For V4L2 drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
|
||||
|
||||
For sub-device drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
foo->sd.ctrl_handler = &foo->ctrl_handler;
|
||||
|
||||
1.4) Clean up the handler at the end:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_free(&foo->ctrl_handler);
|
||||
|
||||
|
||||
2) Add controls:
|
||||
|
||||
You add non-menu controls by calling :c:func:`v4l2_ctrl_new_std`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 min, s32 max, u32 step, s32 def);
|
||||
|
||||
Menu and integer menu controls are added by calling
|
||||
:c:func:`v4l2_ctrl_new_std_menu`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 skip_mask, s32 def);
|
||||
|
||||
Menu controls with a driver specific menu are added by calling
|
||||
:c:func:`v4l2_ctrl_new_std_menu_items`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
|
||||
struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
|
||||
s32 skip_mask, s32 def, const char * const *qmenu);
|
||||
|
||||
Standard compound controls can be added by calling
|
||||
:c:func:`v4l2_ctrl_new_std_compound`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops, u32 id,
|
||||
const union v4l2_ctrl_ptr p_def);
|
||||
|
||||
Integer menu controls with a driver specific menu can be added by calling
|
||||
:c:func:`v4l2_ctrl_new_int_menu`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 def, const s64 *qmenu_int);
|
||||
|
||||
These functions are typically called right after the
|
||||
:c:func:`v4l2_ctrl_handler_init`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const s64 exp_bias_qmenu[] = {
|
||||
-2, -1, 0, 1, 2
|
||||
};
|
||||
static const char * const test_pattern[] = {
|
||||
"Disabled",
|
||||
"Vertical Bars",
|
||||
"Solid Black",
|
||||
"Solid White",
|
||||
};
|
||||
|
||||
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
|
||||
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
|
||||
v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_CONTRAST, 0, 255, 1, 128);
|
||||
v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
|
||||
v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE_BIAS,
|
||||
ARRAY_SIZE(exp_bias_qmenu) - 1,
|
||||
ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
|
||||
exp_bias_qmenu);
|
||||
v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
|
||||
V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
|
||||
0, test_pattern);
|
||||
...
|
||||
if (foo->ctrl_handler.error) {
|
||||
int err = foo->ctrl_handler.error;
|
||||
|
||||
v4l2_ctrl_handler_free(&foo->ctrl_handler);
|
||||
return err;
|
||||
}
|
||||
|
||||
The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
|
||||
the new control, but if you do not need to access the pointer outside the
|
||||
control ops, then there is no need to store it.
|
||||
|
||||
The :c:func:`v4l2_ctrl_new_std` function will fill in most fields based on
|
||||
the control ID except for the min, max, step and default values. These are
|
||||
passed in the last four arguments. These values are driver specific while
|
||||
control attributes like type, name, flags are all global. The control's
|
||||
current value will be set to the default value.
|
||||
|
||||
The :c:func:`v4l2_ctrl_new_std_menu` function is very similar but it is
|
||||
used for menu controls. There is no min argument since that is always 0 for
|
||||
menu controls, and instead of a step there is a skip_mask argument: if bit
|
||||
X is 1, then menu item X is skipped.
|
||||
|
||||
The :c:func:`v4l2_ctrl_new_int_menu` function creates a new standard
|
||||
integer menu control with driver-specific items in the menu. It differs
|
||||
from v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and
|
||||
takes as the last argument an array of signed 64-bit integers that form an
|
||||
exact menu item list.
|
||||
|
||||
The :c:func:`v4l2_ctrl_new_std_menu_items` function is very similar to
|
||||
v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the
|
||||
driver specific menu for an otherwise standard menu control. A good example
|
||||
for this control is the test pattern control for capture/display/sensors
|
||||
devices that have the capability to generate test patterns. These test
|
||||
patterns are hardware specific, so the contents of the menu will vary from
|
||||
device to device.
|
||||
|
||||
Note that if something fails, the function will return NULL or an error and
|
||||
set ctrl_handler->error to the error code. If ctrl_handler->error was already
|
||||
set, then it will just return and do nothing. This is also true for
|
||||
v4l2_ctrl_handler_init if it cannot allocate the internal data structure.
|
||||
|
||||
This makes it easy to init the handler and just add all controls and only check
|
||||
the error code at the end. Saves a lot of repetitive error checking.
|
||||
|
||||
It is recommended to add controls in ascending control ID order: it will be
|
||||
a bit faster that way.
|
||||
|
||||
3) Optionally force initial control setup:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_setup(&foo->ctrl_handler);
|
||||
|
||||
This will call s_ctrl for all controls unconditionally. Effectively this
|
||||
initializes the hardware to the default control values. It is recommended
|
||||
that you do this as this ensures that both the internal data structures and
|
||||
the hardware are in sync.
|
||||
|
||||
4) Finally: implement the :c:type:`v4l2_ctrl_ops`
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_ops foo_ctrl_ops = {
|
||||
.s_ctrl = foo_s_ctrl,
|
||||
};
|
||||
|
||||
Usually all you need is s_ctrl:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
write_reg(0x123, ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_CONTRAST:
|
||||
write_reg(0x456, ctrl->val);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
The control ops are called with the v4l2_ctrl pointer as argument.
|
||||
The new control value has already been validated, so all you need to do is
|
||||
to actually update the hardware registers.
|
||||
|
||||
You're done! And this is sufficient for most of the drivers we have. No need
|
||||
to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
|
||||
and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
The remainder sections deal with more advanced controls topics and scenarios.
|
||||
In practice the basic usage as described above is sufficient for most drivers.
|
||||
|
||||
|
||||
Inheriting Sub-device Controls
|
||||
------------------------------
|
||||
|
||||
When a sub-device is registered with a V4L2 driver by calling
|
||||
v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev
|
||||
and v4l2_device are set, then the controls of the subdev will become
|
||||
automatically available in the V4L2 driver as well. If the subdev driver
|
||||
contains controls that already exist in the V4L2 driver, then those will be
|
||||
skipped (so a V4L2 driver can always override a subdev control).
|
||||
|
||||
What happens here is that v4l2_device_register_subdev() calls
|
||||
v4l2_ctrl_add_handler() adding the controls of the subdev to the controls
|
||||
of v4l2_device.
|
||||
|
||||
|
||||
Accessing Control Values
|
||||
------------------------
|
||||
|
||||
The following union is used inside the control framework to access control
|
||||
values:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
union v4l2_ctrl_ptr {
|
||||
s32 *p_s32;
|
||||
s64 *p_s64;
|
||||
char *p_char;
|
||||
void *p;
|
||||
};
|
||||
|
||||
The v4l2_ctrl struct contains these fields that can be used to access both
|
||||
current and new values:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
s32 val;
|
||||
struct {
|
||||
s32 val;
|
||||
} cur;
|
||||
|
||||
|
||||
union v4l2_ctrl_ptr p_new;
|
||||
union v4l2_ctrl_ptr p_cur;
|
||||
|
||||
If the control has a simple s32 type type, then:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
&ctrl->val == ctrl->p_new.p_s32
|
||||
&ctrl->cur.val == ctrl->p_cur.p_s32
|
||||
|
||||
For all other types use ctrl->p_cur.p<something>. Basically the val
|
||||
and cur.val fields can be considered an alias since these are used so often.
|
||||
|
||||
Within the control ops you can freely use these. The val and cur.val speak for
|
||||
themselves. The p_char pointers point to character buffers of length
|
||||
ctrl->maximum + 1, and are always 0-terminated.
|
||||
|
||||
Unless the control is marked volatile the p_cur field points to the the
|
||||
current cached control value. When you create a new control this value is made
|
||||
identical to the default value. After calling v4l2_ctrl_handler_setup() this
|
||||
value is passed to the hardware. It is generally a good idea to call this
|
||||
function.
|
||||
|
||||
Whenever a new value is set that new value is automatically cached. This means
|
||||
that most drivers do not need to implement the g_volatile_ctrl() op. The
|
||||
exception is for controls that return a volatile register such as a signal
|
||||
strength read-out that changes continuously. In that case you will need to
|
||||
implement g_volatile_ctrl like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
ctrl->val = read_reg(0x123);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Note that you use the 'new value' union as well in g_volatile_ctrl. In general
|
||||
controls that need to implement g_volatile_ctrl are read-only controls. If they
|
||||
are not, a V4L2_EVENT_CTRL_CH_VALUE will not be generated when the control
|
||||
changes.
|
||||
|
||||
To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
|
||||
if (ctrl)
|
||||
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
For try/s_ctrl the new values (i.e. as passed by the user) are filled in and
|
||||
you can modify them in try_ctrl or set them in s_ctrl. The 'cur' union
|
||||
contains the current value, which you can use (but not change!) as well.
|
||||
|
||||
If s_ctrl returns 0 (OK), then the control framework will copy the new final
|
||||
values to the 'cur' union.
|
||||
|
||||
While in g_volatile/s/try_ctrl you can access the value of all controls owned
|
||||
by the same handler since the handler's lock is held. If you need to access
|
||||
the value of controls owned by other handlers, then you have to be very careful
|
||||
not to introduce deadlocks.
|
||||
|
||||
Outside of the control ops you have to go through to helper functions to get
|
||||
or set a single control value safely in your driver:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
|
||||
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
|
||||
|
||||
These functions go through the control framework just as VIDIOC_G/S_CTRL ioctls
|
||||
do. Don't use these inside the control ops g_volatile/s/try_ctrl, though, that
|
||||
will result in a deadlock since these helpers lock the handler as well.
|
||||
|
||||
You can also take the handler lock yourself:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
mutex_lock(&state->ctrl_handler.lock);
|
||||
pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
|
||||
pr_info("Integer value is '%s'\n", ctrl2->cur.val);
|
||||
mutex_unlock(&state->ctrl_handler.lock);
|
||||
|
||||
|
||||
Menu Controls
|
||||
-------------
|
||||
|
||||
The v4l2_ctrl struct contains this union:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
union {
|
||||
u32 step;
|
||||
u32 menu_skip_mask;
|
||||
};
|
||||
|
||||
For menu controls menu_skip_mask is used. What it does is that it allows you
|
||||
to easily exclude certain menu items. This is used in the VIDIOC_QUERYMENU
|
||||
implementation where you can return -EINVAL if a certain menu item is not
|
||||
present. Note that VIDIOC_QUERYCTRL always returns a step value of 1 for
|
||||
menu controls.
|
||||
|
||||
A good example is the MPEG Audio Layer II Bitrate menu control where the
|
||||
menu is a list of standardized possible bitrates. But in practice hardware
|
||||
implementations will only support a subset of those. By setting the skip
|
||||
mask you can tell the framework which menu items should be skipped. Setting
|
||||
it to 0 means that all menu items are supported.
|
||||
|
||||
You set this mask either through the v4l2_ctrl_config struct for a custom
|
||||
control, or by calling v4l2_ctrl_new_std_menu().
|
||||
|
||||
|
||||
Custom Controls
|
||||
---------------
|
||||
|
||||
Driver specific controls can be created using v4l2_ctrl_new_custom():
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_config ctrl_filter = {
|
||||
.ops = &ctrl_custom_ops,
|
||||
.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
|
||||
.name = "Spatial Filter",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.flags = V4L2_CTRL_FLAG_SLIDER,
|
||||
.max = 15,
|
||||
.step = 1,
|
||||
};
|
||||
|
||||
ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_filter, NULL);
|
||||
|
||||
The last argument is the priv pointer which can be set to driver-specific
|
||||
private data.
|
||||
|
||||
The v4l2_ctrl_config struct also has a field to set the is_private flag.
|
||||
|
||||
If the name field is not set, then the framework will assume this is a standard
|
||||
control and will fill in the name, type and flags fields accordingly.
|
||||
|
||||
|
||||
Active and Grabbed Controls
|
||||
---------------------------
|
||||
|
||||
If you get more complex relationships between controls, then you may have to
|
||||
activate and deactivate controls. For example, if the Chroma AGC control is
|
||||
on, then the Chroma Gain control is inactive. That is, you may set it, but
|
||||
the value will not be used by the hardware as long as the automatic gain
|
||||
control is on. Typically user interfaces can disable such input fields.
|
||||
|
||||
You can set the 'active' status using v4l2_ctrl_activate(). By default all
|
||||
controls are active. Note that the framework does not check for this flag.
|
||||
It is meant purely for GUIs. The function is typically called from within
|
||||
s_ctrl.
|
||||
|
||||
The other flag is the 'grabbed' flag. A grabbed control means that you cannot
|
||||
change it because it is in use by some resource. Typical examples are MPEG
|
||||
bitrate controls that cannot be changed while capturing is in progress.
|
||||
|
||||
If a control is set to 'grabbed' using v4l2_ctrl_grab(), then the framework
|
||||
will return -EBUSY if an attempt is made to set this control. The
|
||||
v4l2_ctrl_grab() function is typically called from the driver when it
|
||||
starts or stops streaming.
|
||||
|
||||
|
||||
Control Clusters
|
||||
----------------
|
||||
|
||||
By default all controls are independent from the others. But in more
|
||||
complex scenarios you can get dependencies from one control to another.
|
||||
In that case you need to 'cluster' them:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct foo {
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
#define AUDIO_CL_VOLUME (0)
|
||||
#define AUDIO_CL_MUTE (1)
|
||||
struct v4l2_ctrl *audio_cluster[2];
|
||||
...
|
||||
};
|
||||
|
||||
state->audio_cluster[AUDIO_CL_VOLUME] =
|
||||
v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
state->audio_cluster[AUDIO_CL_MUTE] =
|
||||
v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
v4l2_ctrl_cluster(ARRAY_SIZE(state->audio_cluster), state->audio_cluster);
|
||||
|
||||
From now on whenever one or more of the controls belonging to the same
|
||||
cluster is set (or 'gotten', or 'tried'), only the control ops of the first
|
||||
control ('volume' in this example) is called. You effectively create a new
|
||||
composite control. Similar to how a 'struct' works in C.
|
||||
|
||||
So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set
|
||||
all two controls belonging to the audio_cluster:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_VOLUME: {
|
||||
struct v4l2_ctrl *mute = ctrl->cluster[AUDIO_CL_MUTE];
|
||||
|
||||
write_reg(0x123, mute->val ? 0 : ctrl->val);
|
||||
break;
|
||||
}
|
||||
case V4L2_CID_CONTRAST:
|
||||
write_reg(0x456, ctrl->val);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
In the example above the following are equivalent for the VOLUME case:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME]
|
||||
ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE]
|
||||
|
||||
In practice using cluster arrays like this becomes very tiresome. So instead
|
||||
the following equivalent method is used:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct {
|
||||
/* audio cluster */
|
||||
struct v4l2_ctrl *volume;
|
||||
struct v4l2_ctrl *mute;
|
||||
};
|
||||
|
||||
The anonymous struct is used to clearly 'cluster' these two control pointers,
|
||||
but it serves no other purpose. The effect is the same as creating an
|
||||
array with two control pointers. So you can just do:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
v4l2_ctrl_cluster(2, &state->volume);
|
||||
|
||||
And in foo_s_ctrl you can use these pointers directly: state->mute->val.
|
||||
|
||||
Note that controls in a cluster may be NULL. For example, if for some
|
||||
reason mute was never added (because the hardware doesn't support that
|
||||
particular feature), then mute will be NULL. So in that case we have a
|
||||
cluster of 2 controls, of which only 1 is actually instantiated. The
|
||||
only restriction is that the first control of the cluster must always be
|
||||
present, since that is the 'master' control of the cluster. The master
|
||||
control is the one that identifies the cluster and that provides the
|
||||
pointer to the v4l2_ctrl_ops struct that is used for that cluster.
|
||||
|
||||
Obviously, all controls in the cluster array must be initialized to either
|
||||
a valid control or to NULL.
|
||||
|
||||
In rare cases you might want to know which controls of a cluster actually
|
||||
were set explicitly by the user. For this you can check the 'is_new' flag of
|
||||
each control. For example, in the case of a volume/mute cluster the 'is_new'
|
||||
flag of the mute control would be set if the user called VIDIOC_S_CTRL for
|
||||
mute only. If the user would call VIDIOC_S_EXT_CTRLS for both mute and volume
|
||||
controls, then the 'is_new' flag would be 1 for both controls.
|
||||
|
||||
The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup().
|
||||
|
||||
|
||||
Handling autogain/gain-type Controls with Auto Clusters
|
||||
-------------------------------------------------------
|
||||
|
||||
A common type of control cluster is one that handles 'auto-foo/foo'-type
|
||||
controls. Typical examples are autogain/gain, autoexposure/exposure,
|
||||
autowhitebalance/red balance/blue balance. In all cases you have one control
|
||||
that determines whether another control is handled automatically by the hardware,
|
||||
or whether it is under manual control from the user.
|
||||
|
||||
If the cluster is in automatic mode, then the manual controls should be
|
||||
marked inactive and volatile. When the volatile controls are read the
|
||||
g_volatile_ctrl operation should return the value that the hardware's automatic
|
||||
mode set up automatically.
|
||||
|
||||
If the cluster is put in manual mode, then the manual controls should become
|
||||
active again and the volatile flag is cleared (so g_volatile_ctrl is no longer
|
||||
called while in manual mode). In addition just before switching to manual mode
|
||||
the current values as determined by the auto mode are copied as the new manual
|
||||
values.
|
||||
|
||||
Finally the V4L2_CTRL_FLAG_UPDATE should be set for the auto control since
|
||||
changing that control affects the control flags of the manual controls.
|
||||
|
||||
In order to simplify this a special variation of v4l2_ctrl_cluster was
|
||||
introduced:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
|
||||
u8 manual_val, bool set_volatile);
|
||||
|
||||
The first two arguments are identical to v4l2_ctrl_cluster. The third argument
|
||||
tells the framework which value switches the cluster into manual mode. The
|
||||
last argument will optionally set V4L2_CTRL_FLAG_VOLATILE for the non-auto controls.
|
||||
If it is false, then the manual controls are never volatile. You would typically
|
||||
use that if the hardware does not give you the option to read back to values as
|
||||
determined by the auto mode (e.g. if autogain is on, the hardware doesn't allow
|
||||
you to obtain the current gain value).
|
||||
|
||||
The first control of the cluster is assumed to be the 'auto' control.
|
||||
|
||||
Using this function will ensure that you don't need to handle all the complex
|
||||
flag and volatile handling.
|
||||
|
||||
|
||||
VIDIOC_LOG_STATUS Support
|
||||
-------------------------
|
||||
|
||||
This ioctl allow you to dump the current status of a driver to the kernel log.
|
||||
The v4l2_ctrl_handler_log_status(ctrl_handler, prefix) can be used to dump the
|
||||
value of the controls owned by the given handler to the log. You can supply a
|
||||
prefix as well. If the prefix didn't end with a space, then ': ' will be added
|
||||
for you.
|
||||
|
||||
|
||||
Different Handlers for Different Video Nodes
|
||||
--------------------------------------------
|
||||
|
||||
Usually the V4L2 driver has just one control handler that is global for
|
||||
all video nodes. But you can also specify different control handlers for
|
||||
different video nodes. You can do that by manually setting the ctrl_handler
|
||||
field of struct video_device.
|
||||
|
||||
That is no problem if there are no subdevs involved but if there are, then
|
||||
you need to block the automatic merging of subdev controls to the global
|
||||
control handler. You do that by simply setting the ctrl_handler field in
|
||||
struct v4l2_device to NULL. Now v4l2_device_register_subdev() will no longer
|
||||
merge subdev controls.
|
||||
|
||||
After each subdev was added, you will then have to call v4l2_ctrl_add_handler
|
||||
manually to add the subdev's control handler (sd->ctrl_handler) to the desired
|
||||
control handler. This control handler may be specific to the video_device or
|
||||
for a subset of video_device's. For example: the radio device nodes only have
|
||||
audio controls, while the video and vbi device nodes share the same control
|
||||
handler for the audio and video controls.
|
||||
|
||||
If you want to have one handler (e.g. for a radio device node) have a subset
|
||||
of another handler (e.g. for a video device node), then you should first add
|
||||
the controls to the first handler, add the other controls to the second
|
||||
handler and finally add the first handler to the second. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...);
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
|
||||
v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler, NULL);
|
||||
|
||||
The last argument to v4l2_ctrl_add_handler() is a filter function that allows
|
||||
you to filter which controls will be added. Set it to NULL if you want to add
|
||||
all controls.
|
||||
|
||||
Or you can add specific controls to a handler:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...);
|
||||
|
||||
What you should not do is make two identical controls for two handlers.
|
||||
For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
|
||||
This would be bad since muting the radio would not change the video mute
|
||||
control. The rule is to have one control for each hardware 'knob' that you
|
||||
can twiddle.
|
||||
|
||||
|
||||
Finding Controls
|
||||
----------------
|
||||
|
||||
Normally you have created the controls yourself and you can store the struct
|
||||
v4l2_ctrl pointer into your own struct.
|
||||
|
||||
But sometimes you need to find a control from another handler that you do
|
||||
not own. For example, if you have to find a volume control from a subdev.
|
||||
|
||||
You can do that by calling v4l2_ctrl_find:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *volume;
|
||||
|
||||
volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME);
|
||||
|
||||
Since v4l2_ctrl_find will lock the handler you have to be careful where you
|
||||
use it. For example, this is not a good idea:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
||||
v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...);
|
||||
v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...);
|
||||
|
||||
...and in video_ops.s_ctrl:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST);
|
||||
...
|
||||
|
||||
When s_ctrl is called by the framework the ctrl_handler.lock is already taken, so
|
||||
attempting to find another control from the same handler will deadlock.
|
||||
|
||||
It is recommended not to use this function from inside the control ops.
|
||||
|
||||
|
||||
Preventing Controls inheritance
|
||||
-------------------------------
|
||||
|
||||
When one control handler is added to another using v4l2_ctrl_add_handler, then
|
||||
by default all controls from one are merged to the other. But a subdev might
|
||||
have low-level controls that make sense for some advanced embedded system, but
|
||||
not when it is used in consumer-level hardware. In that case you want to keep
|
||||
those low-level controls local to the subdev. You can do this by simply
|
||||
setting the 'is_private' flag of the control to 1:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_config ctrl_private = {
|
||||
.ops = &ctrl_custom_ops,
|
||||
.id = V4L2_CID_...,
|
||||
.name = "Some Private Control",
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.max = 15,
|
||||
.step = 1,
|
||||
.is_private = 1,
|
||||
};
|
||||
|
||||
ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_private, NULL);
|
||||
|
||||
These controls will now be skipped when v4l2_ctrl_add_handler is called.
|
||||
|
||||
|
||||
V4L2_CTRL_TYPE_CTRL_CLASS Controls
|
||||
----------------------------------
|
||||
|
||||
Controls of this type can be used by GUIs to get the name of the control class.
|
||||
A fully featured GUI can make a dialog with multiple tabs with each tab
|
||||
containing the controls belonging to a particular control class. The name of
|
||||
each tab can be found by querying a special control with ID <control class | 1>.
|
||||
|
||||
Drivers do not have to care about this. The framework will automatically add
|
||||
a control of this type whenever the first control belonging to a new control
|
||||
class is added.
|
||||
|
||||
|
||||
Adding Notify Callbacks
|
||||
-----------------------
|
||||
|
||||
Sometimes the platform or bridge driver needs to be notified when a control
|
||||
from a sub-device driver changes. You can set a notify callback by calling
|
||||
this function:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
|
||||
void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
|
||||
|
||||
Whenever the give control changes value the notify callback will be called
|
||||
with a pointer to the control and the priv pointer that was passed with
|
||||
v4l2_ctrl_notify. Note that the control's handler lock is held when the
|
||||
notify function is called.
|
||||
|
||||
There can be only one notify function per control handler. Any attempt
|
||||
to set another notify function will cause a WARN_ON.
|
||||
|
||||
v4l2_ctrl functions and data structures
|
||||
---------------------------------------
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-ctrls.h
|
||||
29
Documentation/driver-api/media/v4l2-core.rst
Normal file
29
Documentation/driver-api/media/v4l2-core.rst
Normal file
@@ -0,0 +1,29 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Video4Linux devices
|
||||
-------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
v4l2-intro
|
||||
v4l2-dev
|
||||
v4l2-device
|
||||
v4l2-fh
|
||||
v4l2-subdev
|
||||
v4l2-event
|
||||
v4l2-controls
|
||||
v4l2-videobuf
|
||||
v4l2-videobuf2
|
||||
v4l2-clocks
|
||||
v4l2-dv-timings
|
||||
v4l2-flash-led-class
|
||||
v4l2-mc
|
||||
v4l2-mediabus
|
||||
v4l2-mem2mem
|
||||
v4l2-async
|
||||
v4l2-fwnode
|
||||
v4l2-rect
|
||||
v4l2-tuner
|
||||
v4l2-common
|
||||
v4l2-tveeprom
|
||||
375
Documentation/driver-api/media/v4l2-dev.rst
Normal file
375
Documentation/driver-api/media/v4l2-dev.rst
Normal file
@@ -0,0 +1,375 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Video device' s internal representation
|
||||
=======================================
|
||||
|
||||
The actual device nodes in the ``/dev`` directory are created using the
|
||||
:c:type:`video_device` struct (``v4l2-dev.h``). This struct can either be
|
||||
allocated dynamically or embedded in a larger struct.
|
||||
|
||||
To allocate it dynamically use :c:func:`video_device_alloc`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct video_device *vdev = video_device_alloc();
|
||||
|
||||
if (vdev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
vdev->release = video_device_release;
|
||||
|
||||
If you embed it in a larger struct, then you must set the ``release()``
|
||||
callback to your own function:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct video_device *vdev = &my_vdev->vdev;
|
||||
|
||||
vdev->release = my_vdev_release;
|
||||
|
||||
The ``release()`` callback must be set and it is called when the last user
|
||||
of the video device exits.
|
||||
|
||||
The default :c:func:`video_device_release` callback currently
|
||||
just calls ``kfree`` to free the allocated memory.
|
||||
|
||||
There is also a :c:func:`video_device_release_empty` function that does
|
||||
nothing (is empty) and should be used if the struct is embedded and there
|
||||
is nothing to do when it is released.
|
||||
|
||||
You should also set these fields of :c:type:`video_device`:
|
||||
|
||||
- :c:type:`video_device`->v4l2_dev: must be set to the :c:type:`v4l2_device`
|
||||
parent device.
|
||||
|
||||
- :c:type:`video_device`->name: set to something descriptive and unique.
|
||||
|
||||
- :c:type:`video_device`->vfl_dir: set this to ``VFL_DIR_RX`` for capture
|
||||
devices (``VFL_DIR_RX`` has value 0, so this is normally already the
|
||||
default), set to ``VFL_DIR_TX`` for output devices and ``VFL_DIR_M2M`` for mem2mem (codec) devices.
|
||||
|
||||
- :c:type:`video_device`->fops: set to the :c:type:`v4l2_file_operations`
|
||||
struct.
|
||||
|
||||
- :c:type:`video_device`->ioctl_ops: if you use the :c:type:`v4l2_ioctl_ops`
|
||||
to simplify ioctl maintenance (highly recommended to use this and it might
|
||||
become compulsory in the future!), then set this to your
|
||||
:c:type:`v4l2_ioctl_ops` struct. The :c:type:`video_device`->vfl_type and
|
||||
:c:type:`video_device`->vfl_dir fields are used to disable ops that do not
|
||||
match the type/dir combination. E.g. VBI ops are disabled for non-VBI nodes,
|
||||
and output ops are disabled for a capture device. This makes it possible to
|
||||
provide just one :c:type:`v4l2_ioctl_ops` struct for both vbi and
|
||||
video nodes.
|
||||
|
||||
- :c:type:`video_device`->lock: leave to ``NULL`` if you want to do all the
|
||||
locking in the driver. Otherwise you give it a pointer to a struct
|
||||
``mutex_lock`` and before the :c:type:`video_device`->unlocked_ioctl
|
||||
file operation is called this lock will be taken by the core and released
|
||||
afterwards. See the next section for more details.
|
||||
|
||||
- :c:type:`video_device`->queue: a pointer to the struct :c:type:`vb2_queue`
|
||||
associated with this device node.
|
||||
If queue is not ``NULL``, and queue->lock is not ``NULL``, then queue->lock
|
||||
is used for the queuing ioctls (``VIDIOC_REQBUFS``, ``CREATE_BUFS``,
|
||||
``QBUF``, ``DQBUF``, ``QUERYBUF``, ``PREPARE_BUF``, ``STREAMON`` and
|
||||
``STREAMOFF``) instead of the lock above.
|
||||
That way the :ref:`vb2 <vb2_framework>` queuing framework does not have
|
||||
to wait for other ioctls. This queue pointer is also used by the
|
||||
:ref:`vb2 <vb2_framework>` helper functions to check for
|
||||
queuing ownership (i.e. is the filehandle calling it allowed to do the
|
||||
operation).
|
||||
|
||||
- :c:type:`video_device`->prio: keeps track of the priorities. Used to
|
||||
implement ``VIDIOC_G_PRIORITY`` and ``VIDIOC_S_PRIORITY``.
|
||||
If left to ``NULL``, then it will use the struct :c:type:`v4l2_prio_state`
|
||||
in :c:type:`v4l2_device`. If you want to have a separate priority state per
|
||||
(group of) device node(s), then you can point it to your own struct
|
||||
:c:type:`v4l2_prio_state`.
|
||||
|
||||
- :c:type:`video_device`->dev_parent: you only set this if v4l2_device was
|
||||
registered with ``NULL`` as the parent ``device`` struct. This only happens
|
||||
in cases where one hardware device has multiple PCI devices that all share
|
||||
the same :c:type:`v4l2_device` core.
|
||||
|
||||
The cx88 driver is an example of this: one core :c:type:`v4l2_device` struct,
|
||||
but it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
|
||||
(cx8802). Since the :c:type:`v4l2_device` cannot be associated with two PCI
|
||||
devices at the same time it is setup without a parent device. But when the
|
||||
struct :c:type:`video_device` is initialized you **do** know which parent
|
||||
PCI device to use and so you set ``dev_device`` to the correct PCI device.
|
||||
|
||||
If you use :c:type:`v4l2_ioctl_ops`, then you should set
|
||||
:c:type:`video_device`->unlocked_ioctl to :c:func:`video_ioctl2` in your
|
||||
:c:type:`v4l2_file_operations` struct.
|
||||
|
||||
In some cases you want to tell the core that a function you had specified in
|
||||
your :c:type:`v4l2_ioctl_ops` should be ignored. You can mark such ioctls by
|
||||
calling this function before :c:func:`video_register_device` is called:
|
||||
|
||||
:c:func:`v4l2_disable_ioctl <v4l2_disable_ioctl>`
|
||||
(:c:type:`vdev <video_device>`, 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 :c:type:`v4l2_ioctl_ops`
|
||||
without having to make a new struct.
|
||||
|
||||
The :c:type:`v4l2_file_operations` struct is a subset of file_operations.
|
||||
The main difference is that the inode argument is omitted since it is never
|
||||
used.
|
||||
|
||||
If integration with the media framework is needed, you must initialize the
|
||||
:c:type:`media_entity` struct embedded in the :c:type:`video_device` struct
|
||||
(entity field) by calling :c:func:`media_entity_pads_init`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct media_pad *pad = &my_vdev->pad;
|
||||
int err;
|
||||
|
||||
err = media_entity_pads_init(&vdev->entity, 1, pad);
|
||||
|
||||
The pads array must have been previously initialized. There is no need to
|
||||
manually set the struct media_entity type and name fields.
|
||||
|
||||
A reference to the entity will be automatically acquired/released when the
|
||||
video device is opened/closed.
|
||||
|
||||
ioctls and locking
|
||||
------------------
|
||||
|
||||
The V4L core provides optional locking services. The main service is the
|
||||
lock field in struct :c:type:`video_device`, which is a pointer to a mutex.
|
||||
If you set this pointer, then that will be used by unlocked_ioctl to
|
||||
serialize all ioctls.
|
||||
|
||||
If you are using the :ref:`videobuf2 framework <vb2_framework>`, then there
|
||||
is a second lock that you can set: :c:type:`video_device`->queue->lock. If
|
||||
set, then this lock will be used instead of :c:type:`video_device`->lock
|
||||
to serialize all queuing ioctls (see the previous section
|
||||
for the full list of those ioctls).
|
||||
|
||||
The advantage of using a different lock for the queuing ioctls is that for some
|
||||
drivers (particularly USB drivers) certain commands such as setting controls
|
||||
can take a long time, so you want to use a separate lock for the buffer queuing
|
||||
ioctls. That way your ``VIDIOC_DQBUF`` doesn't stall because the driver is busy
|
||||
changing the e.g. exposure of the webcam.
|
||||
|
||||
Of course, you can always do all the locking yourself by leaving both lock
|
||||
pointers at ``NULL``.
|
||||
|
||||
If you use the old :ref:`videobuf framework <vb_framework>` then you must
|
||||
pass the :c:type:`video_device`->lock to the videobuf queue initialize
|
||||
function: if videobuf has to wait for a frame to arrive, then it will
|
||||
temporarily unlock the lock and relock it afterwards. If your driver also
|
||||
waits in the code, then you should do the same to allow other
|
||||
processes to access the device node while the first process is waiting for
|
||||
something.
|
||||
|
||||
In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the
|
||||
``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable.
|
||||
If you use the ``queue->lock`` pointer, then you can use the helper functions
|
||||
:c:func:`vb2_ops_wait_prepare` and :c:func:`vb2_ops_wait_finish`.
|
||||
|
||||
The implementation of a hotplug disconnect should also take the lock from
|
||||
:c:type:`video_device` before calling v4l2_device_disconnect. If you are also
|
||||
using :c:type:`video_device`->queue->lock, then you have to first lock
|
||||
:c:type:`video_device`->queue->lock followed by :c:type:`video_device`->lock.
|
||||
That way you can be sure no ioctl is running when you call
|
||||
:c:func:`v4l2_device_disconnect`.
|
||||
|
||||
Video device registration
|
||||
-------------------------
|
||||
|
||||
Next you register the video device with :c:func:`video_register_device`.
|
||||
This will create the character device for you.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
|
||||
if (err) {
|
||||
video_device_release(vdev); /* or kfree(my_vdev); */
|
||||
return err;
|
||||
}
|
||||
|
||||
If the :c:type:`v4l2_device` parent device has a not ``NULL`` mdev field,
|
||||
the video device entity will be automatically registered with the media
|
||||
device.
|
||||
|
||||
Which device is registered depends on the type argument. The following
|
||||
types exist:
|
||||
|
||||
========================== ==================== ==============================
|
||||
:c:type:`vfl_devnode_type` Device name Usage
|
||||
========================== ==================== ==============================
|
||||
``VFL_TYPE_VIDEO`` ``/dev/videoX`` for video input/output devices
|
||||
``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e.
|
||||
closed captions, teletext)
|
||||
``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners
|
||||
``VFL_TYPE_SUBDEV`` ``/dev/v4l-subdevX`` for V4L2 subdevices
|
||||
``VFL_TYPE_SDR`` ``/dev/swradioX`` for Software Defined Radio
|
||||
(SDR) tuners
|
||||
``VFL_TYPE_TOUCH`` ``/dev/v4l-touchX`` for touch sensors
|
||||
========================== ==================== ==============================
|
||||
|
||||
The last argument gives you a certain amount of control over the device
|
||||
device node number used (i.e. the X in ``videoX``). Normally you will pass -1
|
||||
to let the v4l2 framework pick the first free number. But sometimes users
|
||||
want to select a specific node number. It is common that drivers allow
|
||||
the user to select a specific device node number through a driver module
|
||||
option. That number is then passed to this function and video_register_device
|
||||
will attempt to select that device node number. If that number was already
|
||||
in use, then the next free device node number will be selected and it
|
||||
will send a warning to the kernel log.
|
||||
|
||||
Another use-case is if a driver creates many devices. In that case it can
|
||||
be useful to place different video devices in separate ranges. For example,
|
||||
video capture devices start at 0, video output devices start at 16.
|
||||
So you can use the last argument to specify a minimum device node number
|
||||
and the v4l2 framework will try to pick the first free number that is equal
|
||||
or higher to what you passed. If that fails, then it will just pick the
|
||||
first free number.
|
||||
|
||||
Since in this case you do not care about a warning about not being able
|
||||
to select the specified device node number, you can call the function
|
||||
:c:func:`video_register_device_no_warn` instead.
|
||||
|
||||
Whenever a device node is created some attributes are also created for you.
|
||||
If you look in ``/sys/class/video4linux`` you see the devices. Go into e.g.
|
||||
``video0`` and you will see 'name', 'dev_debug' and 'index' attributes. The
|
||||
'name' attribute is the 'name' field of the video_device struct. The
|
||||
'dev_debug' attribute can be used to enable core debugging. See the next
|
||||
section for more detailed information on this.
|
||||
|
||||
The 'index' attribute is the index of the device node: for each call to
|
||||
:c:func:`video_register_device()` the index is just increased by 1. The
|
||||
first video device node you register always starts with index 0.
|
||||
|
||||
Users can setup udev rules that utilize the index attribute to make fancy
|
||||
device names (e.g. '``mpegX``' for MPEG video capture device nodes).
|
||||
|
||||
After the device was successfully registered, then you can use these fields:
|
||||
|
||||
- :c:type:`video_device`->vfl_type: the device type passed to
|
||||
:c:func:`video_register_device`.
|
||||
- :c:type:`video_device`->minor: the assigned device minor number.
|
||||
- :c:type:`video_device`->num: the device node number (i.e. the X in
|
||||
``videoX``).
|
||||
- :c:type:`video_device`->index: the device index number.
|
||||
|
||||
If the registration failed, then you need to call
|
||||
:c:func:`video_device_release` to free the allocated :c:type:`video_device`
|
||||
struct, or free your own struct if the :c:type:`video_device` was embedded in
|
||||
it. The ``vdev->release()`` callback will never be called if the registration
|
||||
failed, nor should you ever attempt to unregister the device if the
|
||||
registration failed.
|
||||
|
||||
video device debugging
|
||||
----------------------
|
||||
|
||||
The 'dev_debug' attribute that is created for each video, vbi, radio or swradio
|
||||
device in ``/sys/class/video4linux/<devX>/`` allows you to enable logging of
|
||||
file operations.
|
||||
|
||||
It is a bitmask and the following bits can be set:
|
||||
|
||||
.. tabularcolumns:: |p{5ex}|L|
|
||||
|
||||
===== ================================================================
|
||||
Mask Description
|
||||
===== ================================================================
|
||||
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.
|
||||
0x20 Log error and messages in the control operations.
|
||||
===== ================================================================
|
||||
|
||||
Video device cleanup
|
||||
--------------------
|
||||
|
||||
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 with:
|
||||
|
||||
:c:func:`video_unregister_device`
|
||||
(:c:type:`vdev <video_device>`);
|
||||
|
||||
This will remove the device nodes from sysfs (causing udev to remove them
|
||||
from ``/dev``).
|
||||
|
||||
After :c:func:`video_unregister_device` returns no new opens can be done.
|
||||
However, in the case of USB devices some application might still have one of
|
||||
these device nodes open. So after the unregister all file operations (except
|
||||
release, of course) will return an error as well.
|
||||
|
||||
When the last user of the video device node exits, then the ``vdev->release()``
|
||||
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:
|
||||
|
||||
:c:func:`media_entity_cleanup <media_entity_cleanup>`
|
||||
(&vdev->entity);
|
||||
|
||||
This can be done from the release callback.
|
||||
|
||||
|
||||
helper functions
|
||||
----------------
|
||||
|
||||
There are a few useful helper functions:
|
||||
|
||||
- file and :c:type:`video_device` private data
|
||||
|
||||
You can set/get driver private data in the video_device struct using:
|
||||
|
||||
:c:func:`video_get_drvdata <video_get_drvdata>`
|
||||
(:c:type:`vdev <video_device>`);
|
||||
|
||||
:c:func:`video_set_drvdata <video_set_drvdata>`
|
||||
(:c:type:`vdev <video_device>`);
|
||||
|
||||
Note that you can safely call :c:func:`video_set_drvdata` before calling
|
||||
:c:func:`video_register_device`.
|
||||
|
||||
And this function:
|
||||
|
||||
:c:func:`video_devdata <video_devdata>`
|
||||
(struct file \*file);
|
||||
|
||||
returns the video_device belonging to the file struct.
|
||||
|
||||
The :c:func:`video_devdata` function combines :c:func:`video_get_drvdata`
|
||||
with :c:func:`video_devdata`:
|
||||
|
||||
:c:func:`video_drvdata <video_drvdata>`
|
||||
(struct file \*file);
|
||||
|
||||
You can go from a :c:type:`video_device` struct to the v4l2_device struct using:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
|
||||
|
||||
- Device node name
|
||||
|
||||
The :c:type:`video_device` node kernel name can be retrieved using:
|
||||
|
||||
:c:func:`video_device_node_name <video_device_node_name>`
|
||||
(:c:type:`vdev <video_device>`);
|
||||
|
||||
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
|
||||
video_device::minor fields.
|
||||
|
||||
video_device functions and data structures
|
||||
------------------------------------------
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-dev.h
|
||||
146
Documentation/driver-api/media/v4l2-device.rst
Normal file
146
Documentation/driver-api/media/v4l2-device.rst
Normal file
@@ -0,0 +1,146 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 device instance
|
||||
--------------------
|
||||
|
||||
Each device instance is represented by a struct :c:type:`v4l2_device`.
|
||||
Very simple devices can just allocate this struct, but most of the time you
|
||||
would embed this struct inside a larger struct.
|
||||
|
||||
You must register the device instance by calling:
|
||||
|
||||
:c:func:`v4l2_device_register <v4l2_device_register>`
|
||||
(dev, :c:type:`v4l2_dev <v4l2_device>`).
|
||||
|
||||
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.
|
||||
|
||||
Drivers that want integration with the media device framework need to set
|
||||
dev->driver_data manually to point to the driver-specific device structure
|
||||
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).
|
||||
If you set it up before calling :c:func:`v4l2_device_register` then it will
|
||||
be untouched. If dev is ``NULL``, then you **must** setup
|
||||
:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
|
||||
:c:func:`v4l2_device_register`.
|
||||
|
||||
You can use :c:func:`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``, 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:
|
||||
|
||||
:c:func:`v4l2_device_unregister`
|
||||
(: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.
|
||||
|
||||
If you have a hotpluggable device (e.g. a USB device), then when a disconnect
|
||||
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:
|
||||
|
||||
:c:func:`v4l2_device_disconnect`
|
||||
(:c:type:`v4l2_dev <v4l2_device>`).
|
||||
|
||||
This does *not* unregister the subdevs, so you still need to call the
|
||||
: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`.
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 buses 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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 :c:type:`v4l2_device` for hotpluggable devices. For this
|
||||
purpose :c:type:`v4l2_device` has refcounting support. The refcount is
|
||||
increased whenever :c:func:`video_register_device` is called and it is
|
||||
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.
|
||||
|
||||
If other device nodes (e.g. ALSA) are created, then you can increase and
|
||||
decrease the refcount manually as well by calling:
|
||||
|
||||
:c:func:`v4l2_device_get`
|
||||
(:c:type:`v4l2_dev <v4l2_device>`).
|
||||
|
||||
or:
|
||||
|
||||
:c:func:`v4l2_device_put`
|
||||
(:c:type:`v4l2_dev <v4l2_device>`).
|
||||
|
||||
Since the initial refcount is 1 you also need to call
|
||||
:c:func:`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.
|
||||
|
||||
v4l2_device functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-device.h
|
||||
6
Documentation/driver-api/media/v4l2-dv-timings.rst
Normal file
6
Documentation/driver-api/media/v4l2-dv-timings.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 DV Timings functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-dv-timings.h
|
||||
181
Documentation/driver-api/media/v4l2-event.rst
Normal file
181
Documentation/driver-api/media/v4l2-event.rst
Normal file
@@ -0,0 +1,181 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 events
|
||||
-----------
|
||||
|
||||
The V4L2 events provide a generic way to pass events to user space.
|
||||
The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
|
||||
|
||||
Events are subscribed per-filehandle. An event specification consists of a
|
||||
``type`` and is optionally associated with an object identified through the
|
||||
``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
|
||||
identified by the ``(type, id)`` tuple.
|
||||
|
||||
The :c:type:`v4l2_fh` struct has a list of subscribed events on its
|
||||
``subscribed`` field.
|
||||
|
||||
When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
|
||||
struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
|
||||
subscribed event.
|
||||
|
||||
Each :c:type:`v4l2_subscribed_event` struct ends with a
|
||||
:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
|
||||
of :c:func:`v4l2_event_subscribe`. This ringbuffer is used to store any events
|
||||
raised by the driver.
|
||||
|
||||
So every ``(type, ID)`` event tuple will have its own
|
||||
:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
|
||||
generating lots of events of one type in a short time, then that will
|
||||
not overwrite events of another type.
|
||||
|
||||
But if you get more events of one type than the size of the
|
||||
:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
|
||||
and the new one added.
|
||||
|
||||
The :c:type:`v4l2_kevent` struct links into the ``available``
|
||||
list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
|
||||
know which event to dequeue first.
|
||||
|
||||
Finally, if the event subscription is associated with a particular object
|
||||
such as a V4L2 control, then that object needs to know about that as well
|
||||
so that an event can be raised by that object. So the ``node`` field can
|
||||
be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
|
||||
such objects.
|
||||
|
||||
So to summarize:
|
||||
|
||||
- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
|
||||
and one of the ``available`` events.
|
||||
|
||||
- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
|
||||
(pending) events of that particular type.
|
||||
|
||||
- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
|
||||
object, then that object will have an internal list of
|
||||
struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
|
||||
event to that object.
|
||||
|
||||
Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
|
||||
``merge()`` and ``replace()`` callbacks which drivers can set. These
|
||||
callbacks are called when a new event is raised and there is no more room.
|
||||
|
||||
The ``replace()`` callback allows you to replace the payload of the old event
|
||||
with that of the new event, merging any relevant data from the old payload
|
||||
into the new payload that replaces it. It is called when this event type has
|
||||
a ringbuffer with size is one, i.e. only one event can be stored in the
|
||||
ringbuffer.
|
||||
|
||||
The ``merge()`` callback allows you to merge the oldest event payload into
|
||||
that of the second-oldest event payload. It is called when
|
||||
the ringbuffer has size is greater than one.
|
||||
|
||||
This way no status information is lost, just the intermediate steps leading
|
||||
up to that state.
|
||||
|
||||
A good example of these ``replace``/``merge`` callbacks is in v4l2-event.c:
|
||||
``ctrls_replace()`` and ``ctrls_merge()`` callbacks for the control event.
|
||||
|
||||
.. note::
|
||||
these callbacks can be called from interrupt context, so they must
|
||||
be fast.
|
||||
|
||||
In order to queue events to video device, drivers should call:
|
||||
|
||||
:c:func:`v4l2_event_queue <v4l2_event_queue>`
|
||||
(:c:type:`vdev <video_device>`, :c:type:`ev <v4l2_event>`)
|
||||
|
||||
The driver's only responsibility is to fill in the type and the data fields.
|
||||
The other fields will be filled in by V4L2.
|
||||
|
||||
Event subscription
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Subscribing to an event is via:
|
||||
|
||||
:c:func:`v4l2_event_subscribe <v4l2_event_subscribe>`
|
||||
(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>` ,
|
||||
elems, :c:type:`ops <v4l2_subscribed_event_ops>`)
|
||||
|
||||
|
||||
This function is used to implement :c:type:`video_device`->
|
||||
:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_subscribe_event``,
|
||||
but the driver must check first if the driver is able to produce events
|
||||
with specified event id, and then should call
|
||||
:c:func:`v4l2_event_subscribe` to subscribe the event.
|
||||
|
||||
The elems argument is the size of the event queue for this event. If it is 0,
|
||||
then the framework will fill in a default value (this depends on the event
|
||||
type).
|
||||
|
||||
The ops argument allows the driver to specify a number of callbacks:
|
||||
|
||||
.. tabularcolumns:: |p{1.5cm}|p{16.0cm}|
|
||||
|
||||
======== ==============================================================
|
||||
Callback Description
|
||||
======== ==============================================================
|
||||
add called when a new listener gets added (subscribing to the same
|
||||
event twice will only cause this callback to get called once)
|
||||
del called when a listener stops listening
|
||||
replace replace event 'old' with event 'new'.
|
||||
merge merge event 'old' into event 'new'.
|
||||
======== ==============================================================
|
||||
|
||||
All 4 callbacks are optional, if you don't want to specify any callbacks
|
||||
the ops argument itself maybe ``NULL``.
|
||||
|
||||
Unsubscribing an event
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Unsubscribing to an event is via:
|
||||
|
||||
:c:func:`v4l2_event_unsubscribe <v4l2_event_unsubscribe>`
|
||||
(:c:type:`fh <v4l2_fh>`, :c:type:`sub <v4l2_event_subscription>`)
|
||||
|
||||
This function is used to implement :c:type:`video_device`->
|
||||
:c:type:`ioctl_ops <v4l2_ioctl_ops>`-> ``vidioc_unsubscribe_event``.
|
||||
A driver may call :c:func:`v4l2_event_unsubscribe` directly unless it
|
||||
wants to be involved in unsubscription process.
|
||||
|
||||
The special type ``V4L2_EVENT_ALL`` may be used to unsubscribe all events. The
|
||||
drivers may want to handle this in a special way.
|
||||
|
||||
Check if there's a pending event
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Checking if there's a pending event is via:
|
||||
|
||||
:c:func:`v4l2_event_pending <v4l2_event_pending>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
|
||||
|
||||
This function returns the number of pending events. Useful when implementing
|
||||
poll.
|
||||
|
||||
How events work
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Events are delivered to user space through the poll system call. The driver
|
||||
can use :c:type:`v4l2_fh`->wait (a wait_queue_head_t) as the argument for
|
||||
``poll_wait()``.
|
||||
|
||||
There are standard and private events. New standard events must use the
|
||||
smallest available event type. The drivers must allocate their events from
|
||||
their own class starting from class base. Class base is
|
||||
``V4L2_EVENT_PRIVATE_START`` + n * 1000 where n is the lowest available number.
|
||||
The first event type in the class is reserved for future use, so the first
|
||||
available event type is 'class base + 1'.
|
||||
|
||||
An example on how the V4L2 events may be used can be found in the OMAP
|
||||
3 ISP driver (``drivers/media/platform/omap3isp``).
|
||||
|
||||
A subdev can directly send an event to the :c:type:`v4l2_device` notify
|
||||
function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
|
||||
the subdev that sends the event to the video node(s) associated with the
|
||||
subdev that need to be informed about such an event.
|
||||
|
||||
V4L2 event functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-event.h
|
||||
|
||||
141
Documentation/driver-api/media/v4l2-fh.rst
Normal file
141
Documentation/driver-api/media/v4l2-fh.rst
Normal file
@@ -0,0 +1,141 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 File handlers
|
||||
------------------
|
||||
|
||||
struct :c:type:`v4l2_fh` provides a way to easily keep file handle specific
|
||||
data that is used by the V4L2 framework.
|
||||
|
||||
.. attention::
|
||||
New drivers must use struct :c:type:`v4l2_fh`
|
||||
since it is also used to implement priority handling
|
||||
(:ref:`VIDIOC_G_PRIORITY`).
|
||||
|
||||
The users of :c:type:`v4l2_fh` (in the V4L2 framework, not the driver) know
|
||||
whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
|
||||
by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
|
||||
This bit is set whenever :c:func:`v4l2_fh_init` is called.
|
||||
|
||||
struct :c:type:`v4l2_fh` is allocated as a part of the driver's own file handle
|
||||
structure and ``file->private_data`` is set to it in the driver's ``open()``
|
||||
function by the driver.
|
||||
|
||||
In many cases the struct :c:type:`v4l2_fh` will be embedded in a larger
|
||||
structure. In that case you should call:
|
||||
|
||||
#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
|
||||
#) :c:func:`v4l2_fh_del` and :c:func:`v4l2_fh_exit` in ``release()``
|
||||
|
||||
Drivers can extract their own file handle structure by using the container_of
|
||||
macro.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct my_fh {
|
||||
int blah;
|
||||
struct v4l2_fh fh;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
int my_open(struct file *file)
|
||||
{
|
||||
struct my_fh *my_fh;
|
||||
struct video_device *vfd;
|
||||
int ret;
|
||||
|
||||
...
|
||||
|
||||
my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
|
||||
|
||||
...
|
||||
|
||||
v4l2_fh_init(&my_fh->fh, vfd);
|
||||
|
||||
...
|
||||
|
||||
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 :c:type:`v4l2_fh` functions used:
|
||||
|
||||
:c:func:`v4l2_fh_init <v4l2_fh_init>`
|
||||
(:c:type:`fh <v4l2_fh>`, :c:type:`vdev <video_device>`)
|
||||
|
||||
|
||||
- Initialise the file handle. This **MUST** be performed in the driver's
|
||||
:c:type:`v4l2_file_operations`->open() handler.
|
||||
|
||||
|
||||
:c:func:`v4l2_fh_add <v4l2_fh_add>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
|
||||
- Add a :c:type:`v4l2_fh` to :c:type:`video_device` file handle list.
|
||||
Must be called once the file handle is completely initialized.
|
||||
|
||||
:c:func:`v4l2_fh_del <v4l2_fh_del>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
|
||||
- Unassociate the file handle from :c:type:`video_device`. The file handle
|
||||
exit function may now be called.
|
||||
|
||||
:c:func:`v4l2_fh_exit <v4l2_fh_exit>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
|
||||
- Uninitialise the file handle. After uninitialisation the :c:type:`v4l2_fh`
|
||||
memory can be freed.
|
||||
|
||||
|
||||
If struct :c:type:`v4l2_fh` is not embedded, then you can use these helper functions:
|
||||
|
||||
:c:func:`v4l2_fh_open <v4l2_fh_open>`
|
||||
(struct file \*filp)
|
||||
|
||||
- This allocates a struct :c:type:`v4l2_fh`, initializes it and adds it to
|
||||
the struct :c:type:`video_device` associated with the file struct.
|
||||
|
||||
:c:func:`v4l2_fh_release <v4l2_fh_release>`
|
||||
(struct file \*filp)
|
||||
|
||||
- This deletes it from the struct :c:type:`video_device` associated with the
|
||||
file struct, uninitialised the :c:type:`v4l2_fh` and frees it.
|
||||
|
||||
These two functions can be plugged into the v4l2_file_operation's ``open()``
|
||||
and ``release()`` ops.
|
||||
|
||||
Several drivers need to do something when the first file handle is opened and
|
||||
when the last file handle closes. Two helper functions were added to check
|
||||
whether the :c:type:`v4l2_fh` struct is the only open filehandle of the
|
||||
associated device node:
|
||||
|
||||
:c:func:`v4l2_fh_is_singular <v4l2_fh_is_singular>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
|
||||
- Returns 1 if the file handle is the only open file handle, else 0.
|
||||
|
||||
:c:func:`v4l2_fh_is_singular_file <v4l2_fh_is_singular_file>`
|
||||
(struct file \*filp)
|
||||
|
||||
- Same, but it calls v4l2_fh_is_singular with filp->private_data.
|
||||
|
||||
|
||||
V4L2 fh functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-fh.h
|
||||
6
Documentation/driver-api/media/v4l2-flash-led-class.rst
Normal file
6
Documentation/driver-api/media/v4l2-flash-led-class.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 flash functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-flash-led-class.h
|
||||
5
Documentation/driver-api/media/v4l2-fwnode.rst
Normal file
5
Documentation/driver-api/media/v4l2-fwnode.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 fwnode kAPI
|
||||
^^^^^^^^^^^^^^^^
|
||||
.. kernel-doc:: include/media/v4l2-fwnode.h
|
||||
76
Documentation/driver-api/media/v4l2-intro.rst
Normal file
76
Documentation/driver-api/media/v4l2-intro.rst
Normal file
@@ -0,0 +1,76 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The V4L2 drivers tend to be very complex due to the complexity of the
|
||||
hardware: most devices have multiple ICs, export multiple device nodes in
|
||||
/dev, and create also non-V4L2 devices such as DVB, ALSA, FB, I2C and input
|
||||
(IR) devices.
|
||||
|
||||
Especially the fact that V4L2 drivers have to setup supporting ICs to
|
||||
do audio/video muxing/encoding/decoding makes it more complex than most.
|
||||
Usually these ICs are connected to the main bridge driver through one or
|
||||
more I2C buses, but other buses can also be used. Such devices are
|
||||
called 'sub-devices'.
|
||||
|
||||
For a long time the framework was limited to the video_device struct for
|
||||
creating V4L device nodes and video_buf for handling the video buffers
|
||||
(note that this document does not discuss the video_buf framework).
|
||||
|
||||
This meant that all drivers had to do the setup of device instances and
|
||||
connecting to sub-devices themselves. Some of this is quite complicated
|
||||
to do right and many drivers never did do it correctly.
|
||||
|
||||
There is also a lot of common code that could never be refactored due to
|
||||
the lack of a framework.
|
||||
|
||||
So this framework sets up the basic building blocks that all drivers
|
||||
need and this same framework should make it much easier to refactor
|
||||
common code into utility functions shared by all drivers.
|
||||
|
||||
A good example to look at as a reference is the v4l2-pci-skeleton.c
|
||||
source that is available in samples/v4l/. It is a skeleton driver for
|
||||
a PCI capture card, and demonstrates how to use the V4L2 driver
|
||||
framework. It can be used as a template for real PCI video capture driver.
|
||||
|
||||
Structure of a V4L driver
|
||||
-------------------------
|
||||
|
||||
All drivers have the following structure:
|
||||
|
||||
1) A struct for each device instance containing the device state.
|
||||
|
||||
2) A way of initializing and commanding sub-devices (if any).
|
||||
|
||||
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX and /dev/radioX)
|
||||
and keeping track of device-node specific data.
|
||||
|
||||
4) Filehandle-specific structs containing per-filehandle data;
|
||||
|
||||
5) video buffer handling.
|
||||
|
||||
This is a rough schematic of how it all relates:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
device instances
|
||||
|
|
||||
+-sub-device instances
|
||||
|
|
||||
\-V4L2 device nodes
|
||||
|
|
||||
\-filehandle instances
|
||||
|
||||
|
||||
Structure of the V4L2 framework
|
||||
-------------------------------
|
||||
|
||||
The framework closely resembles the driver structure: it has a v4l2_device
|
||||
struct for the device instance data, a v4l2_subdev struct to refer to
|
||||
sub-device instances, the video_device struct stores V4L2 device node data
|
||||
and the v4l2_fh struct keeps track of filehandle instances.
|
||||
|
||||
The V4L2 framework also optionally integrates with the media framework. If a
|
||||
driver sets the struct v4l2_device mdev field, sub-devices and video nodes
|
||||
will automatically appear in the media framework as entities.
|
||||
6
Documentation/driver-api/media/v4l2-mc.rst
Normal file
6
Documentation/driver-api/media/v4l2-mc.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 Media Controller functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-mc.h
|
||||
6
Documentation/driver-api/media/v4l2-mediabus.rst
Normal file
6
Documentation/driver-api/media/v4l2-mediabus.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 Media Bus functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-mediabus.h
|
||||
6
Documentation/driver-api/media/v4l2-mem2mem.rst
Normal file
6
Documentation/driver-api/media/v4l2-mem2mem.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 Memory to Memory functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-mem2mem.h
|
||||
6
Documentation/driver-api/media/v4l2-rect.rst
Normal file
6
Documentation/driver-api/media/v4l2-rect.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 rect helper functions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-rect.h
|
||||
444
Documentation/driver-api/media/v4l2-subdev.rst
Normal file
444
Documentation/driver-api/media/v4l2-subdev.rst
Normal file
@@ -0,0 +1,444 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 sub-devices
|
||||
----------------
|
||||
|
||||
Many drivers need to communicate with sub-devices. These devices can do all
|
||||
sort of tasks, but most commonly they handle audio and/or video muxing,
|
||||
encoding or decoding. For webcams common sub-devices are sensors and camera
|
||||
controllers.
|
||||
|
||||
Usually these are I2C devices, but not necessarily. In order to provide the
|
||||
driver with a consistent interface to these sub-devices the
|
||||
:c:type:`v4l2_subdev` struct (v4l2-subdev.h) was created.
|
||||
|
||||
Each sub-device driver must have a :c:type:`v4l2_subdev` struct. This struct
|
||||
can be stand-alone for simple sub-devices or it might be embedded in a larger
|
||||
struct if more state information needs to be stored. Usually there is a
|
||||
low-level device struct (e.g. ``i2c_client``) that contains the device data as
|
||||
setup by the kernel. It is recommended to store that pointer in the private
|
||||
data of :c:type:`v4l2_subdev` using :c:func:`v4l2_set_subdevdata`. That makes
|
||||
it easy to go from a :c:type:`v4l2_subdev` to the actual low-level bus-specific
|
||||
device data.
|
||||
|
||||
You also need a way to go from the low-level struct to :c:type:`v4l2_subdev`.
|
||||
For the common i2c_client struct the i2c_set_clientdata() call is used to store
|
||||
a :c:type:`v4l2_subdev` pointer, for other buses you may have to use other
|
||||
methods.
|
||||
|
||||
Bridges might also need to store per-subdev private data, such as a pointer to
|
||||
bridge-specific per-subdev private data. The :c:type:`v4l2_subdev` structure
|
||||
provides host private data for that purpose that can be accessed with
|
||||
:c:func:`v4l2_get_subdev_hostdata` and :c:func:`v4l2_set_subdev_hostdata`.
|
||||
|
||||
From the bridge driver perspective, you load the sub-device module and somehow
|
||||
obtain the :c:type:`v4l2_subdev` pointer. For i2c devices this is easy: you call
|
||||
``i2c_get_clientdata()``. For other buses something similar needs to be done.
|
||||
Helper functions exists for sub-devices on an I2C bus that do most of this
|
||||
tricky work for you.
|
||||
|
||||
Each :c:type:`v4l2_subdev` contains function pointers that sub-device drivers
|
||||
can implement (or leave ``NULL`` if it is not applicable). Since sub-devices can
|
||||
do so many different things and you do not want to end up with a huge ops struct
|
||||
of which only a handful of ops are commonly implemented, the function pointers
|
||||
are sorted according to category and each category has its own ops struct.
|
||||
|
||||
The top-level ops struct contains pointers to the category ops structs, which
|
||||
may be NULL if the subdev driver does not support anything from that category.
|
||||
|
||||
It looks like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_subdev_core_ops {
|
||||
int (*log_status)(struct v4l2_subdev *sd);
|
||||
int (*init)(struct v4l2_subdev *sd, u32 val);
|
||||
...
|
||||
};
|
||||
|
||||
struct v4l2_subdev_tuner_ops {
|
||||
...
|
||||
};
|
||||
|
||||
struct v4l2_subdev_audio_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;
|
||||
};
|
||||
|
||||
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
|
||||
audio ops and vice versa.
|
||||
|
||||
This setup limits the number of function pointers while still making it easy
|
||||
to add new ops and categories.
|
||||
|
||||
A sub-device driver initializes the :c:type:`v4l2_subdev` struct using:
|
||||
|
||||
:c:func:`v4l2_subdev_init <v4l2_subdev_init>`
|
||||
(:c:type:`sd <v4l2_subdev>`, &\ :c:type:`ops <v4l2_subdev_ops>`).
|
||||
|
||||
|
||||
Afterwards you need to initialize :c:type:`sd <v4l2_subdev>`->name with a
|
||||
unique name and set the module owner. This is done for you if you use the
|
||||
i2c helper functions.
|
||||
|
||||
If integration with the media framework is needed, you must initialize the
|
||||
:c:type:`media_entity` struct embedded in the :c:type:`v4l2_subdev` struct
|
||||
(entity field) by calling :c:func:`media_entity_pads_init`, if the entity has
|
||||
pads:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct media_pad *pads = &my_sd->pads;
|
||||
int err;
|
||||
|
||||
err = media_entity_pads_init(&sd->entity, npads, pads);
|
||||
|
||||
The pads array must have been previously initialized. There is no need to
|
||||
manually set the struct :c:type:`media_entity` function and name fields, but the
|
||||
revision field must be initialized if needed.
|
||||
|
||||
A reference to the entity will be automatically acquired/released when the
|
||||
subdev device node (if any) is opened/closed.
|
||||
|
||||
Don't forget to cleanup the media entity before the sub-device is destroyed:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
media_entity_cleanup(&sd->entity);
|
||||
|
||||
If the subdev driver intends to process video and integrate with the media
|
||||
framework, it must implement format related functionality using
|
||||
:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`.
|
||||
|
||||
In that case, the subdev driver may set the link_validate field to provide
|
||||
its own link validation function. The link validation function is called for
|
||||
every link in the pipeline where both of the ends of the links are V4L2
|
||||
sub-devices. The driver is still responsible for validating the correctness
|
||||
of the format configuration between sub-devices and video nodes.
|
||||
|
||||
If link_validate op is not set, the default function
|
||||
:c:func:`v4l2_subdev_link_validate_default` is used instead. This function
|
||||
ensures that width, height and the media bus pixel code are equal on both source
|
||||
and sink of the link. Subdev drivers are also free to use this function to
|
||||
perform the checks mentioned above in addition to their own checks.
|
||||
|
||||
There are currently two ways to register subdevices with the V4L2 core. The
|
||||
first (traditional) possibility is to have subdevices registered by bridge
|
||||
drivers. This can be done when the bridge driver has the complete information
|
||||
about subdevices connected to it and knows exactly when to register them. This
|
||||
is typically the case for internal subdevices, like video data processing units
|
||||
within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
|
||||
to SoCs, which pass information about them to bridge drivers, usually in their
|
||||
platform data.
|
||||
|
||||
There are however also situations where subdevices have to be registered
|
||||
asynchronously to bridge devices. An example of such a configuration is a Device
|
||||
Tree based system where information about subdevices is made available to the
|
||||
system independently from the bridge devices, e.g. when subdevices are defined
|
||||
in DT as I2C device nodes. The API used in this second case is described further
|
||||
below.
|
||||
|
||||
Using one or the other registration method only affects the probing process, the
|
||||
run-time bridge-subdevice interaction is in both cases the same.
|
||||
|
||||
In the synchronous case a device (bridge) driver needs to register the
|
||||
:c:type:`v4l2_subdev` with the v4l2_device:
|
||||
|
||||
:c:func:`v4l2_device_register_subdev <v4l2_device_register_subdev>`
|
||||
(:c:type:`v4l2_dev <v4l2_device>`, :c:type:`sd <v4l2_subdev>`).
|
||||
|
||||
This can fail if the subdev module disappeared before it could be registered.
|
||||
After this function was called successfully the subdev->dev field points to
|
||||
the :c:type:`v4l2_device`.
|
||||
|
||||
If the v4l2_device parent device has a non-NULL mdev field, the sub-device
|
||||
entity will be automatically registered with the media device.
|
||||
|
||||
You can unregister a sub-device using:
|
||||
|
||||
:c:func:`v4l2_device_unregister_subdev <v4l2_device_unregister_subdev>`
|
||||
(:c:type:`sd <v4l2_subdev>`).
|
||||
|
||||
|
||||
Afterwards the subdev module can be unloaded and
|
||||
:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
|
||||
|
||||
You can call an ops function either directly:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
err = sd->ops->core->g_std(sd, &norm);
|
||||
|
||||
but it is better and easier to use this macro:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
err = v4l2_subdev_call(sd, core, g_std, &norm);
|
||||
|
||||
The macro will to the right ``NULL`` pointer checks and returns ``-ENODEV``
|
||||
if :c:type:`sd <v4l2_subdev>` is ``NULL``, ``-ENOIOCTLCMD`` if either
|
||||
:c:type:`sd <v4l2_subdev>`->core or :c:type:`sd <v4l2_subdev>`->core->g_std is ``NULL``, or the actual result of the
|
||||
:c:type:`sd <v4l2_subdev>`->ops->core->g_std ops.
|
||||
|
||||
It is also possible to call all or a subset of the sub-devices:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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:: c
|
||||
|
||||
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
|
||||
errors (except ``-ENOIOCTLCMD``) occurred, then 0 is returned.
|
||||
|
||||
The second argument to both calls is a group ID. If 0, then all subdevs are
|
||||
called. If non-zero, then only those whose group ID match that value will
|
||||
be called. Before a bridge driver registers a subdev it can set
|
||||
:c:type:`sd <v4l2_subdev>`->grp_id to whatever value it wants (it's 0 by
|
||||
default). This value is owned by the bridge driver and the sub-device driver
|
||||
will never modify or use it.
|
||||
|
||||
The group ID gives the bridge driver more control how callbacks are called.
|
||||
For example, there may be multiple audio chips on a board, each capable of
|
||||
changing the volume. But usually only one will actually be used when the
|
||||
user want to change the volume. You can set the group ID for that subdev to
|
||||
e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
|
||||
``v4l2_device_call_all()``. That ensures that it will only go to the subdev
|
||||
that needs it.
|
||||
|
||||
If the sub-device needs to notify its v4l2_device parent of an event, then
|
||||
it can call ``v4l2_subdev_notify(sd, notification, arg)``. This macro checks
|
||||
whether there is a ``notify()`` callback defined and returns ``-ENODEV`` if not.
|
||||
Otherwise the result of the ``notify()`` call is returned.
|
||||
|
||||
The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
|
||||
does not contain any knowledge about the underlying hardware. So a driver might
|
||||
contain several subdevs that use an I2C bus, but also a subdev that is
|
||||
controlled through GPIO pins. This distinction is only relevant when setting
|
||||
up the device, but once the subdev is registered it is completely transparent.
|
||||
|
||||
In the asynchronous case subdevice probing can be invoked independently of the
|
||||
bridge driver availability. The subdevice driver then has to verify whether all
|
||||
the requirements for a successful probing are satisfied. This can include a
|
||||
check for a master clock availability. If any of the conditions aren't satisfied
|
||||
the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
|
||||
attempts. Once all conditions are met the subdevice shall be registered using
|
||||
the :c:func:`v4l2_async_register_subdev` function. Unregistration is
|
||||
performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
|
||||
registered this way are stored in a global list of subdevices, ready to be
|
||||
picked up by bridge drivers.
|
||||
|
||||
Bridge drivers in turn have to register a notifier object. This is
|
||||
performed using the :c:func:`v4l2_async_notifier_register` call. To
|
||||
unregister the notifier the driver has to call
|
||||
:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
|
||||
takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
|
||||
pointer to struct :c:type:`v4l2_async_notifier`.
|
||||
|
||||
Before registering the notifier, bridge drivers must do two things:
|
||||
first, the notifier must be initialized using the
|
||||
:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
|
||||
begin to form a list of subdevice descriptors that the bridge device
|
||||
needs for its operation. Subdevice descriptors are added to the notifier
|
||||
using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
|
||||
takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
|
||||
and a pointer to the subdevice descripter, which is of type struct
|
||||
:c:type:`v4l2_async_subdev`.
|
||||
|
||||
The V4L2 core will then use these descriptors to match asynchronously
|
||||
registered subdevices to them. If a match is detected the ``.bound()``
|
||||
notifier callback is called. After all subdevices have been located the
|
||||
.complete() callback is called. When a subdevice is removed from the
|
||||
system the .unbind() method is called. All three callbacks are optional.
|
||||
|
||||
V4L2 sub-device userspace API
|
||||
-----------------------------
|
||||
|
||||
Beside exposing a kernel API through the :c:type:`v4l2_subdev_ops` structure,
|
||||
V4L2 sub-devices can also be controlled directly by userspace applications.
|
||||
|
||||
Device nodes named ``v4l-subdev``\ *X* can be created in ``/dev`` to access
|
||||
sub-devices directly. If a sub-device supports direct userspace configuration
|
||||
it must set the ``V4L2_SUBDEV_FL_HAS_DEVNODE`` flag before being registered.
|
||||
|
||||
After registering sub-devices, the :c:type:`v4l2_device` driver can create
|
||||
device nodes for all registered sub-devices marked with
|
||||
``V4L2_SUBDEV_FL_HAS_DEVNODE`` by calling
|
||||
:c:func:`v4l2_device_register_subdev_nodes`. Those device nodes will be
|
||||
automatically removed when sub-devices are unregistered.
|
||||
|
||||
The device node handles a subset of the V4L2 API.
|
||||
|
||||
``VIDIOC_QUERYCTRL``,
|
||||
``VIDIOC_QUERYMENU``,
|
||||
``VIDIOC_G_CTRL``,
|
||||
``VIDIOC_S_CTRL``,
|
||||
``VIDIOC_G_EXT_CTRLS``,
|
||||
``VIDIOC_S_EXT_CTRLS`` and
|
||||
``VIDIOC_TRY_EXT_CTRLS``:
|
||||
|
||||
The controls ioctls are identical to the ones defined in V4L2. They
|
||||
behave identically, with the only exception that they deal only with
|
||||
controls implemented in the sub-device. Depending on the driver, those
|
||||
controls can be also be accessed through one (or several) V4L2 device
|
||||
nodes.
|
||||
|
||||
``VIDIOC_DQEVENT``,
|
||||
``VIDIOC_SUBSCRIBE_EVENT`` and
|
||||
``VIDIOC_UNSUBSCRIBE_EVENT``
|
||||
|
||||
The events ioctls are identical to the ones defined in V4L2. They
|
||||
behave identically, with the only exception that they deal only with
|
||||
events generated by the sub-device. Depending on the driver, those
|
||||
events can also be reported by one (or several) V4L2 device nodes.
|
||||
|
||||
Sub-device drivers that want to use events need to set the
|
||||
``V4L2_SUBDEV_USES_EVENTS`` :c:type:`v4l2_subdev`.flags and initialize
|
||||
:c:type:`v4l2_subdev`.nevents to events queue depth before registering
|
||||
the sub-device. After registration events can be queued as usual on the
|
||||
:c:type:`v4l2_subdev`.devnode device node.
|
||||
|
||||
To properly support events, the ``poll()`` file operation is also
|
||||
implemented.
|
||||
|
||||
Private ioctls
|
||||
|
||||
All ioctls not in the above list are passed directly to the sub-device
|
||||
driver through the core::ioctl operation.
|
||||
|
||||
|
||||
I2C sub-device drivers
|
||||
----------------------
|
||||
|
||||
Since these drivers are so common, special helper functions are available to
|
||||
ease the use of these drivers (``v4l2-common.h``).
|
||||
|
||||
The recommended method of adding :c:type:`v4l2_subdev` support to an I2C driver
|
||||
is to embed the :c:type:`v4l2_subdev` struct into the state struct that is
|
||||
created for each I2C device instance. Very simple devices have no state
|
||||
struct and in that case you can just create a :c:type:`v4l2_subdev` directly.
|
||||
|
||||
A typical state struct would look like this (where 'chipname' is replaced by
|
||||
the name of the chip):
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct chipname_state {
|
||||
struct v4l2_subdev sd;
|
||||
... /* additional state fields */
|
||||
};
|
||||
|
||||
Initialize the :c:type:`v4l2_subdev` struct as follows:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
|
||||
|
||||
This function will fill in all the fields of :c:type:`v4l2_subdev` ensure that
|
||||
the :c:type:`v4l2_subdev` and i2c_client both point to one another.
|
||||
|
||||
You should also add a helper inline function to go from a :c:type:`v4l2_subdev`
|
||||
pointer to a chipname_state struct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 :c:type:`v4l2_subdev` struct to the ``i2c_client``
|
||||
struct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
|
||||
And this to go from an ``i2c_client`` to a :c:type:`v4l2_subdev` struct:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
|
||||
Make sure to call
|
||||
:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
|
||||
when the ``remove()`` callback is called. This will unregister the sub-device
|
||||
from the bridge driver. It is safe to call this even if the sub-device was
|
||||
never registered.
|
||||
|
||||
You need to do this because when the bridge driver destroys the i2c adapter
|
||||
the ``remove()`` callbacks are called of the i2c devices on that adapter.
|
||||
After that the corresponding v4l2_subdev structures are invalid, so they
|
||||
have to be unregistered first. Calling
|
||||
:c:func:`v4l2_device_unregister_subdev`\ (:c:type:`sd <v4l2_subdev>`)
|
||||
from the ``remove()`` callback ensures that this is always done correctly.
|
||||
|
||||
|
||||
The bridge driver also has some helper functions it can use:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
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 :c:func:`i2c_new_device` with the given ``i2c_adapter`` and
|
||||
chip/address arguments. If all goes well, then it registers the subdev with
|
||||
the v4l2_device.
|
||||
|
||||
You can also use the last argument of :c:func:`v4l2_i2c_new_subdev` to pass
|
||||
an array of possible I2C addresses that it should probe. These probe addresses
|
||||
are only used if the previous argument is 0. A non-zero argument means that you
|
||||
know the exact i2c address so in that case no probing will take place.
|
||||
|
||||
Both functions return ``NULL`` if something went wrong.
|
||||
|
||||
Note that the chipid you pass to :c:func:`v4l2_i2c_new_subdev` is usually
|
||||
the same as the module name. It allows you to specify a chip variant, e.g.
|
||||
"saa7114" or "saa7115". In general though the i2c driver autodetects this.
|
||||
The use of chipid is something that needs to be looked at more closely at a
|
||||
later date. It differs between i2c drivers and as such can be confusing.
|
||||
To see which chip variants are supported you can look in the i2c driver code
|
||||
for the i2c_device_id table. This lists all the possibilities.
|
||||
|
||||
There are one more helper function:
|
||||
|
||||
:c:func:`v4l2_i2c_new_subdev_board` uses an :c:type:`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 :c:func:`v4l2_i2c_new_subdev` function will call
|
||||
:c:func:`v4l2_i2c_new_subdev_board`, internally filling a
|
||||
:c:type:`i2c_board_info` structure using the ``client_type`` and the
|
||||
``addr`` to fill it.
|
||||
|
||||
V4L2 sub-device functions and data structures
|
||||
---------------------------------------------
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-subdev.h
|
||||
|
||||
.. kernel-doc:: include/media/v4l2-async.h
|
||||
8
Documentation/driver-api/media/v4l2-tuner.rst
Normal file
8
Documentation/driver-api/media/v4l2-tuner.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Tuner functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/tuner.h
|
||||
|
||||
.. kernel-doc:: include/media/tuner-types.h
|
||||
6
Documentation/driver-api/media/v4l2-tveeprom.rst
Normal file
6
Documentation/driver-api/media/v4l2-tveeprom.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Hauppauge TV EEPROM functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/tveeprom.h
|
||||
406
Documentation/driver-api/media/v4l2-videobuf.rst
Normal file
406
Documentation/driver-api/media/v4l2-videobuf.rst
Normal file
@@ -0,0 +1,406 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. _vb_framework:
|
||||
|
||||
Videobuf Framework
|
||||
==================
|
||||
|
||||
Author: Jonathan Corbet <corbet@lwn.net>
|
||||
|
||||
Current as of 2.6.33
|
||||
|
||||
.. note::
|
||||
|
||||
The videobuf framework was deprecated in favor of videobuf2. Shouldn't
|
||||
be used on new drivers.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The videobuf layer functions as a sort of glue layer between a V4L2 driver
|
||||
and user space. It handles the allocation and management of buffers for
|
||||
the storage of video frames. There is a set of functions which can be used
|
||||
to implement many of the standard POSIX I/O system calls, including read(),
|
||||
poll(), and, happily, mmap(). Another set of functions can be used to
|
||||
implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
|
||||
including buffer allocation, queueing and dequeueing, and streaming
|
||||
control. Using videobuf imposes a few design decisions on the driver
|
||||
author, but the payback comes in the form of reduced code in the driver and
|
||||
a consistent implementation of the V4L2 user-space API.
|
||||
|
||||
Buffer types
|
||||
------------
|
||||
|
||||
Not all video devices use the same kind of buffers. In fact, there are (at
|
||||
least) three common variations:
|
||||
|
||||
- Buffers which are scattered in both the physical and (kernel) virtual
|
||||
address spaces. (Almost) all user-space buffers are like this, but it
|
||||
makes great sense to allocate kernel-space buffers this way as well when
|
||||
it is possible. Unfortunately, it is not always possible; working with
|
||||
this kind of buffer normally requires hardware which can do
|
||||
scatter/gather DMA operations.
|
||||
|
||||
- Buffers which are physically scattered, but which are virtually
|
||||
contiguous; buffers allocated with vmalloc(), in other words. These
|
||||
buffers are just as hard to use for DMA operations, but they can be
|
||||
useful in situations where DMA is not available but virtually-contiguous
|
||||
buffers are convenient.
|
||||
|
||||
- Buffers which are physically contiguous. Allocation of this kind of
|
||||
buffer can be unreliable on fragmented systems, but simpler DMA
|
||||
controllers cannot deal with anything else.
|
||||
|
||||
Videobuf can work with all three types of buffers, but the driver author
|
||||
must pick one at the outset and design the driver around that decision.
|
||||
|
||||
[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
|
||||
which are located within the system's video memory. The overlay
|
||||
functionality is considered to be deprecated for most use, but it still
|
||||
shows up occasionally in system-on-chip drivers where the performance
|
||||
benefits merit the use of this technique. Overlay buffers can be handled
|
||||
as a form of scattered buffer, but there are very few implementations in
|
||||
the kernel and a description of this technique is currently beyond the
|
||||
scope of this document.]
|
||||
|
||||
Data structures, callbacks, and initialization
|
||||
----------------------------------------------
|
||||
|
||||
Depending on which type of buffers are being used, the driver should
|
||||
include one of the following files:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
<media/videobuf-dma-sg.h> /* Physically scattered */
|
||||
<media/videobuf-vmalloc.h> /* vmalloc() buffers */
|
||||
<media/videobuf-dma-contig.h> /* Physically contiguous */
|
||||
|
||||
The driver's data structure describing a V4L2 device should include a
|
||||
struct videobuf_queue instance for the management of the buffer queue,
|
||||
along with a list_head for the queue of available buffers. There will also
|
||||
need to be an interrupt-safe spinlock which is used to protect (at least)
|
||||
the queue.
|
||||
|
||||
The next step is to write four simple callbacks to help videobuf deal with
|
||||
the management of buffers:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct videobuf_queue_ops {
|
||||
int (*buf_setup)(struct videobuf_queue *q,
|
||||
unsigned int *count, unsigned int *size);
|
||||
int (*buf_prepare)(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb,
|
||||
enum v4l2_field field);
|
||||
void (*buf_queue)(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb);
|
||||
void (*buf_release)(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb);
|
||||
};
|
||||
|
||||
buf_setup() is called early in the I/O process, when streaming is being
|
||||
initiated; its purpose is to tell videobuf about the I/O stream. The count
|
||||
parameter will be a suggested number of buffers to use; the driver should
|
||||
check it for rationality and adjust it if need be. As a practical rule, a
|
||||
minimum of two buffers are needed for proper streaming, and there is
|
||||
usually a maximum (which cannot exceed 32) which makes sense for each
|
||||
device. The size parameter should be set to the expected (maximum) size
|
||||
for each frame of data.
|
||||
|
||||
Each buffer (in the form of a struct videobuf_buffer pointer) will be
|
||||
passed to buf_prepare(), which should set the buffer's size, width, height,
|
||||
and field fields properly. If the buffer's state field is
|
||||
VIDEOBUF_NEEDS_INIT, the driver should pass it to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
|
||||
struct v4l2_framebuffer *fbuf);
|
||||
|
||||
Among other things, this call will usually allocate memory for the buffer.
|
||||
Finally, the buf_prepare() function should set the buffer's state to
|
||||
VIDEOBUF_PREPARED.
|
||||
|
||||
When a buffer is queued for I/O, it is passed to buf_queue(), which should
|
||||
put it onto the driver's list of available buffers and set its state to
|
||||
VIDEOBUF_QUEUED. Note that this function is called with the queue spinlock
|
||||
held; if it tries to acquire it as well things will come to a screeching
|
||||
halt. Yes, this is the voice of experience. Note also that videobuf may
|
||||
wait on the first buffer in the queue; placing other buffers in front of it
|
||||
could again gum up the works. So use list_add_tail() to enqueue buffers.
|
||||
|
||||
Finally, buf_release() is called when a buffer is no longer intended to be
|
||||
used. The driver should ensure that there is no I/O active on the buffer,
|
||||
then pass it to the appropriate free routine(s):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
/* Scatter/gather drivers */
|
||||
int videobuf_dma_unmap(struct videobuf_queue *q,
|
||||
struct videobuf_dmabuf *dma);
|
||||
int videobuf_dma_free(struct videobuf_dmabuf *dma);
|
||||
|
||||
/* vmalloc drivers */
|
||||
void videobuf_vmalloc_free (struct videobuf_buffer *buf);
|
||||
|
||||
/* Contiguous drivers */
|
||||
void videobuf_dma_contig_free(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *buf);
|
||||
|
||||
One way to ensure that a buffer is no longer under I/O is to pass it to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
|
||||
|
||||
Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
|
||||
should be used (it should be zero in the buf_release() case), and intr
|
||||
controls whether an interruptible wait is used.
|
||||
|
||||
File operations
|
||||
---------------
|
||||
|
||||
At this point, much of the work is done; much of the rest is slipping
|
||||
videobuf calls into the implementation of the other driver callbacks. The
|
||||
first step is in the open() function, which must initialize the
|
||||
videobuf queue. The function to use depends on the type of buffer used:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
void videobuf_queue_sg_init(struct videobuf_queue *q,
|
||||
struct videobuf_queue_ops *ops,
|
||||
struct device *dev,
|
||||
spinlock_t *irqlock,
|
||||
enum v4l2_buf_type type,
|
||||
enum v4l2_field field,
|
||||
unsigned int msize,
|
||||
void *priv);
|
||||
|
||||
void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
|
||||
struct videobuf_queue_ops *ops,
|
||||
struct device *dev,
|
||||
spinlock_t *irqlock,
|
||||
enum v4l2_buf_type type,
|
||||
enum v4l2_field field,
|
||||
unsigned int msize,
|
||||
void *priv);
|
||||
|
||||
void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
|
||||
struct videobuf_queue_ops *ops,
|
||||
struct device *dev,
|
||||
spinlock_t *irqlock,
|
||||
enum v4l2_buf_type type,
|
||||
enum v4l2_field field,
|
||||
unsigned int msize,
|
||||
void *priv);
|
||||
|
||||
In each case, the parameters are the same: q is the queue structure for the
|
||||
device, ops is the set of callbacks as described above, dev is the device
|
||||
structure for this video device, irqlock is an interrupt-safe spinlock to
|
||||
protect access to the data structures, type is the buffer type used by the
|
||||
device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
|
||||
describes which field is being captured (often V4L2_FIELD_NONE for
|
||||
progressive devices), msize is the size of any containing structure used
|
||||
around struct videobuf_buffer, and priv is a private data pointer which
|
||||
shows up in the priv_data field of struct videobuf_queue. Note that these
|
||||
are void functions which, evidently, are immune to failure.
|
||||
|
||||
V4L2 capture drivers can be written to support either of two APIs: the
|
||||
read() system call and the rather more complicated streaming mechanism. As
|
||||
a general rule, it is necessary to support both to ensure that all
|
||||
applications have a chance of working with the device. Videobuf makes it
|
||||
easy to do that with the same code. To implement read(), the driver need
|
||||
only make a call to one of:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
ssize_t videobuf_read_one(struct videobuf_queue *q,
|
||||
char __user *data, size_t count,
|
||||
loff_t *ppos, int nonblocking);
|
||||
|
||||
ssize_t videobuf_read_stream(struct videobuf_queue *q,
|
||||
char __user *data, size_t count,
|
||||
loff_t *ppos, int vbihack, int nonblocking);
|
||||
|
||||
Either one of these functions will read frame data into data, returning the
|
||||
amount actually read; the difference is that videobuf_read_one() will only
|
||||
read a single frame, while videobuf_read_stream() will read multiple frames
|
||||
if they are needed to satisfy the count requested by the application. A
|
||||
typical driver read() implementation will start the capture engine, call
|
||||
one of the above functions, then stop the engine before returning (though a
|
||||
smarter implementation might leave the engine running for a little while in
|
||||
anticipation of another read() call happening in the near future).
|
||||
|
||||
The poll() function can usually be implemented with a direct call to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
unsigned int videobuf_poll_stream(struct file *file,
|
||||
struct videobuf_queue *q,
|
||||
poll_table *wait);
|
||||
|
||||
Note that the actual wait queue eventually used will be the one associated
|
||||
with the first available buffer.
|
||||
|
||||
When streaming I/O is done to kernel-space buffers, the driver must support
|
||||
the mmap() system call to enable user space to access the data. In many
|
||||
V4L2 drivers, the often-complex mmap() implementation simplifies to a
|
||||
single call to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
int videobuf_mmap_mapper(struct videobuf_queue *q,
|
||||
struct vm_area_struct *vma);
|
||||
|
||||
Everything else is handled by the videobuf code.
|
||||
|
||||
The release() function requires two separate videobuf calls:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
void videobuf_stop(struct videobuf_queue *q);
|
||||
int videobuf_mmap_free(struct videobuf_queue *q);
|
||||
|
||||
The call to videobuf_stop() terminates any I/O in progress - though it is
|
||||
still up to the driver to stop the capture engine. The call to
|
||||
videobuf_mmap_free() will ensure that all buffers have been unmapped; if
|
||||
so, they will all be passed to the buf_release() callback. If buffers
|
||||
remain mapped, videobuf_mmap_free() returns an error code instead. The
|
||||
purpose is clearly to cause the closing of the file descriptor to fail if
|
||||
buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
|
||||
ignores its return value.
|
||||
|
||||
ioctl() operations
|
||||
------------------
|
||||
|
||||
The V4L2 API includes a very long list of driver callbacks to respond to
|
||||
the many ioctl() commands made available to user space. A number of these
|
||||
- those associated with streaming I/O - turn almost directly into videobuf
|
||||
calls. The relevant helper functions are:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
int videobuf_reqbufs(struct videobuf_queue *q,
|
||||
struct v4l2_requestbuffers *req);
|
||||
int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
|
||||
int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b);
|
||||
int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b,
|
||||
int nonblocking);
|
||||
int videobuf_streamon(struct videobuf_queue *q);
|
||||
int videobuf_streamoff(struct videobuf_queue *q);
|
||||
|
||||
So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
|
||||
vidioc_reqbufs() callback which, in turn, usually only needs to locate the
|
||||
proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
|
||||
These support functions can replace a great deal of buffer management
|
||||
boilerplate in a lot of V4L2 drivers.
|
||||
|
||||
The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
|
||||
complex, of course, since they will also need to deal with starting and
|
||||
stopping the capture engine.
|
||||
|
||||
Buffer allocation
|
||||
-----------------
|
||||
|
||||
Thus far, we have talked about buffers, but have not looked at how they are
|
||||
allocated. The scatter/gather case is the most complex on this front. For
|
||||
allocation, the driver can leave buffer allocation entirely up to the
|
||||
videobuf layer; in this case, buffers will be allocated as anonymous
|
||||
user-space pages and will be very scattered indeed. If the application is
|
||||
using user-space buffers, no allocation is needed; the videobuf layer will
|
||||
take care of calling get_user_pages() and filling in the scatterlist array.
|
||||
|
||||
If the driver needs to do its own memory allocation, it should be done in
|
||||
the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The
|
||||
first step is a call to:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
|
||||
|
||||
The returned videobuf_dmabuf structure (defined in
|
||||
<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
struct scatterlist *sglist;
|
||||
int sglen;
|
||||
|
||||
The driver must allocate an appropriately-sized scatterlist array and
|
||||
populate it with pointers to the pieces of the allocated buffer; sglen
|
||||
should be set to the length of the array.
|
||||
|
||||
Drivers using the vmalloc() method need not (and cannot) concern themselves
|
||||
with buffer allocation at all; videobuf will handle those details. The
|
||||
same is normally true of contiguous-DMA drivers as well; videobuf will
|
||||
allocate the buffers (with dma_alloc_coherent()) when it sees fit. That
|
||||
means that these drivers may be trying to do high-order allocations at any
|
||||
time, an operation which is not always guaranteed to work. Some drivers
|
||||
play tricks by allocating DMA space at system boot time; videobuf does not
|
||||
currently play well with those drivers.
|
||||
|
||||
As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
|
||||
as long as that buffer is physically contiguous. Normal user-space
|
||||
allocations will not meet that criterion, but buffers obtained from other
|
||||
kernel drivers, or those contained within huge pages, will work with these
|
||||
drivers.
|
||||
|
||||
Filling the buffers
|
||||
-------------------
|
||||
|
||||
The final part of a videobuf implementation has no direct callback - it's
|
||||
the portion of the code which actually puts frame data into the buffers,
|
||||
usually in response to interrupts from the device. For all types of
|
||||
drivers, this process works approximately as follows:
|
||||
|
||||
- Obtain the next available buffer and make sure that somebody is actually
|
||||
waiting for it.
|
||||
|
||||
- Get a pointer to the memory and put video data there.
|
||||
|
||||
- Mark the buffer as done and wake up the process waiting for it.
|
||||
|
||||
Step (1) above is done by looking at the driver-managed list_head structure
|
||||
- the one which is filled in the buf_queue() callback. Because starting
|
||||
the engine and enqueueing buffers are done in separate steps, it's possible
|
||||
for the engine to be running without any buffers available - in the
|
||||
vmalloc() case especially. So the driver should be prepared for the list
|
||||
to be empty. It is equally possible that nobody is yet interested in the
|
||||
buffer; the driver should not remove it from the list or fill it until a
|
||||
process is waiting on it. That test can be done by examining the buffer's
|
||||
done field (a wait_queue_head_t structure) with waitqueue_active().
|
||||
|
||||
A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
|
||||
DMA; that ensures that the videobuf layer will not try to do anything with
|
||||
it while the device is transferring data.
|
||||
|
||||
For scatter/gather drivers, the needed memory pointers will be found in the
|
||||
scatterlist structure described above. Drivers using the vmalloc() method
|
||||
can get a memory pointer with:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
|
||||
|
||||
For contiguous DMA drivers, the function to use is:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
|
||||
|
||||
The contiguous DMA API goes out of its way to hide the kernel-space address
|
||||
of the DMA buffer from drivers.
|
||||
|
||||
The final step is to set the size field of the relevant videobuf_buffer
|
||||
structure to the actual size of the captured image, set state to
|
||||
VIDEOBUF_DONE, then call wake_up() on the done queue. At this point, the
|
||||
buffer is owned by the videobuf layer and the driver should not touch it
|
||||
again.
|
||||
|
||||
Developers who are interested in more information can go into the relevant
|
||||
header files; there are a few low-level functions declared there which have
|
||||
not been talked about here. Also worthwhile is the vivi driver
|
||||
(drivers/media/platform/vivi.c), which is maintained as an example of how V4L2
|
||||
drivers should be written. Vivi only uses the vmalloc() API, but it's good
|
||||
enough to get started with. Note also that all of these calls are exported
|
||||
GPL-only, so they will not be available to non-GPL kernel modules.
|
||||
12
Documentation/driver-api/media/v4l2-videobuf2.rst
Normal file
12
Documentation/driver-api/media/v4l2-videobuf2.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. _vb2_framework:
|
||||
|
||||
V4L2 videobuf2 functions and data structures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. kernel-doc:: include/media/videobuf2-core.h
|
||||
|
||||
.. kernel-doc:: include/media/videobuf2-v4l2.h
|
||||
|
||||
.. kernel-doc:: include/media/videobuf2-memops.h
|
||||
Reference in New Issue
Block a user