Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,158 @@
.. SPDX-License-Identifier: GPL-2.0
.. _media_writing_camera_sensor_drivers:
Writing camera sensor drivers
=============================
This document covers the in-kernel APIs only. For the best practices on
userspace API implementation in camera sensor drivers, please see
:ref:`media_using_camera_sensor_drivers`.
CSI-2, parallel and BT.656 buses
--------------------------------
Please see :ref:`transmitter-receiver`.
Handling clocks
---------------
Camera sensors have an internal clock tree including a PLL and a number of
divisors. The clock tree is generally configured by the driver based on a few
input parameters that are specific to the hardware: the external clock frequency
and the link frequency. The two parameters generally are obtained from system
firmware. **No other frequencies should be used in any circumstances.**
The reason why the clock frequencies are so important is that the clock signals
come out of the SoC, and in many cases a specific frequency is designed to be
used in the system. Using another frequency may cause harmful effects
elsewhere. Therefore only the pre-determined frequencies are configurable by the
user.
The external clock frequency shall be retrieved by obtaining the external clock
using the ``devm_v4l2_sensor_clk_get()`` helper function, and then getting its
frequency with ``clk_get_rate()``. Usage of the helper function guarantees
correct behaviour regardless of whether the sensor is integrated in a DT-based
or ACPI-based system.
ACPI
~~~~
ACPI-based systems typically don't register the sensor external clock with the
kernel, but specify the external clock frequency in the ``clock-frequency``
_DSD property. The ``devm_v4l2_sensor_clk_get()`` helper creates and returns a
fixed clock set at that rate.
Devicetree
~~~~~~~~~~
Devicetree-based systems declare the sensor external clock in the device tree
and reference it from the sensor node. The preferred way to select the external
clock frequency is to use the ``assigned-clocks``, ``assigned-clock-parents``
and ``assigned-clock-rates`` properties in the sensor node to set the clock
rate. See the `clock device tree bindings
<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_
for more information. The ``devm_v4l2_sensor_clk_get()`` helper retrieves and
returns that clock.
This approach has the drawback that there's no guarantee that the frequency
hasn't been modified directly or indirectly by another driver, or supported by
the board's clock tree to begin with. Changes to the Common Clock Framework API
are required to ensure reliability.
Power management
----------------
Camera sensors are used in conjunction with other devices to form a camera
pipeline. They must obey the rules listed herein to ensure coherent power
management over the pipeline.
Camera sensor drivers are responsible for controlling the power state of the
device they otherwise control as well. They shall use runtime PM to manage
power states. Runtime PM shall be enabled at probe time and disabled at remove
time. Drivers should enable runtime PM autosuspend. Also see
:ref:`async sub-device registration <media-registering-async-subdevs>`.
The runtime PM handlers shall handle clocks, regulators, GPIOs, and other
system resources required to power the sensor up and down. For drivers that
don't use any of those resources (such as drivers that support ACPI systems
only), the runtime PM handlers may be left unimplemented.
In general, the device shall be powered on at least when its registers are
being accessed and when it is streaming. Drivers should use
``pm_runtime_resume_and_get()`` when starting streaming and
``pm_runtime_put()`` or ``pm_runtime_put_autosuspend()`` when stopping
streaming. They may power the device up at probe time (for example to read
identification registers), but should not keep it powered unconditionally after
probe.
At system suspend time, the whole camera pipeline must stop streaming, and
restart when the system is resumed. This requires coordination between the
camera sensor and the rest of the camera pipeline. Bridge drivers are
responsible for this coordination, and instruct camera sensors to stop and
restart streaming by calling the appropriate subdev operations
(``.enable_streams()`` or ``.disable_streams()``). Camera sensor drivers shall
therefore **not** keep track of the streaming state to stop streaming in the PM
suspend handler and restart it in the resume handler. Drivers should in general
not implement the system PM handlers.
Camera sensor drivers shall **not** implement the subdev ``.s_power()``
operation, as it is deprecated. While this operation is implemented in some
existing drivers as they predate the deprecation, new drivers shall use runtime
PM instead. If you feel you need to begin calling ``.s_power()`` from an ISP or
a bridge driver, instead add runtime PM support to the sensor driver you are
using and drop its ``.s_power()`` handler.
Please also see :ref:`examples <media-camera-sensor-examples>`.
Control framework
~~~~~~~~~~~~~~~~~
``v4l2_ctrl_handler_setup()`` function may not be used in the device's runtime
PM ``runtime_resume`` callback, as it has no way to figure out the power state
of the device. This is because the power state of the device is only changed
after the power state transition has taken place. The ``s_ctrl`` callback can be
used to obtain device's power state after the power state transition:
.. c:function:: int pm_runtime_get_if_active(struct device *dev);
The function returns a non-zero value if it succeeded getting the power count or
runtime PM was disabled, in either of which cases the driver may proceed to
access the device.
Rotation, orientation and flipping
----------------------------------
Use ``v4l2_fwnode_device_parse()`` to obtain rotation and orientation
information from system firmware and ``v4l2_ctrl_new_fwnode_properties()`` to
register the appropriate controls.
.. _media-camera-sensor-examples:
Example drivers
---------------
Features implemented by sensor drivers vary, and depending on the set of
supported features and other qualities, particular sensor drivers better serve
the purpose of an example. The following drivers are known to be good examples:
.. flat-table:: Example sensor drivers
:header-rows: 0
:widths: 1 1 1 2
* - Driver name
- File(s)
- Driver type
- Example topic
* - CCS
- ``drivers/media/i2c/ccs/``
- Freely configurable
- Power management (ACPI and DT), UAPI
* - imx219
- ``drivers/media/i2c/imx219.c``
- Register list based
- Power management (DT), UAPI, mode selection
* - imx319
- ``drivers/media/i2c/imx319.c``
- Register list based
- Power management (ACPI and DT)
@@ -0,0 +1,502 @@
.. 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:
https://www.hdmi.org/spec/index
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: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);
void (*adap_unconfigured)(struct cec_adapter *adap);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
const 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 callback */
...
};
These low-level ops deal with various aspects of controlling the CEC adapter
hardware. They are all called with the mutex adap->lock held.
To enable/disable the hardware::
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. The
physical address will always be valid if CEC_CAP_NEEDS_HPD is set. If that
capability is not set, then the physical address can change while the CEC
hardware is enabled. CEC drivers should not set CEC_CAP_NEEDS_HPD unless
the hardware design requires that as this will make it impossible to wake
up displays that pull the HPD low when in standby mode. 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::
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 are 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::
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::
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.
Called when the adapter is unconfigured::
void (*adap_unconfigured)(struct cec_adapter *adap);
The adapter is unconfigured. If the driver has to take specific actions after
unconfiguration, then that can be done through this optional callback.
To transmit a new message::
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 pass on the result of a canceled non-blocking transmit::
void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
const struct cec_msg *msg);
This optional callback can be used to obtain the result of a canceled
non-blocking transmit with sequence number msg->sequence. This is
called if the transmit was aborted, the transmit timed out (i.e. the
hardware never signaled that the transmit finished), or the transmit
was successful, but the wait for the expected reply was either aborted
or it timed out.
To log the current CEC hardware status::
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::
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)::
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::
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
current error injection state::
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::
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 high-level callbacks are called without the adap->lock
mutex being held. 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 */
void (*configured)(struct cec_adapter *adap);
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
};
Called when the adapter is configured::
void (*configured)(struct cec_adapter *adap);
The adapter is fully configured, i.e. all logical addresses have been
successfully claimed. If the driver has to take specific actions after
configuration, then that can be done through this optional callback.
The received() callback allows the driver to optionally handle a newly
received CEC message::
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
@@ -0,0 +1,116 @@
.. SPDX-License-Identifier: GPL-2.0
The bttv driver
===============
bttv and sound mini howto
-------------------------
There are a lot of different bt848/849/878/879 based boards available.
Making video work often is not a big deal, because this is handled
completely by the bt8xx chip, which is common on all boards. But
sound is handled in slightly different ways on each board.
To handle the grabber boards correctly, there is a array tvcards[] in
bttv-cards.c, which holds the information required for each board.
Sound will work only, if the correct entry is used (for video it often
makes no difference). The bttv driver prints a line to the kernel
log, telling which card type is used. Like this one::
bttv0: model: BT848(Hauppauge old) [autodetected]
You should verify this is correct. If it isn't, you have to pass the
correct board type as insmod argument, ``insmod bttv card=2`` for
example. The file Documentation/admin-guide/media/bttv-cardlist.rst has a list
of valid arguments for card.
If your card isn't listed there, you might check the source code for
new entries which are not listed yet. If there isn't one for your
card, you can check if one of the existing entries does work for you
(just trial and error...).
Some boards have an extra processor for sound to do stereo decoding
and other nice features. The msp34xx chips are used by Hauppauge for
example. If your board has one, you might have to load a helper
module like ``msp3400`` to make sound work. If there isn't one for the
chip used on your board: Bad luck. Start writing a new one. Well,
you might want to check the video4linux mailing list archive first...
Of course you need a correctly installed soundcard unless you have the
speakers connected directly to the grabber board. Hint: check the
mixer settings too. ALSA for example has everything muted by default.
How sound works in detail
~~~~~~~~~~~~~~~~~~~~~~~~~
Still doesn't work? Looks like some driver hacking is required.
Below is a do-it-yourself description for you.
The bt8xx chips have 32 general purpose pins, and registers to control
these pins. One register is the output enable register
(``BT848_GPIO_OUT_EN``), it says which pins are actively driven by the
bt848 chip. Another one is the data register (``BT848_GPIO_DATA``), where
you can get/set the status if these pins. They can be used for input
and output.
Most grabber board vendors use these pins to control an external chip
which does the sound routing. But every board is a little different.
These pins are also used by some companies to drive remote control
receiver chips. Some boards use the i2c bus instead of the gpio pins
to connect the mux chip.
As mentioned above, there is a array which holds the required
information for each known board. You basically have to create a new
line for your board. The important fields are these two::
struct tvcard
{
[ ... ]
u32 gpiomask;
u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
};
gpiomask specifies which pins are used to control the audio mux chip.
The corresponding bits in the output enable register
(``BT848_GPIO_OUT_EN``) will be set as these pins must be driven by the
bt848 chip.
The ``audiomux[]`` array holds the data values for the different inputs
(i.e. which pins must be high/low for tuner/mute/...). This will be
written to the data register (``BT848_GPIO_DATA``) to switch the audio
mux.
What you have to do is figure out the correct values for gpiomask and
the audiomux array. If you have Windows and the drivers four your
card installed, you might to check out if you can read these registers
values used by the windows driver. A tool to do this is available
from http://btwincap.sourceforge.net/download.html.
You might also dig around in the ``*.ini`` files of the Windows applications.
You can have a look at the board to see which of the gpio pins are
connected at all and then start trial-and-error ...
Starting with release 0.7.41 bttv has a number of insmod options to
make the gpio debugging easier:
================= ==============================================
bttv_gpio=0/1 enable/disable gpio debug messages
gpiomask=n set the gpiomask value
audiomux=i,j,... set the values of the audiomux array
audioall=a set the values of the audiomux array (one
value for all array elements, useful to check
out which effect the particular value has).
================= ==============================================
The messages printed with ``bttv_gpio=1`` look like this::
bttv0: gpio: en=00000027, out=00000024 in=00ffffd8 [audio: off]
en = output _en_able register (BT848_GPIO_OUT_EN)
out = _out_put bits of the data register (BT848_GPIO_DATA),
i.e. BT848_GPIO_DATA & BT848_GPIO_OUT_EN
in = _in_put bits of the data register,
i.e. BT848_GPIO_DATA & ~BT848_GPIO_OUT_EN
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
.. SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
.. include:: <isonum.txt>
.. _media-ccs-driver:
MIPI CCS camera sensor driver
=============================
The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS
<https://www.mipi.org/specifications/camera-command-set>`_ compliant
camera sensors.
Also see :ref:`the CCS driver UAPI documentation <media-ccs-uapi>`.
CCS static data
---------------
The MIPI CCS driver supports CCS static data for all compliant devices,
including not just those compliant with CCS 1.1 but also CCS 1.0 and SMIA(++).
For CCS the file names are formed as
ccs/ccs-sensor-vvvv-mmmm-rrrr.fw (sensor) and
ccs/ccs-module-vvvv-mmmm-rrrr.fw (module).
For SMIA++ compliant devices the corresponding file names are
ccs/smiapp-sensor-vv-mmmm-rr.fw (sensor) and
ccs/smiapp-module-vv-mmmm-rrrr.fw (module).
For SMIA (non-++) compliant devices the static data file name is
ccs/smia-sensor-vv-mmmm-rr.fw (sensor).
vvvv or vv denotes MIPI and SMIA manufacturer IDs respectively, mmmm model ID
and rrrr or rr revision number.
CCS tools
~~~~~~~~~
`CCS tools <https://github.com/MIPI-Alliance/ccs-tools/>`_ is a set of
tools for working with CCS static data files. CCS tools includes a
definition of the human-readable CCS static data YAML format and includes a
program to convert it to a binary.
Register definition generator
-----------------------------
The ccs-regs.asc file contains MIPI CCS register definitions that are used
to produce C source code files for definitions that can be better used by
programs written in C language. As there are many dependencies between the
produced files, please do not modify them manually as it's error-prone and
in vain, but instead change the script producing them.
Usage
~~~~~
Conventionally the script is called this way to update the CCS driver
definitions:
.. code-block:: none
$ Documentation/driver-api/media/drivers/ccs/mk-ccs-regs -k \
-e drivers/media/i2c/ccs/ccs-regs.h \
-L drivers/media/i2c/ccs/ccs-limits.h \
-l drivers/media/i2c/ccs/ccs-limits.c \
-c Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
CCS PLL calculator
==================
The CCS PLL calculator is used to compute the PLL configuration, given sensor's
capabilities as well as board configuration and user specified configuration. As
the configuration space that encompasses all these configurations is vast, the
PLL calculator isn't entirely trivial. Yet it is relatively simple to use for a
driver.
The PLL model implemented by the PLL calculator corresponds to MIPI CCS 1.1.
.. kernel-doc:: drivers/media/i2c/ccs-pll.h
**Copyright** |copy| 2020 Intel Corporation
@@ -0,0 +1,480 @@
#!/usr/bin/perl -w
# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
# Copyright (C) 2019--2020 Intel Corporation
use Getopt::Long qw(:config no_ignore_case);
use File::Basename;
my $ccsregs = "ccs-regs.asc";
my $header;
my $regarray;
my $limitc;
my $limith;
my $kernel;
my $help;
GetOptions("ccsregs|c=s" => \$ccsregs,
"header|e=s" => \$header,
"regarray|r=s" => \$regarray,
"limitc|l=s" => \$limitc,
"limith|L=s" => \$limith,
"kernel|k" => \$kernel,
"help|h" => \$help) or die "can't parse options";
$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;
if (defined $help) {
print <<EOH
$0 - Create CCS register definitions for C
usage: $0 -c ccs-regs.asc -e header -r regarray -l limit-c -L limit-header [-k]
-c ccs register file
-e header file name
-r register description array file name
-l limit and capability array file name
-L limit and capability header file name
-k generate files for kernel space consumption
EOH
;
exit 0;
}
my $lh_hdr = ! defined $kernel
? '#include "ccs-os.h"' . "\n"
: "#include <linux/bits.h>\n#include <linux/types.h>\n";
my $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
my $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';
open(my $R, "< $ccsregs") or die "can't open $ccsregs";
open(my $H, "> $header") or die "can't open $header";
my $A;
if (defined $regarray) {
open($A, "> $regarray") or die "can't open $regarray";
}
open(my $LC, "> $limitc") or die "can't open $limitc";
open(my $LH, "> $limith") or die "can't open $limith";
my %this;
sub is_limit_reg($) {
my $addr = hex $_[0];
return 0 if $addr < 0x40; # weed out status registers
return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers
return 1;
}
my $uc_header = basename uc $header;
$uc_header =~ s/[^A-Z0-9]/_/g;
my $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
my $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
my $note = "/*\n * Generated by $0;\n * do not modify.\n */\n";
for my $fh ($A, $LC) {
print $fh "// $license\n$copyright$note\n" if defined $fh;
}
for my $fh ($H, $LH) {
print $fh "/* $license */\n$copyright$note\n";
}
print $H <<EOF
#ifndef __${uc_header}__
#define __${uc_header}__
EOF
;
print $H <<EOF
#include <linux/bits.h>
#include <media/v4l2-cci.h>
EOF
if defined $kernel;
print $H "#define CCS_FL_BASE " .
(defined $kernel ? "CCI_REG_PRIVATE_SHIFT" : 16) . "\n";
my $flag = -1;
my $all_flags;
sub bit_def($) {
my $bit = shift @_;
if (defined $kernel) {
return "BIT$bit" if $bit =~ /^\(.*\)$/;
return "BIT($bit)";
}
return "(1U << $bit)";
}
sub flag_str($$) {
my ($flag, $check) = @_;
$$flag++;
my $flag_str = !$$flag ? "CCS_FL_BASE" : "(CCS_FL_BASE + $$flag)";
$flag_str = bit_def($flag_str);
$$check .= " | " if defined $$check;
$$check .= $flag_str;
return $flag_str;
}
if (! defined $kernel) {
print $H "#define CCS_FL_16BIT " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_FL_32BIT " . flag_str(\$flag, \$all_flags) . "\n";
}
print $H "#define CCS_FL_FLOAT_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_FL_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_BUILD_BUG \\
BUILD_BUG_ON(~CCI_REG_PRIVATE_MASK & ($all_flags))\n"
if defined $kernel;
print $H <<EOF
#define CCS_R_ADDR(r) ((r) & 0xffff)
EOF
if ! defined $kernel;
print $A <<EOF
#include <stdint.h>
#include <stdio.h>
#include "ccs-extra.h"
#include "ccs-regs.h"
EOF
if defined $A;
my $uc_limith = basename uc $limith;
$uc_limith =~ s/[^A-Z0-9]/_/g;
print $LH <<EOF
#ifndef __${uc_limith}__
#define __${uc_limith}__
$lh_hdr
struct ccs_limit {
$uint32_t reg;
$uint16_t size;
$uint16_t flags;
const char *name;
};
EOF
;
print $LH "#define CCS_L_FL_SAME_REG " . bit_def(0) . "\n\n";
print $LH <<EOF
extern const struct ccs_limit ccs_limits[];
EOF
;
print $LC <<EOF
#include "ccs-limits.h"
#include "ccs-regs.h"
const struct ccs_limit ccs_limits[] = {
EOF
;
my $limitcount = 0;
my $argdescs;
my $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";
sub name_split($$) {
my ($name, $addr) = @_;
my $args;
$name =~ /([^\(]+?)(\(.*)/;
($name, $args) = ($1, $2);
$args = [split /,\s*/, $args];
foreach my $t (@$args) {
$t =~ s/[\(\)]//g;
$t =~ s/\//\\\//g;
}
return ($name, $addr, $args);
}
sub tabconv($) {
$_ = shift;
my @l = split "\n", $_;
map {
s/ {8,8}/\t/g;
s/\t\K +//;
} @l;
return (join "\n", @l) . "\n";
}
sub elem_bits(@) {
my @flags = @_;
return 16 if grep /^16$/, @flags;
return 32 if grep /^32$/, @flags;
return 8;
}
sub arr_size($) {
my $this = $_[0];
my $size = $this->{elsize};
my $h = $this->{argparams};
foreach my $arg (@{$this->{args}}) {
my $apref = $h->{$arg};
$size *= $apref->{max} - $apref->{min} + 1;
}
return $size;
}
sub print_args($$$) {
my ($this, $postfix, $is_same_reg) = @_;
my ($args, $argparams, $name) =
($this->{args}, $this->{argparams}, $this->{name});
my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
my @mins;
my @sorted_args = @{$this->{sorted_args}};
my $lim_arg;
my $size = arr_size($this);
$argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";
foreach my $sorted_arg (@sorted_args) {
push @mins, $argparams->{$sorted_arg}->{min};
}
foreach my $sorted_arg (@sorted_args) {
my $h = $argparams->{$sorted_arg};
$argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";
$lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
}
$argdescs .= "};\n\n";
$reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
"), $size, sizeof($varname) / sizeof(*$varname)," .
" \"" . (lc $name) . "\", $varname },\n";
print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
$size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
if is_limit_reg $this->{base_addr};
}
my $hdr_data;
while (<$R>) {
chop;
s/^\s*//;
next if /^[#;]/ || /^$/;
if (s/^-\s*//) {
if (s/^b\s*//) {
my ($bit, $addr) = split /\t+/;
$bit = uc $bit;
$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
} elsif (s/^f\s*//) {
s/[,\.-]/_/g;
my @a = split /\s+/;
my ($msb, $lsb, $this_field) = reverse @a;
@a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
{ "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
$this{"field"} = $this_field;
foreach my $ar (@a) {
#print $ar->{fmt}."\n";
$hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
}
} elsif (s/^e\s*//) {
s/[,\.-]/_/g;
my ($enum, $addr) = split /\s+/;
$enum = uc $enum;
$hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
} elsif (s/^l\s*//) {
my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
my $size;
foreach my $num ($min, $max) {
$num = hex $num if $num =~ /0x/i;
}
$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
$hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";
my $h = $this{argparams};
$h->{$arg} = { "min" => $min,
"max" => $max,
"elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
"discontig" => \@discontig };
$this{discontig} = $arg if @discontig;
next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
my $reg_formula = "$this{addr}";
my $lim_formula;
chop $reg_formula;
$reg_formula = "(" . $reg_formula if $this{flagstring} ne "";
foreach my $arg (@{$this{args}}) {
my $d = $h->{$arg}->{discontig};
my $times = $h->{$arg}->{elsize} != 1 ?
" * " . $h->{$arg}->{elsize} : "";
if (@$d) {
my ($lim, $offset) = split /,/, $d->[0];
$reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
} else {
$reg_formula .= " + ($arg)$times";
}
$lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
}
$reg_formula .= ")";
$lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
$this{arglist}, $reg_formula .
(($this{flagstring} eq "") ? "" :
" | " . $this{flagstring} . ")") . "\n");
print $H tabconv $hdr_data;
undef $hdr_data;
# Sort arguments in descending order by size
@{$this{sorted_args}} = sort {
$h->{$a}->{elsize} <= $h->{$b}->{elsize}
} @{$this{args}};
if (defined $this{discontig}) {
my $da = $this{argparams}->{$this{discontig}};
my ($first_discontig) = split /,/, $da->{discontig}->[0];
my $max = $da->{max};
$da->{max} = $first_discontig - 1;
print_args(\%this, "", 0);
$da->{min} = $da->{max} + 1;
$da->{max} = $max;
print_args(\%this, $first_discontig, 1);
} else {
print_args(\%this, "", 0);
}
next unless is_limit_reg $this{base_addr};
print $LH tabconv sprintf "#define %-63s%s\n",
"CCS_L_" . (uc $this{name}) . "_OFFSET(" .
(join ", ", @{$this{args}}) . ")", "($lim_formula)";
}
if (! @{$this{args}}) {
print $H tabconv($hdr_data);
undef $hdr_data;
}
next;
}
my ($name, $addr, @flags) = split /\t+/, $_;
my $args = [];
my $sp;
($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;
$name =~ s/[,\.-]/_/g;
my $flagstring = "";
my $bits = elem_bits(@flags);
if (! defined $kernel) {
$flagstring .= "| CCS_FL_16BIT " if $bits == 16;
$flagstring .= "| CCS_FL_32BIT " if $bits == 32;
}
$flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
$flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
$flagstring =~ s/^\| //;
$flagstring =~ s/ $//;
$flagstring = "($flagstring)" if $flagstring =~ /\|/;
my $base_addr = $addr;
$addr = "CCI_REG$bits($addr)" if defined $kernel;
if ($flagstring ne "" && !@$args) {
$addr = "($addr | $flagstring)";
$flagstring = "";
}
my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
$hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
if !@$args;
$name =~ s/\(.*//;
%this = ( name => $name,
addr => $addr,
flagstring => $flagstring,
base_addr => $base_addr,
argparams => {},
args => $args,
arglist => $arglist,
elsize => $bits / 8,
);
if (!@$args) {
$reglist .= "\t{ CCS_R_" . (uc $name) . ", 1, 0, \"" . (lc $name) . "\", NULL },\n";
print $H tabconv $hdr_data;
undef $hdr_data;
print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
$this{elsize} . ", 0, \"$name\" },\n"
if is_limit_reg $this{base_addr};
}
print $LH tabconv sprintf "#define %-63s%s\n",
"CCS_L_" . (uc $this{name}), $limitcount++
if is_limit_reg $this{base_addr};
}
if (defined $A) {
print $A $argdescs, $reglist;
print $A "\t{ 0 }\n";
print $A "};\n";
}
print $H "\n#endif /* __${uc_header}__ */\n";
print $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;
print $LH "\n#endif /* __${uc_limith}__ */\n";
print $LC "\t{ 0 } /* Guardian */\n";
print $LC "};\n";
close($R);
close($H);
close($A) if defined $A;
close($LC);
close($LH);
@@ -0,0 +1,131 @@
.. SPDX-License-Identifier: GPL-2.0
Contributors
============
.. note::
This documentation is outdated. There are several other DVB contributors
that aren't listed below.
Thanks go to the following people for patches and contributions:
- Michael Hunold <m.hunold@gmx.de>
- for the initial saa7146 driver and its recent overhaul
- Christian Theiss
- for his work on the initial Linux DVB driver
- Marcus Metzler <mocm@metzlerbros.de> and
Ralph Metzler <rjkm@metzlerbros.de>
- for their continuing work on the DVB driver
- Michael Holzt <kju@debian.org>
- for his contributions to the dvb-net driver
- Diego Picciani <d.picciani@novacomp.it>
- for CyberLogin for Linux which allows logging onto EON
(in case you are wondering where CyberLogin is, EON changed its login
procedure and CyberLogin is no longer used.)
- Martin Schaller <martin@smurf.franken.de>
- for patching the cable card decoder driver
- Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>
- for various fixes regarding tuning, OSD and CI stuff and his work on VDR
- Steve Brown <sbrown@cortland.com>
- for his AFC kernel thread
- Christoph Martin <martin@uni-mainz.de>
- for his LIRC infrared handler
- Andreas Oberritter <obi@linuxtv.org>,
Dennis Noermann <dennis.noermann@noernet.de>,
Felix Domke <tmbinc@elitedvb.net>,
Florian Schirmer <jolt@tuxbox.org>,
Ronny Strutz <3des@elitedvb.de>,
Wolfram Joost <dbox2@frokaschwei.de>
and all the other dbox2 people
- for many bugfixes in the generic DVB Core, frontend drivers and
their work on the dbox2 port of the DVB driver
- Oliver Endriss <o.endriss@gmx.de>
- for many bugfixes
- Andrew de Quincey <adq_dvb@lidskialf.net>
- for the tda1004x frontend driver, and various bugfixes
- Peter Schildmann <peter.schildmann@web.de>
- for the driver for the Technisat SkyStar2 PCI DVB card
- Vadim Catana <skystar@moldova.cc>,
Roberto Ragusa <r.ragusa@libero.it> and
Augusto Cardoso <augusto@carhil.net>
- for all the work for the FlexCopII chipset by B2C2,Inc.
- Davor Emard <emard@softhome.net>
- for his work on the budget drivers, the demux code,
the module unloading problems, ...
- Hans-Frieder Vogt <hfvogt@arcor.de>
- for his work on calculating and checking the crc's for the
TechnoTrend/Hauppauge DEC driver firmware
- Michael Dreher <michael@5dot1.de> and
Andreas 'randy' Weinberger
- for the support of the Fujitsu-Siemens Activy budget DVB-S
- Kenneth Aafløy <ke-aa@frisurf.no>
- for adding support for Typhoon DVB-S budget card
- Ernst Peinlich <e.peinlich@inode.at>
- for tuning/DiSEqC support for the DEC 3000-s
- Peter Beutner <p.beutner@gmx.net>
- for the IR code for the ttusb-dec driver
- Wilson Michaels <wilsonmichaels@earthlink.net>
- for the lgdt330x frontend driver, and various bugfixes
- Michael Krufky <mkrufky@linuxtv.org>
- for maintaining v4l/dvb inter-tree dependencies
- Taylor Jacob <rtjacob@earthlink.net>
- for the nxt2002 frontend driver
- Jean-Francois Thibert <jeanfrancois@sagetv.com>
- for the nxt2004 frontend driver
- Kirk Lapray <kirk.lapray@gmail.com>
- for the or51211 and or51132 frontend drivers, and
for merging the nxt2002 and nxt2004 modules into a
single nxt200x frontend driver.
(If you think you should be in this list, but you are not, drop a
line to the DVB mailing list)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,113 @@
.. SPDX-License-Identifier: GPL-2.0
The cx88 driver
===============
Author: Gerd Hoffmann
Documentation missing at the cx88 datasheet
-------------------------------------------
MO_OUTPUT_FORMAT (0x310164)
.. code-block:: none
Previous default from DScaler: 0x1c1f0008
Digit 8: 31-28
28: PREVREMOD = 1
Digit 7: 27-24 (0xc = 12 = b1100 )
27: COMBALT = 1
26: PAL_INV_PHASE
(DScaler apparently set this to 1, resulted in sucky picture)
Digits 6,5: 23-16
25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
Digit 4: 15-12
15: DISIFX = 0
14: INVCBF = 0
13: DISADAPT = 0
12: NARROWADAPT = 0
Digit 3: 11-8
11: FORCE2H
10: FORCEREMD
9: NCHROMAEN
8: NREMODEN
Digit 2: 7-4
7-6: YCORE
5-4: CCORE
Digit 1: 3-0
3: RANGE = 1
2: HACTEXT
1: HSFMT
0x47 is the sync byte for MPEG-2 transport stream packets.
Datasheet incorrectly states to use 47 decimal. 188 is the length.
All DVB compliant frontends output packets with this start code.
Hauppauge WinTV cx88 IR information
-----------------------------------
The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
====== ======== =================================================
GPIO0 GPIO1
====== ======== =================================================
0 0 TV Audio
1 0 FM radio
0 1 Line-In
1 1 Mono tuner bypass or CD passthru (tuner specific)
====== ======== =================================================
GPIO 16(I believe) is tied to the IR port (if present).
From the data sheet:
- Register 24'h20004 PCI Interrupt Status
- bit [18] IR_SMP_INT Set when 32 input samples have been collected over
- gpio[16] pin into GP_SAMPLE register.
What's missing from the data sheet:
- Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
compat remote)
- set register 0x35C050 to 0xa80a80
- enable sampling
- set register 0x35C054 to 0x5
- enable the IRQ bit 18 in the interrupt mask register (and
provide for a handler)
GP_SAMPLE register is at 0x35C058
Bits are then right shifted into the GP_SAMPLE register at the specified
rate; you get an interrupt when a full DWORD is received.
You need to recover the actual RC5 bits out of the (oversampled) IR sensor
bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data) An
actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
I'm pretty sure when no IR signal is present the receiver is always in a
marking state(1); but stray light, etc can cause intermittent noise values
as well. Remember, this is a free running sample of the IR receiver state
over time, so don't assume any sample starts at any particular place.
Additional info
~~~~~~~~~~~~~~~
This data sheet (google search) seems to have a lovely description of the
RC5 basics:
http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
This document has more data:
http://www.nenya.be/beor/electronics/rc5.htm
This document has a how to decode a bi-phase data stream:
http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
This document has still more info:
http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
@@ -0,0 +1,357 @@
.. SPDX-License-Identifier: GPL-2.0
Idea behind the dvb-usb-framework
=================================
.. note::
#) This documentation is outdated. Please check at the DVB wiki
at https://linuxtv.org/wiki for more updated info.
#) **deprecated:** Newer DVB USB drivers should use the dvb-usb-v2 framework.
In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs
and a firmware.
Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
After reading some specs and doing some USB snooping, it realized, that the
dibusb-driver would be a complete mess afterwards. So I decided to do it in a
different way: With the help of a dvb-usb-framework.
The framework provides generic functions (mostly kernel API calls), such as:
- Transport Stream URB handling in conjunction with dvb-demux-feed-control
(bulk and isoc are supported)
- registering the device for the DVB-API
- registering an I2C-adapter if applicable
- remote-control/input-device handling
- firmware requesting and loading (currently just for the Cypress USB
controllers)
- other functions/methods which can be shared by several drivers (such as
functions for bulk-control-commands)
- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
depending on length of a register and the number of values that can be
multi-written and multi-read.
The source code of the particular DVB USB devices does just the communication
with the device via the bus. The connection between the DVB-API-functionality
is done via callbacks, assigned in a static device-description (struct
dvb_usb_device) each device-driver has to have.
For an example have a look in drivers/media/usb/dvb-usb/vp7045*.
Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
the dvb-usb-lib.
TODO: dynamic enabling and disabling of the pid-filter in regard to number of
feeds requested.
Supported devices
-----------------
See the LinuxTV DVB Wiki at https://linuxtv.org for a complete list of
cards/drivers/firmwares:
https://linuxtv.org/wiki/index.php/DVB_USB
0. History & News:
2005-06-30
- added support for WideView WT-220U (Thanks to Steve Chang)
2005-05-30
- added basic isochronous support to the dvb-usb-framework
- added support for Conexant Hybrid reference design and Nebula
DigiTV USB
2005-04-17
- all dibusb devices ported to make use of the dvb-usb-framework
2005-04-02
- re-enabled and improved remote control code.
2005-03-31
- ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
2005-03-30
- first commit of the dvb-usb-module based on the dibusb-source.
First device is a new driver for the
TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
- (change from dvb-dibusb to dvb-usb)
2005-03-28
- added support for the AVerMedia AverTV DVB-T USB2.0 device
(Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
2005-03-14
- added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
2005-02-11
- added support for the KWorld/ADSTech Instant DVB-T USB2.0.
Thanks a lot to Joachim von Caron
2005-02-02
- added support for the Hauppauge Win-TV Nova-T USB2
2005-01-31
- distorted streaming is gone for USB1.1 devices
2005-01-13
- moved the mirrored pid_filter_table back to dvb-dibusb
first almost working version for HanfTek UMT-010
found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
2005-01-10
- refactoring completed, now everything is very delightful
- tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
Panasonic Tuner assembled). Tunerprobing implemented.
Thanks a lot to Gunnar Wittich.
2004-12-29
- after several days of struggling around bug of no returning URBs fixed.
2004-12-26
- refactored the dibusb-driver, split into separate files
- i2c-probing enabled
2004-12-06
- possibility for demod i2c-address probing
- new usb IDs (Compro, Artec)
2004-11-23
- merged changes from DiB3000MC_ver2.1
- revised the debugging
- possibility to deliver the complete TS for USB2.0
2004-11-21
- first working version of the dib3000mc/p frontend driver.
2004-11-12
- added additional remote control keys. Thanks to Uwe Hanke.
2004-11-07
- added remote control support. Thanks to David Matthews.
2004-11-05
- added support for a new devices (Grandtec/Avermedia/Artec)
- merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
- moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
better settled there (added xfer_ops-struct)
- created a common files for frontends (mc/p/mb)
2004-09-28
- added support for a new device (Unknown, vendor ID is Hyper-Paltek)
2004-09-20
- added support for a new device (Compro DVB-U2000), thanks
to Amaury Demol for reporting
- changed usb TS transfer method (several urbs, stopping transfer
before setting a new pid)
2004-09-13
- added support for a new device (Artec T1 USB TVBOX), thanks
to Christian Motschke for reporting
2004-09-05
- released the dibusb device and dib3000mb-frontend driver
(old news for vp7041.c)
2004-07-15
- found out, by accident, that the device has a TUA6010XS for PLL
2004-07-12
- figured out, that the driver should also work with the
CTS Portable (Chinese Television System)
2004-07-08
- firmware-extraction-2.422-problem solved, driver is now working
properly with firmware extracted from 2.422
- #if for 2.6.4 (dvb), compile issue
- changed firmware handling, see vp7041.txt sec 1.1
2004-07-02
- some tuner modifications, v0.1, cleanups, first public
2004-06-28
- now using the dvb_dmx_swfilter_packets, everything runs fine now
2004-06-27
- able to watch and switching channels (pre-alpha)
- no section filtering yet
2004-06-06
- first TS received, but kernel oops :/
2004-05-14
- firmware loader is working
2004-05-11
- start writing the driver
How to use?
-----------
Firmware
~~~~~~~~
Most of the USB drivers need to download a firmware to the device before start
working.
Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
you need for your device:
https://linuxtv.org/wiki/index.php/DVB_USB
Compiling
~~~~~~~~~
Since the driver is in the linux kernel, activating the driver in
your favorite config-environment should sufficient. I recommend
to compile the driver as module. Hotplug does the rest.
If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
load' afterwards.
Loading the drivers
~~~~~~~~~~~~~~~~~~~
Hotplug is able to load the driver, when it is needed (because you plugged
in the device).
If you want to enable debug output, you have to load the driver manually and
from within the dvb-kernel cvs repository.
first have a look, which debug level are available:
.. code-block:: none
# modinfo dvb-usb
# modinfo dvb-usb-vp7045
etc.
.. code-block:: none
modprobe dvb-usb debug=<level>
modprobe dvb-usb-vp7045 debug=<level>
etc.
should do the trick.
When the driver is loaded successfully, the firmware file was in
the right place and the device is connected, the "Power"-LED should be
turned on.
At this point you should be able to start a dvb-capable application. I'm use
(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
long-term test scenario.
Known problems and bugs
-----------------------
- Don't remove the USB device while running an DVB application, your system
will go crazy or die most likely.
Adding support for devices
~~~~~~~~~~~~~~~~~~~~~~~~~~
TODO
USB1.1 Bandwidth limitation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
A lot of the currently supported devices are USB1.1 and thus they have a
maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
This is not enough for receiving the complete transport stream of a
DVB-T channel (which is about 16 MBit/s). Normally this is not a
problem, if you only want to watch TV (this does not apply for HDTV),
but watching a channel while recording another channel on the same
frequency simply does not work very well. This applies to all USB1.1
DVB-T devices, not just the dvb-usb-devices)
The bug, where the TS is distorted by a heavy usage of the device is gone
definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
working like charm now with VDR. Sometimes I even was able to record a channel
and watch another one.
Comments
~~~~~~~~
Patches, comments and suggestions are very very welcome.
3. Acknowledgements
-------------------
Amaury Demol (Amaury.Demol@parrot.com) and Francois Kanounnikoff from DiBcom for
providing specs, code and help, on which the dvb-dibusb, dib3000mb and
dib3000mc are based.
David Matthews for identifying a new device type (Artec T1 with AN2235)
and for extending dibusb with remote control event handling. Thank you.
Alex Woods for frequently answering question about usb and dvb
stuff, a big thank you.
Bernd Wagner for helping with huge bug reports and discussions.
Gunnar Wittich and Joachim von Caron for their trust for providing
root-shells on their machines to implement support for new devices.
Allan Third and Michael Hutchinson for their help to write the Nebula
digitv-driver.
Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
Jung from AVerMedia who kindly provided a special firmware to get the device
up and running in Linux.
Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
writing the vp7045-driver.
Steve Chang from WideView for providing information for new devices and
firmware files.
Michael Paxton for submitting remote control keymaps.
Some guys on the linux-dvb mailing list for encouraging me.
Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
user-level firmware loader, which saves a lot of time
(when writing the vp7041 driver)
Ulf Hermenau for helping me out with traditional chinese.
André Smoktun and Christian Frömmel for supporting me with
hardware and listening to my problems very patiently.
@@ -0,0 +1,33 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
The Samsung S5P/EXYNOS4 FIMC driver
===================================
Copyright |copy| 2012 - 2013 Samsung Electronics Co., Ltd.
Files partitioning
------------------
- media device driver
drivers/media/platform/samsung/exynos4-is/media-dev.[ch]
- camera capture video device driver
drivers/media/platform/samsung/exynos4-is/fimc-capture.c
- MIPI-CSI2 receiver subdev
drivers/media/platform/samsung/exynos4-is/mipi-csis.[ch]
- video post-processor (mem-to-mem)
drivers/media/platform/samsung/exynos4-is/fimc-core.c
- common files
drivers/media/platform/samsung/exynos4-is/fimc-core.h
drivers/media/platform/samsung/exynos4-is/fimc-reg.h
drivers/media/platform/samsung/exynos4-is/regs-fimc.h
@@ -0,0 +1,32 @@
.. SPDX-License-Identifier: GPL-2.0
****************
Frontend drivers
****************
Frontend attach headers
***********************
.. Keep it on alphabetic order
.. kernel-doc:: drivers/media/dvb-frontends/a8293.h
.. kernel-doc:: drivers/media/dvb-frontends/af9013.h
.. kernel-doc:: drivers/media/dvb-frontends/ascot2e.h
.. kernel-doc:: drivers/media/dvb-frontends/cxd2820r.h
.. kernel-doc:: drivers/media/dvb-frontends/drxk.h
.. kernel-doc:: drivers/media/dvb-frontends/dvb-pll.h
.. kernel-doc:: drivers/media/dvb-frontends/helene.h
.. kernel-doc:: drivers/media/dvb-frontends/horus3a.h
.. kernel-doc:: drivers/media/dvb-frontends/ix2505v.h
.. kernel-doc:: drivers/media/dvb-frontends/m88ds3103.h
.. kernel-doc:: drivers/media/dvb-frontends/mb86a20s.h
.. kernel-doc:: drivers/media/dvb-frontends/mn88472.h
.. kernel-doc:: drivers/media/dvb-frontends/rtl2830.h
.. kernel-doc:: drivers/media/dvb-frontends/rtl2832.h
.. kernel-doc:: drivers/media/dvb-frontends/rtl2832_sdr.h
.. kernel-doc:: drivers/media/dvb-frontends/stb6000.h
.. kernel-doc:: drivers/media/dvb-frontends/tda10071.h
.. kernel-doc:: drivers/media/dvb-frontends/tda826x.h
.. kernel-doc:: drivers/media/dvb-frontends/zd1301_demod.h
.. kernel-doc:: drivers/media/dvb-frontends/zl10036.h
@@ -0,0 +1,41 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
===================================
Media driver-specific documentation
===================================
Video4Linux (V4L) drivers
=========================
.. toctree::
:maxdepth: 5
bttv-devel
cx2341x-devel
cx88-devel
fimc-devel
pvrusb2
pxa_camera
radiotrack
rkisp1
saa7134-devel
sh_mobile_ceu_camera
tuners
vimc-devel
zoran
ccs/ccs
ipu6
Digital TV drivers
==================
.. toctree::
:maxdepth: 5
dvb-usb
frontends
vidtv
contributors
@@ -0,0 +1,190 @@
.. SPDX-License-Identifier: GPL-2.0
==================
Intel IPU6 Driver
==================
Author: Bingbu Cao <bingbu.cao@intel.com>
Overview
=========
Intel IPU6 is the sixth generation of Intel Image Processing Unit used in some
Intel Chipsets such as Tiger Lake, Jasper Lake, Alder Lake, Raptor Lake and
Meteor Lake. IPU6 consists of two major systems: Input System (ISYS) and
Processing System (PSYS). IPU6 are visible on the PCI bus as a single device, it
can be found by ``lspci``:
``0000:00:05.0 Multimedia controller: Intel Corporation Device xxxx (rev xx)``
IPU6 has a 16 MB BAR in PCI configuration Space for MMIO registers which is
visible for driver.
Buttress
=========
The IPU6 is connecting to the system fabric with Buttress which is enabling host
driver to control the IPU6, it also allows IPU6 access the system memory to
store and load frame pixel streams and any other metadata.
Buttress mainly manages several system functionalities: power management,
interrupt handling, firmware authentication and global timer sync.
ISYS and PSYS Power flow
------------------------
IPU6 driver initialize the ISYS and PSYS power up or down request by setting the
Buttress frequency control register for ISYS and PSYS
(``IPU6_BUTTRESS_REG_IS_FREQ_CTL`` and ``IPU6_BUTTRESS_REG_PS_FREQ_CTL``) in
function:
.. c:function:: int ipu6_buttress_power(...)
Buttress forwards the request to Punit, after Punit execute the power up flow,
Buttress indicates driver that ISYS or PSYS is powered up by updating the power
status registers.
.. Note:: ISYS power up needs take place prior to PSYS power up, ISYS power down
needs take place after PSYS power down due to hardware limitation.
Interrupt
---------
IPU6 interrupt can be generated as MSI or INTA, interrupt will be triggered when
ISYS, PSYS, Buttress event or error happen, driver can get the interrupt cause
by reading the interrupt status register ``BUTTRESS_REG_ISR_STATUS``, driver
clears the irq status and then calls specific ISYS or PSYS irq handler.
.. c:function:: irqreturn_t ipu6_buttress_isr(int irq, ...)
Security and firmware authentication
-------------------------------------
To address the IPU6 firmware security concerns, the IPU6 firmware needs to
undergo an authentication process before it is allowed to executed on the IPU6
internal processors. The IPU6 driver will work with Converged Security Engine
(CSE) to complete authentication process. The CSE is responsible of
authenticating the IPU6 firmware. The authenticated firmware binary is copied
into an isolated memory region. Firmware authentication process is implemented
by CSE following an IPC handshake with the IPU6 driver. There are some Buttress
registers used by the CSE and the IPU6 driver to communicate with each other via
IPC.
.. c:function:: int ipu6_buttress_authenticate(...)
Global timer sync
-----------------
The IPU6 driver initiates a Hammock Harbor synchronization flow each time it
starts camera operation. The IPU6 will synchronizes an internal counter in the
Buttress with a copy of the SoC time, this counter maintains the up-to-date time
until camera operation is stopped. The IPU6 driver can use this time counter to
calibrate the timestamp based on the timestamp in response event from firmware.
.. c:function:: int ipu6_buttress_start_tsc_sync(...)
DMA and MMU
============
The IPU6 has its own scalar processor where the firmware run at and an internal
32-bit virtual address space. The IPU6 has MMU address translation hardware to
allow that scalar processors to access the internal memory and external system
memory through IPU6 virtual address. The address translation is based on two
levels of page lookup tables stored in system memory which are maintained by the
IPU6 driver. The IPU6 driver sets the level-1 page table base address to MMU
register and allows MMU to perform page table lookups.
The IPU6 driver exports its own DMA operations. The IPU6 driver will update the
page table entries for each DMA operation and invalidate the MMU TLB after each
unmap and free.
Firmware file format
====================
The IPU6 firmware is in Code Partition Directory (CPD) file format. The CPD
firmware contains a CPD header, several CPD entries and components. The CPD
component includes 3 entries - manifest, metadata and module data. Manifest and
metadata are defined by CSE and used by CSE for authentication. Module data is
specific to IPU6 which holds the binary data of firmware called package
directory. The IPU6 driver (``ipu6-cpd.c`` in particular) parses and validates
the CPD firmware file and gets the package directory binary data of the IPU6
firmware, copies it to specific DMA buffer and sets its base address to Buttress
``FW_SOURCE_BASE`` register. Finally the CSE will do authentication for this
firmware binary.
Syscom interface
================
The IPU6 driver communicates with firmware via the Syscom ABI. Syscom is an
inter-processor communication mechanism between the IPU scalar processors and
the CPU. There are a number of resources shared between firmware and software.
A system memory region where the message queues reside, firmware can access the
memory region via the IPU MMU. The Syscom queues are FIFO fixed depth queues
with a configurable number of tokens (messages). There are also common IPU6 MMIO
registers where the queue read and write indices reside. Software and firmware
function as producer and consumer of tokens in the queues and update the write
and read indices separately when sending or receiving each message.
The IPU6 driver must prepare and configure the number of input and output
queues, configure the count of tokens per queue and the size of per token before
initiating and starting the communication with firmware. Firmware and software
must use same configurations. The IPU6 Buttress has a number of firmware boot
parameter registers which can be used to store the address of configuration and
initialise the Syscom state, then driver can request firmware to start and run via
setting the scalar processor control status register.
Input System
============
IPU6 input system consists of MIPI D-PHY and several CSI-2 receivers. It can
capture image pixel data from camera sensors or other MIPI CSI-2 output devices.
D-PHYs and CSI-2 ports lane mapping
-----------------------------------
The IPU6 integrates different D-PHY IPs on different SoCs, on Tiger Lake and
Alder Lake, IPU6 integrates MCD10 D-PHY, IPU6SE on Jasper Lake integrates JSL
D-PHY and IPU6EP on Meteor Lake integrates a Synopsys DWC D-PHY. There is an
adaptional layer between D-PHY and CSI-2 receiver controller which includes port
configuration, PHY wrapper or private test interfaces for D-PHY. There are 3
D-PHY drivers ``ipu6-isys-mcd-phy.c``, ``ipu6-isys-jsl-phy.c`` and
``ipu6-isys-dwc-phy.c`` program the above 3 D-PHYs in IPU6.
Different IPU6 versions have different D-PHY lanes mappings, On Tiger Lake,
there are 12 data lanes and 8 clock lanes, IPU6 support maximum 8 CSI-2 ports,
see the PPI mmapping in ``ipu6-isys-mcd-phy.c`` for more information. On Jasper
Lake and Alder Lake, D-PHY has 8 data lanes and 4 clock lanes, the IPU6 supports
maximum 4 CSI-2 ports. For Meteor Lake, D-PHY has 12 data lanes and 6 clock
lanes so IPU6 support maximum 6 CSI-2 ports.
.. Note:: Each pair of CSI-2 two ports is a single unit that can share the data
lanes. For example, for CSI-2 port 0 and 1, CSI-2 port 0 support
maximum 4 data lanes, CSI-2 port 1 support maximum 2 data lanes, CSI-2
port 0 with 2 data lanes can work together with CSI-2 port 1 with 2
data lanes. If trying to use CSI-2 port 0 with 4 lanes, CSI-2 port 1
will not be available as the 4 data lanes are shared by CSI-2 port 0
and 1. The same applies to CSI ports 2/3, 4/5 and 7/8.
ISYS firmware ABIs
------------------
The IPU6 firmware implements a series of ABIs for software access. In general,
software firstly prepares the stream configuration ``struct
ipu6_fw_isys_stream_cfg_data_abi`` and sends the configuration to firmware via
sending ``STREAM_OPEN`` command. Stream configuration includes input pins and
output pins, input pin ``struct ipu6_fw_isys_input_pin_info_abi`` defines the
resolution and data type of input source, output pin ``struct
ipu6_fw_isys_output_pin_info_abi`` defines the output resolution, stride and
frame format, etc.
Once the driver gets the interrupt from firmware that indicates stream open
successfully, the driver will send the ``STREAM_START`` and ``STREAM_CAPTURE``
command to request firmware to start capturing image frames. ``STREAM_CAPTURE``
command queues the buffers to firmware with ``struct
ipu6_fw_isys_frame_buff_set``, software then waits for the interrupt and
response from firmware, ``PIN_DATA_READY`` means a buffer is ready on a specific
output pin and then software can return the buffer to user.
.. Note:: See :ref:`Examples<ipu6_isys_capture_examples>` about how to do
capture by IPU6 ISYS driver.
@@ -0,0 +1,202 @@
.. SPDX-License-Identifier: GPL-2.0
The pvrusb2 driver
==================
Author: Mike Isely <isely@pobox.com>
Background
----------
This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which
is a USB 2.0 hosted TV Tuner. This driver is a work in progress.
Its history started with the reverse-engineering effort by Björn
Danielsson <pvrusb2@dax.nu> whose web page can be found here:
http://pvrusb2.dax.nu/
From there Aurelien Alleaume <slts@free.fr> began an effort to
create a video4linux compatible driver. I began with Aurelien's
last known snapshot and evolved the driver to the state it is in
here.
More information on this driver can be found at:
https://www.isely.net/pvrusb2.html
This driver has a strong separation of layers. They are very
roughly:
1. Low level wire-protocol implementation with the device.
2. I2C adaptor implementation and corresponding I2C client drivers
implemented elsewhere in V4L.
3. High level hardware driver implementation which coordinates all
activities that ensure correct operation of the device.
4. A "context" layer which manages instancing of driver, setup,
tear-down, arbitration, and interaction with high level
interfaces appropriately as devices are hotplugged in the
system.
5. High level interfaces which glue the driver to various published
Linux APIs (V4L, sysfs, maybe DVB in the future).
The most important shearing layer is between the top 2 layers. A
lot of work went into the driver to ensure that any kind of
conceivable API can be laid on top of the core driver. (Yes, the
driver internally leverages V4L to do its work but that really has
nothing to do with the API published by the driver to the outside
world.) The architecture allows for different APIs to
simultaneously access the driver. I have a strong sense of fairness
about APIs and also feel that it is a good design principle to keep
implementation and interface isolated from each other. Thus while
right now the V4L high level interface is the most complete, the
sysfs high level interface will work equally well for similar
functions, and there's no reason I see right now why it shouldn't be
possible to produce a DVB high level interface that can sit right
alongside V4L.
Building
--------
To build these modules essentially amounts to just running "Make",
but you need the kernel source tree nearby and you will likely also
want to set a few controlling environment variables first in order
to link things up with that source tree. Please see the Makefile
here for comments that explain how to do that.
Source file list / functional overview
--------------------------------------
(Note: The term "module" used below generally refers to loosely
defined functional units within the pvrusb2 driver and bears no
relation to the Linux kernel's concept of a loadable module.)
pvrusb2-audio.[ch] - This is glue logic that resides between this
driver and the msp3400.ko I2C client driver (which is found
elsewhere in V4L).
pvrusb2-context.[ch] - This module implements the context for an
instance of the driver. Everything else eventually ties back to
or is otherwise instanced within the data structures implemented
here. Hotplugging is ultimately coordinated here. All high level
interfaces tie into the driver through this module. This module
helps arbitrate each interface's access to the actual driver core,
and is designed to allow concurrent access through multiple
instances of multiple interfaces (thus you can for example change
the tuner's frequency through sysfs while simultaneously streaming
video through V4L out to an instance of mplayer).
pvrusb2-debug.h - This header defines a printk() wrapper and a mask
of debugging bit definitions for the various kinds of debug
messages that can be enabled within the driver.
pvrusb2-debugifc.[ch] - This module implements a crude command line
oriented debug interface into the driver. Aside from being part
of the process for implementing manual firmware extraction (see
the pvrusb2 web site mentioned earlier), probably I'm the only one
who has ever used this. It is mainly a debugging aid.
pvrusb2-eeprom.[ch] - This is glue logic that resides between this
driver the tveeprom.ko module, which is itself implemented
elsewhere in V4L.
pvrusb2-encoder.[ch] - This module implements all protocol needed to
interact with the Conexant mpeg2 encoder chip within the pvrusb2
device. It is a crude echo of corresponding logic in ivtv,
however the design goals (strict isolation) and physical layer
(proxy through USB instead of PCI) are enough different that this
implementation had to be completely different.
pvrusb2-hdw-internal.h - This header defines the core data structure
in the driver used to track ALL internal state related to control
of the hardware. Nobody outside of the core hardware-handling
modules should have any business using this header. All external
access to the driver should be through one of the high level
interfaces (e.g. V4L, sysfs, etc), and in fact even those high
level interfaces are restricted to the API defined in
pvrusb2-hdw.h and NOT this header.
pvrusb2-hdw.h - This header defines the full internal API for
controlling the hardware. High level interfaces (e.g. V4L, sysfs)
will work through here.
pvrusb2-hdw.c - This module implements all the various bits of logic
that handle overall control of a specific pvrusb2 device.
(Policy, instantiation, and arbitration of pvrusb2 devices fall
within the jurisdiction of pvrusb-context not here).
pvrusb2-i2c-chips-\*.c - These modules implement the glue logic to
tie together and configure various I2C modules as they attach to
the I2C bus. There are two versions of this file. The "v4l2"
version is intended to be used in-tree alongside V4L, where we
implement just the logic that makes sense for a pure V4L
environment. The "all" version is intended for use outside of
V4L, where we might encounter other possibly "challenging" modules
from ivtv or older kernel snapshots (or even the support modules
in the standalone snapshot).
pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1
compatible commands to the I2C modules. It is here where state
changes inside the pvrusb2 driver are translated into V4L1
commands that are in turn send to the various I2C modules.
pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2
compatible commands to the I2C modules. It is here where state
changes inside the pvrusb2 driver are translated into V4L2
commands that are in turn send to the various I2C modules.
pvrusb2-i2c-core.[ch] - This module provides an implementation of a
kernel-friendly I2C adaptor driver, through which other external
I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
operate corresponding chips within the pvrusb2 device. It is
through here that other V4L modules can reach into this driver to
operate specific pieces (and those modules are in turn driven by
glue logic which is coordinated by pvrusb2-hdw, doled out by
pvrusb2-context, and then ultimately made available to users
through one of the high level interfaces).
pvrusb2-io.[ch] - This module implements a very low level ring of
transfer buffers, required in order to stream data from the
device. This module is *very* low level. It only operates the
buffers and makes no attempt to define any policy or mechanism for
how such buffers might be used.
pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch]
to provide a streaming API usable by a read() system call style of
I/O. Right now this is the only layer on top of pvrusb2-io.[ch],
however the underlying architecture here was intended to allow for
other styles of I/O to be implemented with additional modules, like
mmap()'ed buffers or something even more exotic.
pvrusb2-main.c - This is the top level of the driver. Module level
and USB core entry points are here. This is our "main".
pvrusb2-sysfs.[ch] - This is the high level interface which ties the
pvrusb2 driver into sysfs. Through this interface you can do
everything with the driver except actually stream data.
pvrusb2-tuner.[ch] - This is glue logic that resides between this
driver and the tuner.ko I2C client driver (which is found
elsewhere in V4L).
pvrusb2-util.h - This header defines some common macros used
throughout the driver. These macros are not really specific to
the driver, but they had to go somewhere.
pvrusb2-v4l2.[ch] - This is the high level interface which ties the
pvrusb2 driver into video4linux. It is through here that V4L
applications can open and operate the driver in the usual V4L
ways. Note that **ALL** V4L functionality is published only
through here and nowhere else.
pvrusb2-video-\*.[ch] - This is glue logic that resides between this
driver and the saa711x.ko I2C client driver (which is found
elsewhere in V4L). Note that saa711x.ko used to be known as
saa7115.ko in ivtv. There are two versions of this; one is
selected depending on the particular saa711[5x].ko that is found.
pvrusb2.h - This header contains compile time tunable parameters
(and at the moment the driver has very little that needs to be
tuned).
@@ -0,0 +1,194 @@
.. SPDX-License-Identifier: GPL-2.0
PXA-Camera Host Driver
======================
Author: Robert Jarzmik <robert.jarzmik@free.fr>
Constraints
-----------
a) Image size for YUV422P format
All YUV422P images are enforced to have width x height % 16 = 0.
This is due to DMA constraints, which transfers only planes of 8 byte
multiples.
Global video workflow
---------------------
a) QCI stopped
Initially, the QCI interface is stopped.
When a buffer is queued, start_streaming is called and the QCI starts.
b) QCI started
More buffers can be queued while the QCI is started without halting the
capture. The new buffers are "appended" at the tail of the DMA chain, and
smoothly captured one frame after the other.
Once a buffer is filled in the QCI interface, it is marked as "DONE" and
removed from the active buffers list. It can be then requeud or dequeued by
userland application.
Once the last buffer is filled in, the QCI interface stops.
c) Capture global finite state machine schema
.. code-block:: none
+----+ +---+ +----+
| DQ | | Q | | DQ |
| v | v | v
+-----------+ +------------------------+
| STOP | | Wait for capture start |
+-----------+ Q +------------------------+
+-> | QCI: stop | ------------------> | QCI: run | <------------+
| | DMA: stop | | DMA: stop | |
| +-----------+ +-----> +------------------------+ |
| / | |
| / +---+ +----+ | |
|capture list empty / | Q | | DQ | | QCI Irq EOF |
| / | v | v v |
| +--------------------+ +----------------------+ |
| | DMA hotlink missed | | Capture running | |
| +--------------------+ +----------------------+ |
| | QCI: run | +-----> | QCI: run | <-+ |
| | DMA: stop | / | DMA: run | | |
| +--------------------+ / +----------------------+ | Other |
| ^ /DMA still | | channels |
| | capture list / running | DMA Irq End | not |
| | not empty / | | finished |
| | / v | yet |
| +----------------------+ +----------------------+ | |
| | Videobuf released | | Channel completed | | |
| +----------------------+ +----------------------+ | |
+-- | QCI: run | | QCI: run | --+ |
| DMA: run | | DMA: run | |
+----------------------+ +----------------------+ |
^ / | |
| no overrun / | overrun |
| / v |
+--------------------+ / +----------------------+ |
| Frame completed | / | Frame overran | |
+--------------------+ <-----+ +----------------------+ restart frame |
| QCI: run | | QCI: stop | --------------+
| DMA: run | | DMA: stop |
+--------------------+ +----------------------+
Legend: - each box is a FSM state
- each arrow is the condition to transition to another state
- an arrow with a comment is a mandatory transition (no condition)
- arrow "Q" means : a buffer was enqueued
- arrow "DQ" means : a buffer was dequeued
- "QCI: stop" means the QCI interface is not enabled
- "DMA: stop" means all 3 DMA channels are stopped
- "DMA: run" means at least 1 DMA channel is still running
DMA usage
---------
a) DMA flow
- first buffer queued for capture
Once a first buffer is queued for capture, the QCI is started, but data
transfer is not started. On "End Of Frame" interrupt, the irq handler
starts the DMA chain.
- capture of one videobuffer
The DMA chain starts transferring data into videobuffer RAM pages.
When all pages are transferred, the DMA irq is raised on "ENDINTR" status
- finishing one videobuffer
The DMA irq handler marks the videobuffer as "done", and removes it from
the active running queue
Meanwhile, the next videobuffer (if there is one), is transferred by DMA
- finishing the last videobuffer
On the DMA irq of the last videobuffer, the QCI is stopped.
b) DMA prepared buffer will have this structure
.. code-block:: none
+------------+-----+---------------+-----------------+
| desc-sg[0] | ... | desc-sg[last] | finisher/linker |
+------------+-----+---------------+-----------------+
This structure is pointed by dma->sg_cpu.
The descriptors are used as follows:
- desc-sg[i]: i-th descriptor, transferring the i-th sg
element to the video buffer scatter gather
- finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN
- linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0
For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N],
"f" stands for finisher and "l" for linker.
A typical running chain is :
.. code-block:: none
Videobuffer 1 Videobuffer 2
+---------+----+---+ +----+----+----+---+
| d0 | .. | dN | l | | d0 | .. | dN | f |
+---------+----+-|-+ ^----+----+----+---+
| |
+----+
After the chaining is finished, the chain looks like :
.. code-block:: none
Videobuffer 1 Videobuffer 2 Videobuffer 3
+---------+----+---+ +----+----+----+---+ +----+----+----+---+
| d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
+---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
| | | |
+----+ +----+
new_link
c) DMA hot chaining timeslice issue
As DMA chaining is done while DMA _is_ running, the linking may be done
while the DMA jumps from one Videobuffer to another. On the schema, that
would be a problem if the following sequence is encountered :
- DMA chain is Videobuffer1 + Videobuffer2
- pxa_videobuf_queue() is called to queue Videobuffer3
- DMA controller finishes Videobuffer2, and DMA stops
.. code-block:: none
=>
Videobuffer 1 Videobuffer 2
+---------+----+---+ +----+----+----+---+
| d0 | .. | dN | l | | d0 | .. | dN | f |
+---------+----+-|-+ ^----+----+----+-^-+
| | |
+----+ +-- DMA DDADR loads DDADR_STOP
- pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is
replaced by a "linker" to Videobuffer3 (creation of new_link)
- pxa_videobuf_queue() finishes
- the DMA irq handler is called, which terminates Videobuffer2
- Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!)
.. code-block:: none
Videobuffer 1 Videobuffer 2 Videobuffer 3
+---------+----+---+ +----+----+----+---+ +----+----+----+---+
| d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f |
+---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+
| | | |
+----+ +----+
new_link
DMA DDADR still is DDADR_STOP
- pxa_camera_check_link_miss() is called
This checks if the DMA is finished and a buffer is still on the
pcdev->capture list. If that's the case, the capture will be restarted,
and Videobuffer3 is scheduled on DMA chain.
- the DMA irq handler finishes
.. note::
If DMA stops just after pxa_camera_check_link_miss() reads DDADR()
value, we have the guarantee that the DMA irq handler will be called back
when the DMA will finish the buffer, and pxa_camera_check_link_miss() will
be called again, to reschedule Videobuffer3.
@@ -0,0 +1,168 @@
.. SPDX-License-Identifier: GPL-2.0
The Radiotrack radio driver
===========================
Author: Stephen M. Benoit <benoits@servicepro.com>
Date: Dec 14, 1996
ACKNOWLEDGMENTS
----------------
This document was made based on 'C' code for Linux from Gideon le Grange
(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
Frans Brinkman (brinkman@esd.nl) in 1996. The results reported here are from
experiments that the author performed on his own setup, so your mileage may
vary... I make no guarantees, claims or warranties to the suitability or
validity of this information. No other documentation on the AIMS
Lab (http://www.aimslab.com/) RadioTrack card was made available to the
author. This document is offered in the hopes that it might help users who
want to use the RadioTrack card in an environment other than MS Windows.
WHY THIS DOCUMENT?
------------------
I have a RadioTrack card from back when I ran an MS-Windows platform. After
converting to Linux, I found Gideon le Grange's command-line software for
running the card, and found that it was good! Frans Brinkman made a
comfortable X-windows interface, and added a scanning feature. For hack
value, I wanted to see if the tuner could be tuned beyond the usual FM radio
broadcast band, so I could pick up the audio carriers from North American
broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
I did not get much success, but I learned about programming ioports under
Linux and gained some insights about the hardware design used for the card.
So, without further delay, here are the details.
PHYSICAL DESCRIPTION
--------------------
The RadioTrack card is an ISA 8-bit FM radio card. The radio frequency (RF)
input is simply an antenna lead, and the output is a power audio signal
available through a miniature phone plug. Its RF frequencies of operation are
more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
band). Although the registers can be programmed to request frequencies beyond
these limits, experiments did not give promising results. The variable
frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
signal probably has a small range of useful frequencies, and wraps around or
gets clipped beyond the limits mentioned above.
CONTROLLING THE CARD WITH IOPORT
--------------------------------
The RadioTrack (base) ioport is configurable for 0x30c or 0x20c. Only one
ioport seems to be involved. The ioport decoding circuitry must be pretty
simple, as individual ioport bits are directly matched to specific functions
(or blocks) of the radio card. This way, many functions can be changed in
parallel with one write to the ioport. The only feedback available through
the ioports appears to be the "Stereo Detect" bit.
The bits of the ioport are arranged as follows:
.. code-block:: none
MSb LSb
+------+------+------+--------+--------+-------+---------+--------+
| VolA | VolB | ???? | Stereo | Radio | TuneA | TuneB | Tune |
| (+) | (-) | | Detect | Audio | (bit) | (latch) | Update |
| | | | Enable | Enable | | | Enable |
+------+------+------+--------+--------+-------+---------+--------+
==== ==== =================================
VolA VolB Description
==== ==== =================================
0 0 audio mute
0 1 volume + (some delay required)
1 0 volume - (some delay required)
1 1 stay at present volume
==== ==== =================================
==================== ===========
Stereo Detect Enable Description
==================== ===========
0 No Detect
1 Detect
==================== ===========
Results available by reading ioport >60 msec after last port write.
0xff ==> no stereo detected, 0xfd ==> stereo detected.
============================= =============================
Radio to Audio (path) Enable Description
============================= =============================
0 Disable path (silence)
1 Enable path (audio produced)
============================= =============================
===== ===== ==================
TuneA TuneB Description
===== ===== ==================
0 0 "zero" bit phase 1
0 1 "zero" bit phase 2
1 0 "one" bit phase 1
1 1 "one" bit phase 2
===== ===== ==================
24-bit code, where bits = (freq*40) + 10486188.
The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
The bits are shifted in LSb first.
================== ===========================
Tune Update Enable Description
================== ===========================
0 Tuner held constant
1 Tuner updating in progress
================== ===========================
PROGRAMMING EXAMPLES
--------------------
.. code-block:: none
Default: BASE <-- 0xc8 (current volume, no stereo detect,
radio enable, tuner adjust disable)
Card Off: BASE <-- 0x00 (audio mute, no stereo detect,
radio disable, tuner adjust disable)
Card On: BASE <-- 0x00 (see "Card Off", clears any unfinished business)
BASE <-- 0xc8 (see "Default")
Volume Down: BASE <-- 0x48 (volume down, no stereo detect,
radio enable, tuner adjust disable)
wait 10 msec
BASE <-- 0xc8 (see "Default")
Volume Up: BASE <-- 0x88 (volume up, no stereo detect,
radio enable, tuner adjust disable)
wait 10 msec
BASE <-- 0xc8 (see "Default")
Check Stereo: BASE <-- 0xd8 (current volume, stereo detect,
radio enable, tuner adjust disable)
wait 100 msec
x <-- BASE (read ioport)
BASE <-- 0xc8 (see "Default")
x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
Set Frequency: code = (freq*40) + 10486188
foreach of the 24 bits in code,
(from Least to Most Significant):
to write a "zero" bit,
BASE <-- 0x01 (audio mute, no stereo detect, radio
disable, "zero" bit phase 1, tuner adjust)
BASE <-- 0x03 (audio mute, no stereo detect, radio
disable, "zero" bit phase 2, tuner adjust)
to write a "one" bit,
BASE <-- 0x05 (audio mute, no stereo detect, radio
disable, "one" bit phase 1, tuner adjust)
BASE <-- 0x07 (audio mute, no stereo detect, radio
disable, "one" bit phase 2, tuner adjust)
@@ -0,0 +1,43 @@
.. SPDX-License-Identifier: GPL-2.0
The Rockchip Image Signal Processor Driver (rkisp1)
===================================================
Versions and their differences
------------------------------
The rkisp1 block underwent some changes between SoC implementations.
The vendor designates them as:
- V10: used at least in rk3288 and rk3399
- V11: declared in the original vendor code, but not used
- V12: used at least in rk3326 and px30
- V13: used at least in rk1808
- V20: used in rk3568 and beyond
Right now the kernel supports rkisp1 implementations based
on V10 and V12 variants. V11 does not seem to be actually used
and V13 will need some more additions but isn't researched yet,
especially as it seems to be limited to the rk1808 which hasn't
reached much market spread.
V20 on the other hand will probably be used in future SoCs and
has seen really big changes in the vendor kernel, so will need
quite a bit of research.
Changes from V10 to V12
-----------------------
- V12 supports a new CSI-host implementation but can still
also use the same implementation from V10
- The module for lens shading correction got changed
from 12bit to 13bit width
- The AWB and AEC modules got replaced to support finer
grained data collection
Changes from V12 to V13
-----------------------
The list for V13 is incomplete and needs further investigation.
- V13 does not support the old CSI-host implementation anymore
@@ -0,0 +1,67 @@
.. SPDX-License-Identifier: GPL-2.0
The saa7134 driver
==================
Author Gerd Hoffmann
Card Variations:
----------------
Cards can use either of these two crystals (xtal):
- 32.11 MHz -> .audio_clock=0x187de7
- 24.576MHz -> .audio_clock=0x200000 (xtal * .audio_clock = 51539600)
Some details about 30/34/35:
- saa7130 - low-price chip, doesn't have mute, that is why all those
cards should have .mute field defined in their tuner structure.
- saa7134 - usual chip
- saa7133/35 - saa7135 is probably a marketing decision, since all those
chips identifies itself as 33 on pci.
LifeView GPIOs
--------------
This section was authored by: Peter Missel <peter.missel@onlinehome.de>
- LifeView FlyTV Platinum FM (LR214WF)
- GP27 MDT2005 PB4 pin 10
- GP26 MDT2005 PB3 pin 9
- GP25 MDT2005 PB2 pin 8
- GP23 MDT2005 PB1 pin 7
- GP22 MDT2005 PB0 pin 6
- GP21 MDT2005 PB5 pin 11
- GP20 MDT2005 PB6 pin 12
- GP19 MDT2005 PB7 pin 13
- nc MDT2005 PA3 pin 2
- Remote MDT2005 PA2 pin 1
- GP18 MDT2005 PA1 pin 18
- nc MDT2005 PA0 pin 17 strap low
- GP17 Strap "GP7"=High
- GP16 Strap "GP6"=High
- 0=Radio 1=TV
- Drives SA630D ENCH1 and HEF4052 A1 pinsto do FM radio through
SIF input
- GP15 nc
- GP14 nc
- GP13 nc
- GP12 Strap "GP5" = High
- GP11 Strap "GP4" = High
- GP10 Strap "GP3" = High
- GP09 Strap "GP2" = Low
- GP08 Strap "GP1" = Low
- GP07.00 nc
Credits
-------
andrew.stevens@philips.com + werner.leeb@philips.com for providing
saa7134 hardware specs and sample board.
@@ -0,0 +1,142 @@
.. SPDX-License-Identifier: GPL-2.0
Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
=======================================================================
Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Terminology
-----------
sensor scales: horizontal and vertical scales, configured by the sensor driver
host scales: -"- host driver
combined scales: sensor_scale * host_scale
Generic scaling / cropping scheme
---------------------------------
.. code-block:: none
-1--
|
-2-- -\
| --\
| --\
+-5-- . -- -3-- -\
| `... -\
| `... -4-- . - -7..
| `.
| `. .6--
|
| . .6'-
| .´
| ... -4'- .´
| ...´ - -7'.
+-5'- .´ -/
| -- -3'- -/
| --/
| --/
-2'- -/
|
|
-1'-
In the above chart minuses and slashes represent "real" data amounts, points and
accents represent "useful" data, basically, CEU scaled and cropped output,
mapped back onto the client's source plane.
Such a configuration can be produced by user requests:
S_CROP(left / top = (5) - (1), width / height = (5') - (5))
S_FMT(width / height = (6') - (6))
Here:
(1) to (1') - whole max width or height
(1) to (2) - sensor cropped left or top
(2) to (2') - sensor cropped width or height
(3) to (3') - sensor scale
(3) to (4) - CEU cropped left or top
(4) to (4') - CEU cropped width or height
(5) to (5') - reverse sensor scale applied to CEU cropped width or height
(2) to (5) - reverse sensor scale applied to CEU cropped left or top
(6) to (6') - CEU scale - user window
S_FMT
-----
Do not touch input rectangle - it is already optimal.
1. Calculate current sensor scales:
scale_s = ((2') - (2)) / ((3') - (3))
2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
current sensor scales onto input window - this is user S_CROP:
width_u = (5') - (5) = ((4') - (4)) * scale_s
3. Calculate new combined scales from "effective" input window to requested user
window:
scale_comb = width_u / ((6') - (6))
4. Calculate sensor output window by applying combined scales to real input
window:
width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
5. Apply iterative sensor S_FMT for sensor output window.
subdev->video_ops->s_fmt(.width = width_s_out)
6. Retrieve sensor output window (g_fmt)
7. Calculate new sensor scales:
scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
8. Calculate new CEU crop - apply sensor scales to previously calculated
"effective" crop:
width_ceu = (4')_new - (4)_new = width_u / scale_s_new
left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
9. Use CEU cropping to crop to the new window:
ceu_crop(.width = width_ceu, .left = left_ceu)
10. Use CEU scaling to scale to the requested user window:
scale_ceu = width_ceu / width
S_CROP
------
The :ref:`V4L2 crop API <crop-scale>` says:
"...specification does not define an origin or units. However by convention
drivers should horizontally count unscaled samples relative to 0H."
We choose to follow the advise and interpret cropping units as client input
pixels.
Cropping is performed in the following 6 steps:
1. Request exactly user rectangle from the sensor.
2. If smaller - iterate until a larger one is obtained. Result: sensor cropped
to 2 : 2', target crop 5 : 5', current output format 6' - 6.
3. In the previous step the sensor has tried to preserve its output frame as
good as possible, but it could have changed. Retrieve it again.
4. Sensor scaled to 3 : 3'. Sensor's scale is (2' - 2) / (3' - 3). Calculate
intermediate window: 4' - 4 = (5' - 5) * (3' - 3) / (2' - 2)
5. Calculate and apply host scale = (6' - 6) / (4' - 4)
6. Calculate and apply host crop: 6 - 7 = (5 - 2) * (6' - 6) / (5' - 5)
@@ -0,0 +1,133 @@
.. SPDX-License-Identifier: GPL-2.0
Tuner drivers
=============
Simple tuner Programming
------------------------
There are some flavors of Tuner programming APIs.
These differ mainly by the bandswitch byte.
- L= LG_API (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
- P= PHILIPS_API (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
- T= TEMIC_API (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
- A= ALPS_API (VHF_LO=0x14, VHF_HI=0x12, UHF=0x11)
- M= PHILIPS_MK3 (VHF_LO=0x01, VHF_HI=0x02, UHF=0x04, radio=0x19)
Tuner Manufacturers
-------------------
- Samsung Tuner identification: (e.g. TCPM9091PD27)
.. code-block:: none
TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
[ABCJLMNQ]:
A= BG+DK
B= BG
C= I+DK
J= NTSC-Japan
L= Secam LL
M= BG+I+DK
N= NTSC
Q= BG+I+DK+LL
[89]: ?
[125]:
2: No FM
5: With FM
[DP]:
D= NTSC
P= PAL
[ACD]:
A= F-connector
C= Phono connector
D= Din Jack
[ABCD]:
3-wire/I2C tuning, 2-band/3-band
These Tuners are PHILIPS_API compatible.
Philips Tuner identification: (e.g. FM1216MF)
.. code-block:: none
F[IRMQ]12[1345]6{MF|ME|MP}
F[IRMQ]:
FI12x6: Tuner Series
FR12x6: Tuner + Radio IF
FM12x6: Tuner + FM
FQ12x6: special
FMR12x6: special
TD15xx: Digital Tuner ATSC
12[1345]6:
1216: PAL BG
1236: NTSC
1246: PAL I
1256: Pal DK
{MF|ME|MP}
MF: BG LL w/ Secam (Multi France)
ME: BG DK I LL (Multi Europe)
MP: BG DK I (Multi PAL)
MR: BG DK M (?)
MG: BG DKI M (?)
MK2 series PHILIPS_API, most tuners are compatible to this one !
MK3 series introduced in 2002 w/ PHILIPS_MK3_API
Temic Tuner identification: (.e.g 4006FH5)
.. code-block:: none
4[01][0136][269]F[HYNR]5
40x2: Tuner (5V/33V), TEMIC_API.
40x6: Tuner 5V
41xx: Tuner compact
40x9: Tuner+FM compact
[0136]
xx0x: PAL BG
xx1x: Pal DK, Secam LL
xx3x: NTSC
xx6x: PAL I
F[HYNR]5
FH5: Pal BG
FY5: others
FN5: multistandard
FR5: w/ FM radio
3X xxxx: order number with specific connector
Note: Only 40x2 series has TEMIC_API, all newer tuners have PHILIPS_API.
LG Innotek Tuner:
- TPI8NSR11 : NTSC J/M (TPI8NSR01 w/FM) (P,210/497)
- TPI8PSB11 : PAL B/G (TPI8PSB01 w/FM) (P,170/450)
- TAPC-I701 : PAL I (TAPC-I001 w/FM) (P,170/450)
- TPI8PSB12 : PAL D/K+B/G (TPI8PSB02 w/FM) (P,170/450)
- TAPC-H701P: NTSC_JP (TAPC-H001P w/FM) (L,170/450)
- TAPC-G701P: PAL B/G (TAPC-G001P w/FM) (L,170/450)
- TAPC-W701P: PAL I (TAPC-W001P w/FM) (L,170/450)
- TAPC-Q703P: PAL D/K (TAPC-Q001P w/FM) (L,170/450)
- TAPC-Q704P: PAL D/K+I (L,170/450)
- TAPC-G702P: PAL D/K+B/G (L,170/450)
- TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
- TADC-M201D: PAL D/K+B/G+I (L,143/425) (sound control at I2C address 0xc8)
- TADC-T003F: NTSC Taiwan (L,175/410?; 2-B, C-W+11, W+12-69)
Suffix:
- P= Standard phono female socket
- D= IEC female socket
- F= F-connector
Other Tuners:
- TCL2002MB-1 : PAL BG + DK =TUNER_LG_PAL_NEW_TAPC
- TCL2002MB-1F: PAL BG + DK w/FM =PHILIPS_PAL
- TCL2002MI-2 : PAL I = ??
ALPS Tuners:
- Most are LG_API compatible
- TSCH6 has ALPS_API (TSCH5 ?)
- TSBE1 has extra API 05,02,08 Control_byte=0xCB Source:[#f1]_
.. [#f1] conexant100029b-PCI-Decoder-ApplicationNote.pdf
@@ -0,0 +1,513 @@
.. SPDX-License-Identifier: GPL-2.0
================================
vidtv: Virtual Digital TV driver
================================
Author: Daniel W. S. Almeida <dwlsalmeida@gmail.com>, June 2020.
Background
----------
Vidtv is a virtual DVB driver that aims to serve as a reference for driver
writers by serving as a template. It also validates the existing media DVB
APIs, thus helping userspace application writers.
Currently, it consists of:
- A fake tuner driver, which will report a bad signal quality if the chosen
frequency is too far away from a table of valid frequencies for a
particular delivery system.
- A fake demod driver, which will constantly poll the fake signal quality
returned by the tuner, simulating a device that can lose/reacquire a lock
on the signal depending on the CNR levels.
- A fake bridge driver, which is the module responsible for modprobing the
fake tuner and demod modules and implementing the demux logic. This module
takes parameters at initialization that will dictate how the simulation
behaves.
- Code responsible for encoding a valid MPEG Transport Stream, which is then
passed to the bridge driver. This fake stream contains some hardcoded content.
For now, we have a single, audio-only channel containing a single MPEG
Elementary Stream, which in turn contains a SMPTE 302m encoded sine-wave.
Note that this particular encoder was chosen because it is the easiest
way to encode PCM audio data in a MPEG Transport Stream.
Building vidtv
--------------
vidtv is a test driver and thus is **not** enabled by default when
compiling the kernel.
In order to enable compilation of vidtv:
- Enable **DVB_TEST_DRIVERS**, then
- Enable **DVB_VIDTV**
When compiled as a module, expect the following .ko files:
- dvb_vidtv_tuner.ko
- dvb_vidtv_demod.ko
- dvb_vidtv_bridge.ko
Running vidtv
-------------
When compiled as a module, run::
modprobe vidtv
That's it! The bridge driver will initialize the tuner and demod drivers as
part of its own initialization.
By default, it will accept the following frequencies:
- 474 MHz for DVB-T/T2/C;
- 11,362 GHz for DVB-S/S2.
For satellite systems, the driver simulates an universal extended
LNBf, with frequencies at Ku-Band, ranging from 10.7 GHz to 12.75 GHz.
You can optionally define some command-line arguments to vidtv.
Command-line arguments to vidtv
-------------------------------
Below is a list of all arguments that can be supplied to vidtv:
drop_tslock_prob_on_low_snr
Probability of losing the TS lock if the signal quality is bad.
This probability be used by the fake demodulator driver to
eventually return a status of 0 when the signal quality is not
good.
recover_tslock_prob_on_good_snr:
Probability recovering the TS lock when the signal improves. This
probability be used by the fake demodulator driver to eventually
return a status of 0x1f when/if the signal quality improves.
mock_power_up_delay_msec
Simulate a power up delay. Default: 0.
mock_tune_delay_msec
Simulate a tune delay. Default 0.
vidtv_valid_dvb_t_freqs
Valid DVB-T frequencies to simulate, in Hz.
vidtv_valid_dvb_c_freqs
Valid DVB-C frequencies to simulate, in Hz.
vidtv_valid_dvb_s_freqs
Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz.
max_frequency_shift_hz,
Maximum shift in HZ allowed when tuning in a channel.
si_period_msec
How often to send SI packets. Default: 40ms.
pcr_period_msec
How often to send PCR packets. Default: 40ms.
mux_rate_kbytes_sec
Attempt to maintain this bit rate by inserting TS null packets, if
necessary. Default: 4096.
pcr_pid,
PCR PID for all channels. Default: 0x200.
mux_buf_sz_pkts,
Size for the mux buffer in multiples of 188 bytes.
vidtv internal structure
------------------------
The kernel modules are split in the following way:
vidtv_tuner.[ch]
Implements a fake tuner DVB driver.
vidtv_demod.[ch]
Implements a fake demodulator DVB driver.
vidtv_bridge.[ch]
Implements a bridge driver.
The MPEG related code is split in the following way:
vidtv_ts.[ch]
Code to work with MPEG TS packets, such as TS headers, adaptation
fields, PCR packets and NULL packets.
vidtv_psi.[ch]
This is the PSI generator. PSI packets contain general information
about a MPEG Transport Stream. A PSI generator is needed so
userspace apps can retrieve information about the Transport Stream
and eventually tune into a (dummy) channel.
Because the generator is implemented in a separate file, it can be
reused elsewhere in the media subsystem.
Currently vidtv supports working with 5 PSI tables: PAT, PMT,
SDT, NIT and EIT.
The specification for PAT and PMT can be found in *ISO 13818-1:
Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI
EN 300 468: Specification for Service Information (SI) in DVB
systems*.
It isn't strictly necessary, but using a real TS file helps when
debugging PSI tables. Vidtv currently tries to replicate the PSI
structure found in this file: `TS1Globo.ts
<https://tsduck.io/streams/brazil-isdb-tb/TS1globo.ts>`_.
A good way to visualize the structure of streams is by using
`DVBInspector <https://sourceforge.net/projects/dvbinspector/>`_.
vidtv_pes.[ch]
Implements the PES logic to convert encoder data into MPEG TS
packets. These can then be fed into a TS multiplexer and eventually
into userspace.
vidtv_encoder.h
An interface for vidtv encoders. New encoders can be added to this
driver by implementing the calls in this file.
vidtv_s302m.[ch]
Implements a S302M encoder to make it possible to insert PCM audio
data in the generated MPEG Transport Stream. The relevant
specification is available online as *SMPTE 302M-2007: Television -
Mapping of AES3 Data into MPEG-2 Transport Stream*.
The resulting MPEG Elementary Stream is conveyed in a private
stream with a S302M registration descriptor attached.
This shall enable passing an audio signal into userspace so it can
be decoded and played by media software. The corresponding decoder
in ffmpeg is located in 'libavcodec/s302m.c' and is experimental.
vidtv_channel.[ch]
Implements a 'channel' abstraction.
When vidtv boots, it will create some hardcoded channels:
#. Their services will be concatenated to populate the SDT.
#. Their programs will be concatenated to populate the PAT
#. Their events will be concatenated to populate the EIT
#. For each program in the PAT, a PMT section will be created
#. The PMT section for a channel will be assigned its streams.
#. Every stream will have its corresponding encoder polled in a
loop to produce TS packets.
These packets may be interleaved by the muxer and then delivered
to the bridge.
vidtv_mux.[ch]
Implements a MPEG TS mux, loosely based on the ffmpeg
implementation in "libavcodec/mpegtsenc.c"
The muxer runs a loop which is responsible for:
#. Keeping track of the amount of time elapsed since the last
iteration.
#. Polling encoders in order to fetch 'elapsed_time' worth of data.
#. Inserting PSI and/or PCR packets, if needed.
#. Padding the resulting stream with NULL packets if
necessary in order to maintain the chosen bit rate.
#. Delivering the resulting TS packets to the bridge
driver so it can pass them to the demux.
Testing vidtv with v4l-utils
----------------------------
Using the tools in v4l-utils is a great way to test and inspect the output of
vidtv. It is hosted here: `v4l-utils Documentation
<https://linuxtv.org/wiki/index.php/V4l-utils>`_.
From its webpage::
The v4l-utils are a series of packages for handling media devices.
It is hosted at http://git.linuxtv.org/v4l-utils.git, and packaged
on most distributions.
It provides a series of libraries and utilities to be used to
control several aspect of the media boards.
Start by installing v4l-utils and then modprobing vidtv::
modprobe dvb_vidtv_bridge
If the driver is OK, it should load and its probing code will run. This will
pull in the tuner and demod drivers.
Using dvb-fe-tool
~~~~~~~~~~~~~~~~~
The first step to check whether the demod loaded successfully is to run::
$ dvb-fe-tool
Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities:
CAN_FEC_1_2
CAN_FEC_2_3
CAN_FEC_3_4
CAN_FEC_4_5
CAN_FEC_5_6
CAN_FEC_6_7
CAN_FEC_7_8
CAN_FEC_8_9
CAN_FEC_AUTO
CAN_GUARD_INTERVAL_AUTO
CAN_HIERARCHY_AUTO
CAN_INVERSION_AUTO
CAN_QAM_16
CAN_QAM_32
CAN_QAM_64
CAN_QAM_128
CAN_QAM_256
CAN_QAM_AUTO
CAN_QPSK
CAN_TRANSMISSION_MODE_AUTO
DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A
Supported delivery systems:
DVBT
DVBT2
[DVBC/ANNEX_A]
DVBS
DVBS2
Frequency range for the current standard:
From: 51.0 MHz
To: 2.15 GHz
Step: 62.5 kHz
Tolerance: 29.5 MHz
Symbol rate ranges for the current standard:
From: 1.00 MBauds
To: 45.0 MBauds
This should return what is currently set up at the demod struct, i.e.::
static const struct dvb_frontend_ops vidtv_demod_ops = {
.delsys = {
SYS_DVBT,
SYS_DVBT2,
SYS_DVBC_ANNEX_A,
SYS_DVBS,
SYS_DVBS2,
},
.info = {
.name = "Dummy demod for DVB-T/T2/C/S/S2",
.frequency_min_hz = 51 * MHz,
.frequency_max_hz = 2150 * MHz,
.frequency_stepsize_hz = 62500,
.frequency_tolerance_hz = 29500 * kHz,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_4_5 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_6_7 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_8_9 |
FE_CAN_QAM_16 |
FE_CAN_QAM_64 |
FE_CAN_QAM_32 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO |
FE_CAN_QPSK |
FE_CAN_FEC_AUTO |
FE_CAN_INVERSION_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO,
}
....
For more information on dvb-fe-tools check its online documentation here:
`dvb-fe-tool Documentation
<https://www.linuxtv.org/wiki/index.php/Dvb-fe-tool>`_.
Using dvb-scan
~~~~~~~~~~~~~~
In order to tune into a channel and read the PSI tables, we can use dvb-scan.
For this, one should provide a configuration file known as a 'scan file',
here's an example::
[Channel]
FREQUENCY = 474000000
MODULATION = QAM/AUTO
SYMBOL_RATE = 6940000
INNER_FEC = AUTO
DELIVERY_SYSTEM = DVBC/ANNEX_A
.. note::
The parameters depend on the video standard you're testing.
.. note::
Vidtv is a fake driver and does not validate much of the information
in the scan file. Just specifying 'FREQUENCY' and 'DELIVERY_SYSTEM'
should be enough for DVB-T/DVB-T2. For DVB-S/DVB-C however, you
should also provide 'SYMBOL_RATE'.
You can browse scan tables online here: `dvb-scan-tables
<https://git.linuxtv.org/dtv-scan-tables.git>`_.
Assuming this channel is named 'channel.conf', you can then run::
$ dvbv5-scan channel.conf
dvbv5-scan ~/vidtv.conf
ERROR command BANDWIDTH_HZ (5) not found during retrieve
Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet).
Scanning frequency #1 330000000
(0x00) Signal= -68.00dBm
Scanning frequency #2 474000000
Lock (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0
Service Beethoven, provider LinuxTV.org: digital television
For more information on dvb-scan, check its documentation online here:
`dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_.
Using dvb-zap
~~~~~~~~~~~~~
dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The
typical use is to tune into a channel and put it into record mode. The example
below - which is taken from the documentation - illustrates that\ [1]_::
$ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10
using demux 'dvb0.demux0'
reading channels from file 'dvb_channel.conf'
tuning to 474000000 Hz
pass all PID's to TS
dvb_set_pesfilter 8192
dvb_dev_set_bufsize: buffer set to 6160384
Lock (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
Lock (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
Record to file 'music.ts' started
received 24587768 bytes (2401 Kbytes/sec)
Lock (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0
.. [1] In this example, it records 10 seconds with all program ID's stored
at the music.ts file.
The channel can be watched by playing the contents of the stream with some
player that recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``.
By playing the contents of the stream one can visually inspect the workings of
vidtv, e.g., to play a recorded TS file with::
$ mplayer music.ts
or, alternatively, running this command on one terminal::
$ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r &
And, on a second terminal, playing the contents from DVR interface with::
$ mplayer /dev/dvb/adapter0/dvr0
For more information on dvb-zap check its online documentation here:
`dvb-zap Documentation
<https://www.linuxtv.org/wiki/index.php/Dvbv5-zap>`_.
See also: `zap <https://www.linuxtv.org/wiki/index.php/Zap>`_.
What can still be improved in vidtv
-----------------------------------
Add *debugfs* integration
~~~~~~~~~~~~~~~~~~~~~~~~~
Although frontend drivers provide DVBv5 statistics via the .read_status
call, a nice addition would be to make additional statistics available to
userspace via debugfs, which is a simple-to-use, RAM-based filesystem
specifically designed for debug purposes.
The logic for this would be implemented on a separate file so as not to
pollute the frontend driver. These statistics are driver-specific and can
be useful during tests.
The Siano driver is one example of a driver using
debugfs to convey driver-specific statistics to userspace and it can be
used as a reference.
This should be further enabled and disabled via a Kconfig
option for convenience.
Add a way to test video
~~~~~~~~~~~~~~~~~~~~~~~
Currently, vidtv can only encode PCM audio. It would be great to implement
a barebones version of MPEG-2 video encoding so we can also test video. The
first place to look into is *ISO 13818-2: Information technology — Generic
coding of moving pictures and associated audio information — Part 2: Video*,
which covers the encoding of compressed video in MPEG Transport Streams.
This might optionally use the Video4Linux2 Test Pattern Generator, v4l2-tpg,
which resides at::
drivers/media/common/v4l2-tpg/
Add white noise simulation
~~~~~~~~~~~~~~~~~~~~~~~~~~
The vidtv tuner already has code to identify whether the chosen frequency
is too far away from a table of valid frequencies. For now, this means that
the demodulator can eventually lose the lock on the signal, since the tuner will
report a bad signal quality.
A nice addition is to simulate some noise when the signal quality is bad by:
- Randomly dropping some TS packets. This will trigger a continuity error if the
continuity counter is updated but the packet is not passed on to the demux.
- Updating the error statistics accordingly (e.g. BER, etc).
- Simulating some noise in the encoded data.
Functions and structs used within vidtv
---------------------------------------
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_bridge.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_channel.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_demod.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_encoder.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_mux.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_pes.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_psi.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_s302m.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_ts.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.h
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_common.c
.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.c
@@ -0,0 +1,15 @@
.. SPDX-License-Identifier: GPL-2.0
The Virtual Media Controller Driver (vimc)
==========================================
Source code documentation
-------------------------
vimc-streamer
~~~~~~~~~~~~~
.. kernel-doc:: drivers/media/test-drivers/vimc/vimc-streamer.h
:internal:
.. kernel-doc:: drivers/media/test-drivers/vimc/vimc-streamer.c
@@ -0,0 +1,575 @@
.. SPDX-License-Identifier: GPL-2.0
The Zoran driver
================
unified zoran driver (zr360x7, zoran, buz, dc10(+), dc30(+), lml33)
website: http://mjpeg.sourceforge.net/driver-zoran/
Frequently Asked Questions
--------------------------
What cards are supported
------------------------
Iomega Buz, Linux Media Labs LML33/LML33R10, Pinnacle/Miro
DC10/DC10+/DC30/DC30+ and related boards (available under various names).
Iomega Buz
~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36060 MJPEG codec
* Philips saa7111 TV decoder
* Philips saa7185 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, saa7111, saa7185, zr36060, zr36067
Inputs/outputs: Composite and S-video
Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
Card number: 7
AverMedia 6 Eyes AVS6EYES
~~~~~~~~~~~~~~~~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36060 MJPEG codec
* Samsung ks0127 TV decoder
* Conexant bt866 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, ks0127, bt866, zr36060, zr36067
Inputs/outputs:
Six physical inputs. 1-6 are composite,
1-2, 3-4, 5-6 doubles as S-video,
1-3 triples as component.
One composite output.
Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
Card number: 8
.. note::
Not autodetected, card=8 is necessary.
Linux Media Labs LML33
~~~~~~~~~~~~~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36060 MJPEG codec
* Brooktree bt819 TV decoder
* Brooktree bt856 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, bt819, bt856, zr36060, zr36067
Inputs/outputs: Composite and S-video
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
Card number: 5
Linux Media Labs LML33R10
~~~~~~~~~~~~~~~~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36060 MJPEG codec
* Philips saa7114 TV decoder
* Analog Devices adv7170 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, saa7114, adv7170, zr36060, zr36067
Inputs/outputs: Composite and S-video
Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
Card number: 6
Pinnacle/Miro DC10(new)
~~~~~~~~~~~~~~~~~~~~~~~
* Zoran zr36057 PCI controller
* Zoran zr36060 MJPEG codec
* Philips saa7110a TV decoder
* Analog Devices adv7176 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, saa7110, adv7175, zr36060, zr36067
Inputs/outputs: Composite, S-video and Internal
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
Card number: 1
Pinnacle/Miro DC10+
~~~~~~~~~~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36060 MJPEG codec
* Philips saa7110a TV decoder
* Analog Devices adv7176 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, saa7110, adv7175, zr36060, zr36067
Inputs/outputs: Composite, S-video and Internal
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
Card number: 2
Pinnacle/Miro DC10(old)
~~~~~~~~~~~~~~~~~~~~~~~
* Zoran zr36057 PCI controller
* Zoran zr36050 MJPEG codec
* Zoran zr36016 Video Front End or Fuji md0211 Video Front End (clone?)
* Micronas vpx3220a TV decoder
* mse3000 TV encoder or Analog Devices adv7176 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
Inputs/outputs: Composite, S-video and Internal
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
Card number: 0
Pinnacle/Miro DC30
~~~~~~~~~~~~~~~~~~
* Zoran zr36057 PCI controller
* Zoran zr36050 MJPEG codec
* Zoran zr36016 Video Front End
* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
* Analog Devices adv7176 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
Inputs/outputs: Composite, S-video and Internal
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
Card number: 3
Pinnacle/Miro DC30+
~~~~~~~~~~~~~~~~~~~
* Zoran zr36067 PCI controller
* Zoran zr36050 MJPEG codec
* Zoran zr36016 Video Front End
* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
* Analog Devices adv7176 TV encoder
Drivers to use: videodev, i2c-core, i2c-algo-bit,
videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zr36067
Inputs/outputs: Composite, S-video and Internal
Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
Card number: 4
.. note::
#) No module for the mse3000 is available yet
#) No module for the vpx3224 is available yet
1.1 What the TV decoder can do an what not
------------------------------------------
The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that
information is not enough. There are several formats of the TV standards.
And not every TV decoder is able to handle every format. Also the every
combination is supported by the driver. There are currently 11 different
tv broadcast formats all aver the world.
The CCIR defines parameters needed for broadcasting the signal.
The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
The CCIR says not much about the colorsystem used !!!
And talking about a colorsystem says not to much about how it is broadcast.
The CCIR standards A,E,F are not used any more.
When you speak about NTSC, you usually mean the standard: CCIR - M using
the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada
and a few others.
When you talk about PAL, you usually mean: CCIR - B/G using the PAL
colorsystem which is used in many Countries.
When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem
which is used in France, and a few others.
There the other version of SECAM, CCIR - D/K is used in Bulgaria, China,
Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others.
The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in
Egypt, Libya, Sri Lanka, Syrain Arab. Rep.
The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong,
Ireland, Nigeria, South Africa.
The CCIR - N uses the PAL colorsystem and PAL frame size but the NTSC framerate,
and is used in Argentina, Uruguay, and a few others
We do not talk about how the audio is broadcast !
A rather good sites about the TV standards are:
http://www.sony.jp/support/
http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/
and http://www.cabl.com/restaurant/channel.html
Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly
used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same
as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
be the same as NTSC 4.43.
NTSC Combs seems to be a decoder mode where the decoder uses a comb filter
to split coma and luma instead of a Delay line.
But I did not defiantly find out what NTSC Comb is.
Philips saa7111 TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1997, is used in the BUZ and
- can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM
Philips saa7110a TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and
- can handle: PAL B/G, NTSC M and SECAM
Philips saa7114 TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 2000, is used in the LML33R10 and
- can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM
Brooktree bt819 TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1996, and is used in the LML33 and
- can handle: PAL B/D/G/H/I, NTSC M
Micronas vpx3220a TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1996, is used in the DC30 and DC30+ and
- can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC 44, PAL 60, SECAM,NTSC Comb
Samsung ks0127 TV decoder
~~~~~~~~~~~~~~~~~~~~~~~~~
- is used in the AVS6EYES card and
- can handle: NTSC-M/N/44, PAL-M/N/B/G/H/I/D/K/L and SECAM
What the TV encoder can do an what not
--------------------------------------
The TV encoder is doing the "same" as the decoder, but in the other direction.
You feed them digital data and the generate a Composite or SVHS signal.
For information about the colorsystems and TV norm take a look in the
TV decoder section.
Philips saa7185 TV Encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1996, is used in the BUZ
- can generate: PAL B/G, NTSC M
Brooktree bt856 TV Encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1994, is used in the LML33
- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina)
Analog Devices adv7170 TV Encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 2000, is used in the LML300R10
- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL 60
Analog Devices adv7175 TV Encoder
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1996, is used in the DC10, DC10+, DC10 old, DC30, DC30+
- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M
ITT mse3000 TV encoder
~~~~~~~~~~~~~~~~~~~~~~
- was introduced in 1991, is used in the DC10 old
- can generate: PAL , NTSC , SECAM
Conexant bt866 TV encoder
~~~~~~~~~~~~~~~~~~~~~~~~~
- is used in AVS6EYES, and
- can generate: NTSC/PAL, PAL-M, PAL-N
The adv717x, should be able to produce PAL N. But you find nothing PAL N
specific in the registers. Seem that you have to reuse a other standard
to generate PAL N, maybe it would work if you use the PAL M settings.
How do I get this damn thing to work
------------------------------------
Load zr36067.o. If it can't autodetect your card, use the card=X insmod
option with X being the card number as given in the previous section.
To have more than one card, use card=X1[,X2[,X3,[X4[..]]]]
To automate this, add the following to your /etc/modprobe.d/zoran.conf:
options zr36067 card=X1[,X2[,X3[,X4[..]]]]
alias char-major-81-0 zr36067
One thing to keep in mind is that this doesn't load zr36067.o itself yet. It
just automates loading. If you start using xawtv, the device won't load on
some systems, since you're trying to load modules as a user, which is not
allowed ("permission denied"). A quick workaround is to add 'Load "v4l"' to
XF86Config-4 when you use X by default, or to run 'v4l-conf -c <device>' in
one of your startup scripts (normally rc.local) if you don't use X. Both
make sure that the modules are loaded on startup, under the root account.
What mainboard should I use (or why doesn't my card work)
---------------------------------------------------------
<insert lousy disclaimer here>. In short: good=SiS/Intel, bad=VIA.
Experience tells us that people with a Buz, on average, have more problems
than users with a DC10+/LML33. Also, it tells us that people owning a VIA-
based mainboard (ktXXX, MVP3) have more problems than users with a mainboard
based on a different chipset. Here's some notes from Andrew Stevens:
Here's my experience of using LML33 and Buz on various motherboards:
- VIA MVP3
- Forget it. Pointless. Doesn't work.
- Intel 430FX (Pentium 200)
- LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie)
- Intel 440BX (early stepping)
- LML33 tolerable. Buz starting to get annoying (6-10 frames/hour)
- Intel 440BX (late stepping)
- Buz tolerable, LML3 almost perfect (occasional single frame drops)
- SiS735
- LML33 perfect, Buz tolerable.
- VIA KT133(*)
- LML33 starting to get annoying, Buz poor enough that I have up.
- Both 440BX boards were dual CPU versions.
Bernhard Praschinger later added:
- AMD 751
- Buz perfect-tolerable
- AMD 760
- Buz perfect-tolerable
In general, people on the user mailinglist won't give you much of a chance
if you have a VIA-based motherboard. They may be cheap, but sometimes, you'd
rather want to spend some more money on better boards. In general, VIA
mainboard's IDE/PCI performance will also suck badly compared to others.
You'll noticed the DC10+/DC30+ aren't mentioned anywhere in the overview.
Basically, you can assume that if the Buz works, the LML33 will work too. If
the LML33 works, the DC10+/DC30+ will work too. They're most tolerant to
different mainboard chipsets from all of the supported cards.
If you experience timeouts during capture, buy a better mainboard or lower
the quality/buffersize during capture (see 'Concerning buffer sizes, quality,
output size etc.'). If it hangs, there's little we can do as of now. Check
your IRQs and make sure the card has its own interrupts.
Programming interface
---------------------
This driver conforms to video4linux2. Support for V4L1 and for the custom
zoran ioctls has been removed in kernel 2.6.38.
For programming example, please, look at lavrec.c and lavplay.c code in
the MJPEG-tools (http://mjpeg.sf.net/).
Additional notes for software developers:
The driver returns maxwidth and maxheight parameters according to
the current TV standard (norm). Therefore, the software which
communicates with the driver and "asks" for these parameters should
first set the correct norm. Well, it seems logically correct: TV
standard is "more constant" for current country than geometry
settings of a variety of TV capture cards which may work in ITU or
square pixel format.
Applications
------------
Applications known to work with this driver:
TV viewing:
* xawtv
* kwintv
* probably any TV application that supports video4linux or video4linux2.
MJPEG capture/playback:
* mjpegtools/lavtools (or Linux Video Studio)
* gstreamer
* mplayer
General raw capture:
* xawtv
* gstreamer
* probably any application that supports video4linux or video4linux2
Video editing:
* Cinelerra
* MainActor
* mjpegtools (or Linux Video Studio)
Concerning buffer sizes, quality, output size etc.
--------------------------------------------------
The zr36060 can do 1:2 JPEG compression. This is really the theoretical
maximum that the chipset can reach. The driver can, however, limit compression
to a maximum (size) of 1:4. The reason for this is that some cards (e.g. Buz)
can't handle 1:2 compression without stopping capture after only a few minutes.
With 1:4, it'll mostly work. If you have a Buz, use 'low_bitrate=1' to go into
1:4 max. compression mode.
100% JPEG quality is thus 1:2 compression in practice. So for a full PAL frame
(size 720x576). The JPEG fields are stored in YUY2 format, so the size of the
fields are 720x288x16/2 bits/field (2 fields/frame) = 207360 bytes/field x 2 =
414720 bytes/frame (add some more bytes for headers and DHT (huffman)/DQT
(quantization) tables, and you'll get to something like 512kB per frame for
1:2 compression. For 1:4 compression, you'd have frames of half this size.
Some additional explanation by Martin Samuelsson, which also explains the
importance of buffer sizes:
--
> Hmm, I do not think it is really that way. With the current (downloaded
> at 18:00 Monday) driver I get that output sizes for 10 sec:
> -q 50 -b 128 : 24.283.332 Bytes
> -q 50 -b 256 : 48.442.368
> -q 25 -b 128 : 24.655.992
> -q 25 -b 256 : 25.859.820
I woke up, and can't go to sleep again. I'll kill some time explaining why
this doesn't look strange to me.
Let's do some math using a width of 704 pixels. I'm not sure whether the Buz
actually use that number or not, but that's not too important right now.
704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block;
3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block;
1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum
output becomes 512 bits per block. Actually 510, but 512 is simpler to use
for calculations.
Let's say that we specify d1q50. We thus want 256 bits per block; times 3168
becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes
here, so we don't need to do any fancy corrections for bits-per-pixel or such
things. 101376 bytes per field.
d1 video contains two fields per frame. Those sum up to 202752 bytes per
frame, and one of those frames goes into each buffer.
But wait a second! -b128 gives 128kB buffers! It's not possible to cram
202752 bytes of JPEG data into 128kB!
This is what the driver notice and automatically compensate for in your
examples. Let's do some math using this information:
128kB is 131072 bytes. In this buffer, we want to store two fields, which
leaves 65536 bytes for each field. Using 3168 blocks per field, we get
20.68686868... available bytes per block; 165 bits. We can't allow the
request for 256 bits per block when there's only 165 bits available! The -q50
option is silently overridden, and the -b128 option takes precedence, leaving
us with the equivalence of -q32.
This gives us a data rate of 165 bits per block, which, times 3168, sums up
to 65340 bytes per field, out of the allowed 65536. The current driver has
another level of rate limiting; it won't accept -q values that fill more than
6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be
a safe bet. Personally, I think I would have lowered requested-bits-per-block
by one, or something like that.) We can't use 165 bits per block, but have to
lower it again, to 6/8 of the available buffer space: We end up with 124 bits
per block, the equivalence of -q24. With 128kB buffers, you can't use greater
than -q24 at -d1. (And PAL, and 704 pixels width...)
The third example is limited to -q24 through the same process. The second
example, using very similar calculations, is limited to -q48. The only
example that actually grab at the specified -q value is the last one, which
is clearly visible, looking at the file size.
--
Conclusion: the quality of the resulting movie depends on buffer size, quality,
whether or not you use 'low_bitrate=1' as insmod option for the zr36060.c
module to do 1:4 instead of 1:2 compression, etc.
If you experience timeouts, lowering the quality/buffersize or using
'low_bitrate=1 as insmod option for zr36060.o might actually help, as is
proven by the Buz.
It hangs/crashes/fails/whatevers! Help!
---------------------------------------
Make sure that the card has its own interrupts (see /proc/interrupts), check
the output of dmesg at high verbosity (load zr36067.o with debug=2,
load all other modules with debug=1). Check that your mainboard is favorable
(see question 2) and if not, test the card in another computer. Also see the
notes given in question 3 and try lowering quality/buffersize/capturesize
if recording fails after a period of time.
If all this doesn't help, give a clear description of the problem including
detailed hardware information (memory+brand, mainboard+chipset+brand, which
MJPEG card, processor, other PCI cards that might be of interest), give the
system PnP information (/proc/interrupts, /proc/dma, /proc/devices), and give
the kernel version, driver version, glibc version, gcc version and any other
information that might possibly be of interest. Also provide the dmesg output
at high verbosity. See 'Contacting' on how to contact the developers.
Maintainers/Contacting
----------------------
Previous maintainers/developers of this driver are
- Laurent Pinchart <laurent.pinchart@skynet.be>
- Ronald Bultje rbultje@ronald.bitfreak.net
- Serguei Miridonov <mirsev@cicese.mx>
- Wolfgang Scherr <scherr@net4you.net>
- Dave Perks <dperks@ibm.net>
- Rainer Johanni <Rainer@Johanni.de>
Driver's License
----------------
This driver is distributed under the terms of the General Public License.
This program 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.
See http://www.gnu.org/ for more information.
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
Digital TV Conditional Access kABI
----------------------------------
.. kernel-doc:: include/media/dvb_ca_en50221.h
@@ -0,0 +1,53 @@
.. SPDX-License-Identifier: GPL-2.0
Digital TV Common functions
---------------------------
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
@@ -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
@@ -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 defined 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
@@ -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 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 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 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 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 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
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
Digital TV Network kABI
-----------------------
.. kernel-doc:: include/media/dvb_net.h
@@ -0,0 +1,55 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
===================================
Media subsystem kernel internal API
===================================
This section contains usage information about media subsystem and
its supported drivers.
Please see:
Documentation/admin-guide/media/index.rst
- for usage information about media subsystem and supported drivers;
Documentation/userspace-api/media/index.rst
- for the userspace APIs used on media devices.
.. toctree::
:caption: Table of Contents
:maxdepth: 5
:numbered:
maintainer-entry-profile
media-committers
v4l2-core
dtv-core
rc-core
mc-core
cec-core
tx-rx
camera-sensor
drivers/index
**Copyright** |copy| 2009-2020 : 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.
@@ -0,0 +1,545 @@
.. SPDX-License-Identifier: GPL-2.0
Media Subsystem Profile
=======================
Overview
--------
The Linux Media Community (aka: the LinuxTV Community) is formed by
developers working on Linux Kernel Media Subsystem, together with users
who also play an important role in testing the code.
The Media Subsystem has code to support a wide variety of media-related
devices: stream capture, analog and digital TV streams, cameras,
video codecs, video processing (resizers, etc.), radio, remote controllers,
HDMI CEC and media pipeline control.
The Media Subsystem consists of the following directories in the kernel
tree:
- drivers/media
- drivers/staging/media
- include/media
- Documentation/devicetree/bindings/media/\ [1]_
- Documentation/admin-guide/media
- Documentation/driver-api/media
- Documentation/userspace-api/media
.. [1] Device tree bindings are maintained by the
OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS maintainers
(see the MAINTAINERS file). So, changes there must be reviewed
by them before being merged into the media subsystem's development
tree.
Both media userspace and Kernel APIs are documented and the documentation
must be kept in sync with the API changes. It means that all patches that
add new features to the subsystem must also bring changes to the
corresponding API documentation.
Media Maintainers
-----------------
Media Maintainers are not just people capable of writing code, but they
are developers who have demonstrated their ability to collaborate with
the team, get the most knowledgeable people to review code, contribute
high-quality code, and follow through to fix issues (in code or tests).
Due to the size and wide scope of the media subsystem, multiple layers of
maintainers are required, each with their own areas of expertise:
- **Media Driver Maintainer**:
Responsible for one or more drivers within the Media Subsystem. They
are listed in the MAINTAINERS file as maintainer for those drivers. Media
Driver Maintainers review patches for those drivers, provide feedback if
patches do not follow the subsystem rules, or are not using the
media kernel or userspace APIs correctly, or if they have poor code
quality.
If you are the patch author, you work with other Media
Maintainers to ensure your patches are reviewed.
Some Media Driver Maintainers have additional responsibilities. They have
been granted Patchwork access and keep
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_
up to date, decide when patches are ready for merging, and create Pull
Requests for the Media Subsystem Maintainers to merge.
- **Media Core Maintainer**:
Media Driver Maintainers with Patchwork access who are also responsible for
one or more media core frameworks.
Core framework changes are done via consensus between the relevant Media
Core Maintainers. Media Maintainers may include core framework changes in
their Pull Requests if they are signed off by the relevant Media Core
Maintainers.
- **Media Subsystem Maintainers**:
Media Core Maintainers who are also responsible for the subsystem as a
whole, with access to the entire subsystem. Responsible for merging Pull
Requests from other Media Maintainers.
Userspace API/ABI changes are made via consensus among Media Subsystem
Maintainers\ [2]_. Media Maintainers may include API/ABI changes in
their Pull Requests if they are signed off by all Media Subsystem
Maintainers.
All Media Maintainers shall agree with the Kernel development process as
described in Documentation/process/index.rst and with the Kernel development
rules in the Kernel documentation, including its code of conduct.
Media Maintainers are often reachable via the #linux-media IRC channel at OFTC.
.. [2] Everything that would break backward compatibility with existing
non-kernel code are API/ABI changes. This includes ioctl and sysfs
interfaces, v4l2 controls, and their behaviors.
Patchwork Access
----------------
All Media Maintainers who have been granted Patchwork access shall ensure that
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_
will reflect the current status, e.g. patches shall be delegated to the Media
Maintainer who is handling them and the patch status shall be updated according
to these rules:
- ``Under Review``: Used if the patch requires a second opinion
or when it is part of a Pull Request;
- ``Superseded``: There is a newer version of the patch posted to the
mailing list.
- ``Duplicated``: There was another patch doing the same thing from someone
else that was accepted.
- ``Not Applicable``: Use for patch series that are not merged at media.git
tree (e.g. drm, dmabuf, upstream merge, etc.) but were cross-posted to the
linux-media mailing list.
- ``Accepted``: Once a patch is merged in the multi-committer tree. Only Media
Maintainers with commit rights are allowed to set this state.
If Media Maintainers decide not to accept a patch, they should reply to the
patch authors by e‑mail, explaining why it is not accepted, and
update `Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_
accordingly with one of the following statuses:
- ``Changes Requested``: if a new revision was requested;
- ``Rejected``: if the proposed change is not acceptable at all.
.. Note::
Patchwork supports a couple of clients to help semi-automate
status updates via its REST interface:
https://patchwork.readthedocs.io/en/latest/usage/clients/
For patches that fall within their area of responsibility a Media Maintainer
also decides when those patches are ready for merging, and create Pull Requests
for the Media Subsystem Maintainers to merge.
The most important aspect of becoming a Media Maintainer with Patchwork access
is that you have demonstrated an ability to give good code reviews. We value
your ability to deliver thorough, constructive code reviews.
As such, potential maintainers must earn enough credibility and trust from the
Linux Media Community. To do that, developers shall be familiar with the open
source model and have been active in the Linux Kernel community for some time,
and, in particular, in the media subsystem.
In addition to actually making the code changes, you are basically
demonstrating your:
- commitment to the project;
- ability to collaborate with the team and communicate well;
- understanding of how upstream and the Linux Media Community work
(policies, processes for testing, code review, ...)
- reasonable knowledge about:
- the Kernel development process:
Documentation/process/index.rst
- the Media development profile:
Documentation/driver-api/media/maintainer-entry-profile.rst
- understanding of the projects' code base and coding style;
- ability to provide feedback to the patch authors;
- ability to judge when a patch might be ready for review and to submit;
- ability to write good code (last but certainly not least).
Media Driver Maintainers that desire to get Patchwork access are encouraged
to participate at the yearly Linux Media Summit, typically co-located with
a Linux-related conference. These summits are announced on the linux-media
mailing list.
If you are doing such tasks and have become a valued developer, an
existing Media Maintainer can nominate you to the Media Subsystem Maintainers.
The ultimate responsibility for accepting a nominated maintainer is up to
the subsystem's maintainers. The nominated maintainer must have earned a trust
relationship with all Media Subsystem Maintainers, as, by being granted
Patchwork access, you will take over part of their maintenance tasks.
Media Committers
----------------
Experienced and trusted Media Maintainers may be granted commit rights
which allow them to directly push patches to the media development tree instead
of posting a Pull Request for the Media Subsystem Maintainers. This helps
offloading some of the work of the Media Subsystem Maintainers.
More details about Media Committers' roles and responsibilities can be
found here: :ref:`Media Committers`.
Media development sites
-----------------------
The `LinuxTV <https://linuxtv.org/>`_ web site hosts news about the subsystem,
together with:
- `Wiki pages <https://www.linuxtv.org/wiki/index.php/Main_Page>`_;
- `Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_;
- `Linux Media documentation <https://linuxtv.org/docs.php>`_;
- and more.
The main development trees used by the media subsystem are at:
- Stable tree:
- https://git.linuxtv.org/media.git/
- Media committers tree:
- https://gitlab.freedesktop.org/linux-media/media-committers.git
Please note that it can be rebased, although only as a last resort.
- Media development trees, including apps and CI:
- https://git.linuxtv.org/
- https://gitlab.freedesktop.org/linux-media/
.. _Media development workflow:
Media development workflow
++++++++++++++++++++++++++
All changes for the media subsystem shall be sent first as e-mails to the
media mailing list, following the process documented at
Documentation/process/index.rst.
It means that patches shall be submitted as plain text only via e-mail to
linux-media@vger.kernel.org (aka: LMML). While subscription is not mandatory,
you can find details about how to subscribe to it and to see its archives at:
https://subspace.kernel.org/vger.kernel.org.html
Emails with HTML will be automatically rejected by the mail server.
It could be wise to also copy the relevant Media Maintainer(s). You should use
``scripts/get_maintainers.pl`` to identify whom else needs to be copied.
Please always copy driver's authors and maintainers.
To minimize the chance of merge conflicts for your patch series, and make it
easier to backport patches to stable Kernels, we recommend that you use the
following baseline for your patch series:
1. Features for the next mainline release:
- baseline shall be the ``media-committers.git next`` branch;
2. Bug fixes for the next mainline release:
- baseline shall be the ``media-committers.git next`` branch. If the
changes depend on a fix from the ``media-committers.git fixes``
branch, then you can use that as baseline.
3. Bug fixes for the current mainline release (-rcX):
- baseline shall be the latest mainline -rcX release or the
``media-committers.git fixes`` branch if changes depend on a mainline
fix that is not yet merged;
.. Note::
See https://www.kernel.org/category/releases.html for an overview
about Kernel release types.
Patches with fixes shall have:
- a ``Fixes:`` tag pointing to the first commit that introduced the bug;
- when applicable, a ``Cc: stable@vger.kernel.org``.
Patches that were fixing bugs publicly reported by someone at the
linux-media@vger.kernel.org mailing list shall have:
- a ``Reported-by:`` tag immediately followed by a ``Closes:`` tag.
Patches that change API shall update documentation accordingly at the
same patch series.
See Documentation/process/index.rst for more details about e-mail submission.
Once a patch is submitted, it may follow either one of the following
workflows:
a. Media Maintainers' workflow: Media Maintainers post the Pull Requests,
which are handled by the Media Subsystem Maintainers::
+-------+ +------------+ +------+ +-------+ +---------------------+
|e-mail |-->|picked up by|-->|code |-->|pull |-->|Subsystem Maintainers|
|to LMML| |Patchwork | |review| |request| |merge in |
| | | | | | | | |media-committers.git |
+-------+ +------------+ +------+ +-------+ +---------------------+
For this workflow, Pull Requests are generated by Media Maintainers with
Patchwork access. If you do not have Patchwork access, then please don't
submit Pull Requests, as they will not be processed.
b. Media Committers' workflow: patches are handled by Media Maintainers with
commit rights::
+-------+ +------------+ +------+ +--------------------------+
|e-mail |-->|picked up by|-->|code |-->|Media Committers merge in |
|to LMML| |Patchwork | |review| |media-committers.git |
+-------+ +------------+ +------+ +--------------------------+
When patches are picked up by
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_
and when merged at media-committers, Media CI bots will check for errors and
may provide e-mail feedback about patch problems. When this happens, the patch
submitter must fix them or explain why the errors are false positives.
Patches will only be moved to the next stage in these two workflows if they
pass on Media CI or if there are false-positives in the Media CI reports.
For both workflows, all patches shall be properly reviewed at
linux-media@vger.kernel.org (LMML) before being merged in
``media-committers.git``. Media patches will be reviewed in a timely manner
by the maintainers and reviewers as listed in the MAINTAINERS file.
Media Maintainers shall request reviews from other Media Maintainers and
developers where applicable, i.e. because those developers have more
knowledge about some areas that are changed by a patch.
There shall be no open issues or unresolved or conflicting feedback
from anyone. Clear them up first. Defer to the Media Subsystem
Maintainers if needed.
Failures during e-mail submission
+++++++++++++++++++++++++++++++++
Media's workflow is heavily based on Patchwork, meaning that, once a patch
is submitted, the e-mail will first be accepted by the mailing list
server, and, after a while, it should appear at:
- https://patchwork.linuxtv.org/project/linux-media/list/
If it doesn't automatically appear there after some time [3]_, then
probably something went wrong on your submission. Please check if the
email is in plain text\ [4]_ only and if your emailer is not mangling
whitespaces before complaining or submitting them again.
To troubleshoot problems, you should first check if the mailing list
server has accepted your patch, by looking at:
- https://lore.kernel.org/linux-media/
If the patch is there and not at
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_,
it is likely that your e-mailer mangled the patch. Patchwork internally
has logic that checks if the received e-mail contains a valid patch.
Any whitespace and new line breakages mangling the patch won't be recognized by
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_,
and such a patch will be rejected.
.. [3] It usually takes a few minutes for the patch to arrive, but
the e-mail server may be busy, so it may take a longer time
for a patch to be picked by
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_.
.. [4] If your email contains HTML, the mailing list server will simply
drop it, without any further notice.
.. _media-developers-gpg:
Authentication for pull and merge requests
++++++++++++++++++++++++++++++++++++++++++
The authenticity of developers submitting Pull Requests and merge requests
shall be validated by using the Linux Kernel Web of Trust, with PGP signing
at some moment. See: :ref:`kernel_org_trust_repository`.
With the Pull Request workflow, Pull Requests shall use PGP-signed tags.
With the committers' workflow, this is ensured at the time merge request
rights will be granted to the gitlab instance used by the media-committers.git
tree, after receiving the e-mail documented in
:ref:`media-committer-agreement`.
For more details about PGP signing, please read
Documentation/process/maintainer-pgp-guide.rst.
Maintaining media maintainer status
-----------------------------------
See :ref:`Maintain Media Status`.
List of Media Maintainers
-------------------------
The Media Maintainers listed here all have patchwork access and can
make Pull Requests or have commit rights.
The Media Subsystem Maintainers are:
- Mauro Carvalho Chehab <mchehab@kernel.org>
- Hans Verkuil <hverkuil@kernel.org>
The Media Core Maintainers are:
- Sakari Ailus <sakari.ailus@linux.intel.com>
- Media controller drivers
- Core media controller framework
- ISP
- sensor drivers
- v4l2-async and v4l2-fwnode core frameworks
- v4l2-flash-led-class core framework
- Mauro Carvalho Chehab <mchehab@kernel.org>
- DVB
- Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Media controller drivers
- Core media controller framework
- ISP
- Hans Verkuil <hverkuil@kernel.org>
- V4L2 drivers
- V4L2 and videobuf2 core frameworks
- HDMI CEC drivers
- HDMI CEC core framework
- Sean Young <sean@mess.org>
- Remote Controller (infrared) drivers
- Remote Controller (infrared) core framework
The Media Driver Maintainers responsible for specific areas are:
- Nicolas Dufresne <nicolas.dufresne@collabora.com>
- Codec drivers
- M2M driver not otherwise delegated
- Bryan O'Donoghue <bryan.odonoghue@linaro.org>
- Qualcomm drivers
Submit Checklist Addendum
-------------------------
Patches that change the Open Firmware/Device Tree bindings must be
reviewed by the Device Tree maintainers. So, DT maintainers should be
Cc:ed when those are submitted via devicetree@vger.kernel.org mailing
list.
There is a set of compliance tools at https://git.linuxtv.org/v4l-utils.git/
that should be used in order to check if the drivers are properly
implementing the media APIs:
==================== =======================================================
Type Utility
==================== =======================================================
V4L2 drivers\ [5]_ ``v4l2-compliance``
V4L2 virtual drivers ``contrib/test/test-media``
CEC drivers ``cec-compliance``
==================== =======================================================
.. [5] The ``v4l2-compliance`` utility also covers the media controller usage
inside V4L2 drivers.
Those tests need to pass before the patches go upstream.
Also, please notice that we build the Kernel with::
make CF=-D__CHECK_ENDIAN__ CONFIG_DEBUG_SECTION_MISMATCH=y C=1 W=1 CHECK=check_script
Where the check script is::
#!/bin/bash
/devel/smatch/smatch -p=kernel $@ >&2
/devel/sparse/sparse $@ >&2
Be sure to not introduce new warnings on your patches without a
very good reason.
Please see `Media development workflow`_ for e-mail submission rules.
Style Cleanup Patches
+++++++++++++++++++++
Style cleanups are welcome when they come together with other changes
at the files where the style changes will affect.
We may accept pure standalone style cleanups, but they should ideally
be one patch for the whole subsystem (if the cleanup is low volume),
or at least be grouped per directory. So, for example, if you're doing a
big cleanup change set at drivers under drivers/media, please send a single
patch for all drivers under drivers/media/pci, another one for
drivers/media/usb and so on.
Coding Style Addendum
+++++++++++++++++++++
Media development uses ``checkpatch.pl`` on strict mode to verify the code
style, e.g.::
$ ./scripts/checkpatch.pl --strict --max-line-length=80
In principle, patches should follow the coding style rules, but exceptions
are allowed if there are good reasons. On such case, maintainers and reviewers
may question about the rationale for not addressing the ``checkpatch.pl``.
Please notice that the goal here is to improve code readability. On
a few cases, ``checkpatch.pl`` may actually point to something that would
look worse. So, you should use good sense.
Note that addressing one ``checkpatch.pl`` issue (of any kind) alone may lead
to having longer lines than 80 characters per line. While this is not
strictly prohibited, efforts should be made towards staying within 80
characters per line. This could include using re-factoring code that leads
to less indentation, shorter variable or function names and last but not
least, simply wrapping the lines.
In particular, we accept lines with more than 80 columns:
- on strings, as they shouldn't be broken due to line length limits;
- when a function or variable name needs to have a long identifier name,
which makes hard to honor the 80 columns limit;
- on arithmetic expressions, when breaking lines makes them harder to
read;
- when they avoid a line ending with an open parenthesis or an open
bracket.
Key Cycle Dates
---------------
New submissions can be sent at any time, but if they are intended to hit the
next merge window they should be sent before -rc5, and ideally stabilized
in the linux-media branch by -rc6.
Review Cadence
--------------
Provided that your patch has landed in
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_, it
should be sooner or later handled, so you don't need to re-submit a patch.
Except for important bug fixes, we don't usually add new patches to the
development tree between -rc6 and the next -rc1.
Please notice that the media subsystem is a high traffic one, so it
could take a while for us to be able to review your patches. Feel free
to ping if you don't get a feedback in a couple of weeks or to ask
other developers to publicly add ``Reviewed-by:`` and, more importantly,
``Tested-by:`` tags.
Please note that we expect a detailed description for ``Tested-by:``,
identifying what boards were used during the test and what it was tested.
@@ -0,0 +1,341 @@
.. 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 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 initialise media device instances by calling
:c:func:`media_device_init()`. After initialising a media device instance, it is
registered by calling :c:func:`__media_device_register()` via the macro
``media_device_register()`` and unregistered by calling
:c:func:`media_device_unregister()`. An initialised media device must be
eventually cleaned up by calling :c:func:`media_device_cleanup()`.
Note that it is not allowed to unregister a media device instance that was not
previously registered, or clean up a media device instance that was not
previously initialised.
Entities
^^^^^^^^
Entities are represented by a struct 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 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 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 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 media_pad,
making the struct 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 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 traverse media graphs, locating connected
entities and links.
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
...
}
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()`, :c:func:`media_pad_remote_pad_first()`,
:c:func:`media_entity_remote_source_pad_unique()` and
:c:func:`media_pad_remote_pad_unique()`).
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 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
^^^^^^^^^^^^^^^^^^^^^^^^^^^
A media stream is a stream of pixels or metadata originating from one or more
source devices (such as a sensors) and flowing through media entity pads
towards the final sinks. The stream can be modified on the route by the
devices (e.g. scaling or pixel format conversions), or it can be split into
multiple branches, or multiple branches can be merged.
A media pipeline is a set of media streams which are interdependent. This
interdependency can be caused by the hardware (e.g. configuration of a second
stream cannot be changed if the first stream has been enabled) or by the driver
due to the software design. Most commonly a media pipeline consists of a single
stream which does not branch.
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 the pads which are part of the pipeline as streaming.
The struct media_pipeline instance pointed to by the pipe argument will be
stored in every pad in the pipeline. Drivers should embed the struct
media_pipeline in higher-level pipeline structures and can then access the
pipeline through the struct media_pad 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.
Pipeline traversal
^^^^^^^^^^^^^^^^^^
Once a pipeline has been constructed with :c:func:`media_pipeline_start()`,
drivers can iterate over entities or pads in the pipeline with the
:c:macro:´media_pipeline_for_each_entity` and
:c:macro:´media_pipeline_for_each_pad` macros. Iterating over pads is
straightforward:
.. code-block:: c
media_pipeline_pad_iter iter;
struct media_pad *pad;
media_pipeline_for_each_pad(pipe, &iter, pad) {
/* 'pad' will point to each pad in turn */
...
}
To iterate over entities, the iterator needs to be initialized and cleaned up
as an additional steps:
.. code-block:: c
media_pipeline_entity_iter iter;
struct media_entity *entity;
int ret;
ret = media_pipeline_entity_iter_init(pipe, &iter);
if (ret)
...;
media_pipeline_for_each_entity(pipe, &iter, entity) {
/* 'entity' will point to each entity in turn */
...
}
media_pipeline_entity_iter_cleanup(&iter);
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
@@ -0,0 +1,203 @@
.. SPDX-License-Identifier: GPL-2.0
.. _Media Committers:
Media Committers
================
Who is a Media Committer?
-------------------------
A Media Committer is a Media Maintainer with patchwork access who has been
granted commit access to push patches from other developers and their own
patches to the
`media-committers <https://gitlab.freedesktop.org/linux-media/media-committers>`_
tree.
These commit rights are granted with expectation of responsibility:
committers are people who care about the Linux Kernel as a whole and
about the Linux media subsystem and want to advance its development. It
is also based on a trust relationship among other committers, maintainers
and the Linux Media community.
As Media Committer you have the following additional responsibilities:
1. Patches you authored must have a ``Signed-off-by``, ``Reviewed-by``
or ``Acked-by`` from another Media Maintainer;
2. If a patch introduces a regression, then that must be corrected as soon
as possible. Typically the patch is either reverted, or an additional
patch is committed to fix the regression;
3. If patches are fixing bugs against already released Kernels, including
the reverts mentioned above, the Media Committer shall add the needed
tags. Please see :ref:`Media development workflow` for more details.
4. All Media Committers are responsible for maintaining
`Patchwork <https://patchwork.linuxtv.org/project/linux-media/list/>`_,
updating the state of the patches they review or merge.
Becoming a Media Committer
--------------------------
Existing Media Committers can nominate a Media Maintainer to be granted
commit rights. The Media Maintainer must have patchwork access,
have been reviewing patches from third parties for some time, and has
demonstrated a good understanding of the maintainer's duties and processes.
The ultimate responsibility for accepting a nominated committer is up to
the Media Subsystem Maintainers. The nominated committer must have earned a
trust relationship with all Media Subsystem Maintainers, as, by granting you
commit rights, part of their responsibilities are handed over to you.
Due to that, to become a Media Committer, a consensus between all Media
Subsystem Maintainers is required.
.. Note::
In order to preserve/protect the developers that could have their commit
rights granted, denied or removed as well as the subsystem maintainers who
have the task to accept or deny commit rights, all communication related to
changing commit rights should happen in private as much as possible.
.. _media-committer-agreement:
Media Committer's agreement
---------------------------
Once a nominated committer is accepted by all Media Subsystem Maintainers,
they will ask if the developer is interested in the nomination and discuss
what area(s) of the media subsystem the committer will be responsible for.
Those areas will typically be the same as the areas that the nominated
committer is already maintaining.
When the developer accepts being a committer, the new committer shall
explicitly accept the Kernel development policies described under its
Documentation/, and in particular to the rules in this document, by writing
an e-mail to media-committers@linuxtv.org, with a declaration of intent
following the model below::
I, John Doe, would like to change my status to: Committer
As Media Maintainer I accept commit rights for the following areas of
the media subsystem:
...
For the purpose of committing patches to the media-committers tree,
I'll be using my user https://gitlab.freedesktop.org/users/<username>.
Followed by a formal declaration of agreement with the Kernel development
rules::
I agree to follow the Kernel development rules described at:
https://www.kernel.org/doc/html/latest/driver-api/media/media-committers.rst
and to the Linux Kernel development process rules.
I agree to abide by the Code of Conduct as documented in:
https://www.kernel.org/doc/html/latest/process/code-of-conduct.rst
I am aware that I can, at any point of time, retire. In that case, I will
send an e-mail to notify the Media Subsystem Maintainers for them to revoke
my commit rights.
I am aware that the Kernel development rules change over time.
By doing a new push to media-committers tree, I understand that I agree
to follow the rules in effect at the time of the commit.
That e-mail shall be signed via the Kernel Web of trust with a PGP key cross
signed by other Kernel and media developers. As described at
:ref:`media-developers-gpg`, the PGP signature, together with the gitlab user
security are fundamental components that ensure the authenticity of the merge
requests that will happen at the media-committers.git tree.
In case the kernel development process changes, by merging new commits to the
`media-committers tree <https://gitlab.freedesktop.org/linux-media/media-committers>`_,
the Media Committer implicitly declares their agreement with the latest
version of the documented process including the contents of this file.
If a Media Committer decides to retire, it is the committer's duty to
notify the Media Subsystem Maintainers about that decision.
.. note::
1. Changes to the kernel media development process shall be announced in
the media-committers mailing list with a reasonable review period. All
committers are automatically subscribed to that mailing list;
2. Due to the distributed nature of the Kernel development, it is
possible that kernel development process changes may end being
reviewed/merged at the Linux Docs and/or at the Linux Kernel mailing
lists, especially for the contents under Documentation/process and for
trivial typo fixes.
Media Core Committers
---------------------
A Media Core Committer is a Media Core Maintainer with commit rights.
As described in Documentation/driver-api/media/maintainer-entry-profile.rst,
a Media Core Maintainer maintains media core frameworks as well, besides
just drivers, and so is allowed to change core files and the media subsystem's
Kernel API. The extent of the core committer's grants will be detailed by the
Media Subsystem Maintainers when they nominate a Media Core Committer.
Existing Media Committers may become Media Core Committers and vice versa.
Such decisions will be taken in consensus among the Media Subsystem
Maintainers.
Media committers rules
----------------------
Media committers shall do their best efforts to avoid merging patches that
would break any existing drivers. If it breaks, fixup or revert patches
shall be merged as soon as possible, aiming to be merged at the same Kernel
cycle the bug is reported.
Media committers shall behave accordingly to the rights granted by
the Media Subsystem Maintainers, especially with regards of the scope of changes
they may apply directly at the media-committers tree. That scope can
change over time on a mutual agreement between Media Committers and
Media Subsystem Maintainers.
The Media Committer workflow is described at :ref:`Media development workflow`.
.. _Maintain Media Status:
Maintaining Media Maintainer or Committer status
------------------------------------------------
A community of maintainers working together to move the Linux Kernel
forward is essential to creating successful projects that are rewarding
to work on. If there are problems or disagreements within the community,
they can usually be solved through healthy discussion and debate.
In the unhappy event that a Media Maintainer or Committer continues to
disregard good citizenship (or actively disrupts the project), we may need
to revoke that person's status. In such cases, if someone suggests the
revocation with a good reason, then after discussing this among the Media
Maintainers, the final decision is taken by the Media Subsystem Maintainers.
As the decision to become a Media Maintainer or Committer comes from a
consensus between Media Subsystem Maintainers, a single Media Subsystem
Maintainer not trusting the Media Maintainer or Committer anymore is enough
to revoke their maintenance, Patchwork grants and/or commit rights.
Having commit rights revoked doesn't prevent Media Maintainers to keep
contributing to the subsystem either via the pull request or via email workflow
as documented at the :ref:`Media development workflow`.
If a maintainer is inactive for more than a couple of Kernel cycles,
maintainers will try to reach you via e-mail. If not possible, they may
revoke their maintainer/patchwork and committer rights and update MAINTAINERS
file entries accordingly. If you wish to resume contributing as maintainer
later on, then contact the Media Subsystem Maintainers to ask if your
maintenance, Patchwork grants and commit rights can be restored.
References
----------
Much of this was inspired by/copied from the committer policies of:
- `Chromium <https://chromium.googlesource.com/chromium/src/+/main/docs/contributing.md>`_;
- `WebKit <https://webkit.org/commit-and-review-policy/>`_;
- `Mozilla <https://www.mozilla.org/hacking/committer/>`_.
@@ -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
@@ -0,0 +1,145 @@
.. SPDX-License-Identifier: GPL-2.0
.. _transmitter-receiver:
Pixel data transmitter and receiver drivers
===========================================
V4L2 supports various devices that transmit and receive pixel data. Examples of
these devices include a camera sensor, a TV tuner and a parallel, a BT.656 or a
CSI-2 receiver in an SoC.
Bus types
---------
The following buses are the most common. This section discusses these two only.
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`: https://www.mipi.org/
Parallel and BT.656
^^^^^^^^^^^^^^^^^^^
The parallel and `BT.656`_ buses transport one bit of data on each clock cycle
per data line. The parallel bus uses synchronisation and other additional
signals whereas BT.656 embeds synchronisation.
.. _`BT.656`: https://en.wikipedia.org/wiki/ITU-R_BT.656
Transmitter drivers
-------------------
Transmitter drivers generally need to provide the receiver drivers with the
configuration of the transmitter. What is required depends on the type of the
bus. These are common for both buses.
Media bus pixel code
^^^^^^^^^^^^^^^^^^^^
See :ref:`v4l2-mbus-pixelcode`.
Link frequency
^^^^^^^^^^^^^^
The :ref:`V4L2_CID_LINK_FREQ <v4l2-cid-link-freq>` control is used to tell the
receiver the frequency of the bus (i.e. it is not the same as the symbol rate).
Drivers that do not have user-configurable link frequency should report it
through the ``.get_mbus_config()`` subdev pad operation, in the ``link_freq``
field of struct v4l2_mbus_config, instead of through controls.
Receiver drivers should use :c:func:`v4l2_get_link_freq` helper to obtain the
link frequency from the transmitter sub-device.
``.enable_streams()`` and ``.disable_streams()`` callbacks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The struct v4l2_subdev_pad_ops->enable_streams() and struct
v4l2_subdev_pad_ops->disable_streams() callbacks are used by the receiver driver
to control the transmitter driver's streaming state. These callbacks may not be
called directly, but by using ``v4l2_subdev_enable_streams()`` and
``v4l2_subdev_disable_streams()``.
Stopping the transmitter
^^^^^^^^^^^^^^^^^^^^^^^^
A transmitter stops sending the stream of images as a result of
calling the ``.disable_streams()`` 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.
CSI-2 transmitter drivers
-------------------------
Pixel rate
^^^^^^^^^^
The pixel rate on the bus is calculated as follows::
pixel_rate = link_freq * 2 * nr_of_lanes * 16 / k / bits_per_sample
where
.. list-table:: variables in pixel rate calculation
:header-rows: 1
* - variable or constant
- description
* - link_freq
- The value of the :ref:`V4L2_CID_LINK_FREQ <v4l2-cid-link-freq>` integer64
menu item.
* - nr_of_lanes
- Number of data lanes used on the CSI-2 link.
* - 2
- Data is transferred on both rising and falling edge of the signal.
* - bits_per_sample
- Number of bits per sample.
* - k
- 16 for D-PHY and 7 for C-PHY.
Information on whether D-PHY or C-PHY is used, and the value of ``nr_of_lanes``, can be obtained from the OF endpoint configuration.
.. note::
The pixel rate calculated this way is **not** the same thing as the
pixel rate on the camera sensor's pixel array which is indicated by the
:ref:`V4L2_CID_PIXEL_RATE <v4l2-cid-pixel-rate>` control.
LP-11 and LP-111 states
^^^^^^^^^^^^^^^^^^^^^^^
As part of transitioning to high speed mode, a CSI-2 transmitter typically
briefly sets the bus to LP-11 or LP-111 state, depending on the PHY. This period
may be as short as 100 µs, during which the receiver observes this state and
proceeds its own part of high speed mode transition.
Most receivers are capable of autonomously handling this once the software has
configured them to do so, but there are receivers which require software
involvement in observing LP-11 or LP-111 state. 100 µs is a brief period to hit
in software, especially when there is no interrupt telling something is
happening.
One way to address this is to configure the transmitter side explicitly to LP-11
or LP-111 state, which requires support from the transmitter hardware. This is
not universally available. Many devices return to this state once streaming is
stopped while the state after power-on is LP-00 or LP-000.
The ``.pre_streamon()`` callback may be used to prepare a transmitter for
transitioning to streaming state, but not yet start streaming. Similarly, the
``.post_streamoff()`` callback is used to undo what was done by the
``.pre_streamon()`` callback. The caller of ``.pre_streamon()`` is thus required
to call ``.post_streamoff()`` for each successful call of ``.pre_streamon()``.
In the context of CSI-2, the ``.pre_streamon()`` callback is used to transition
the transmitter to the LP-11 or LP-111 state. This also requires powering on the
device, so this should be only done when it is needed.
Receiver drivers that do not need explicit LP-11 or LP-111 state setup are
waived from calling the two callbacks.
@@ -0,0 +1,5 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 async kAPI
^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-async.h
@@ -0,0 +1,5 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 CCI kAPI
^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-cci.h
@@ -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
@@ -0,0 +1,820 @@
.. 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 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);
:c:func:`v4l2_ctrl_handler_free` does not touch the handler's ``error`` field.
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)
return v4l2_ctrl_handler_free(&foo->ctrl_handler);
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, 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
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
@@ -0,0 +1,30 @@
.. 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-videobuf2
v4l2-dv-timings
v4l2-flash-led-class
v4l2-mc
v4l2-mediabus
v4l2-mem2mem
v4l2-async
v4l2-fwnode
v4l2-cci
v4l2-rect
v4l2-tuner
v4l2-common
v4l2-tveeprom
v4l2-jpeg
v4l2-isp
@@ -0,0 +1,367 @@
.. 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 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 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 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 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``.
In the case of :ref:`videobuf2 <vb2_framework>` you must set the ``queue->lock``
pointer to the lock you use to serialize the queuing ioctls. This ensures that
that lock is released while waiting in ``VIDIOC_DQBUF`` for a buffer to arrive,
and it is retaken afterwards.
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
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
@@ -0,0 +1,146 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 device instance
--------------------
Each device instance is represented by a struct 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 v4l2_device instance. This is achieved by a
``dev_set_drvdata()`` call before registering the V4L2 device instance.
They must also set the struct 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
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 DV Timings functions
^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-dv-timings.h
@@ -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 v4l2_fh has two lists: one of the ``subscribed`` events,
and one of the ``available`` events.
- struct v4l2_subscribed_event has a ringbuffer of raised
(pending) events of that particular type.
- If struct v4l2_subscribed_event is associated with a specific
object, then that object will have an internal list of
struct v4l2_subscribed_event so it knows who subscribed an
event to that object.
Furthermore, the internal struct 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/ti/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
@@ -0,0 +1,136 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 File handles
-----------------
struct v4l2_fh provides a way to easily keep file handle specific data that is
used by the V4L2 framework. Its usage is mandatory in all drivers.
struct v4l2_fh is allocated in the driver's ``open()`` file operation handler.
It is typically embedded in a larger driver-specific structure. The
:c:type:`v4l2_fh` must be initialized with a call to :c:func:`v4l2_fh_init`,
and added to the video device with :c:func:`v4l2_fh_add`. This associates the
:c:type:`v4l2_fh` with the :c:type:`file` by setting ``file->private_data`` to
point to the :c:type:`v4l2_fh`.
Similarly, the struct v4l2_fh is freed in the driver's ``release()`` file
operation handler. It must be removed from the video device with
:c:func:`v4l2_fh_del` and cleaned up with :c:func:`v4l2_fh_exit` before being
freed.
Drivers must not access ``file->private_data`` directly. They can retrieve the
:c:type:`v4l2_fh` associated with a :c:type:`file` by calling
:c:func:`file_to_v4l2_fh`. 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_obj(*my_fh);
...
v4l2_fh_init(&my_fh->fh, vfd);
...
v4l2_fh_add(&my_fh->fh, file);
return 0;
}
int my_release(struct file *file)
{
struct v4l2_fh *fh = file_to_v4l2_fh(file);
struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
...
v4l2_fh_del(&my_fh->fh, file);
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>`, struct file \*filp)
- 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>`, struct file \*filp)
- 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.
:c:func:`file_to_v4l2_fh <file_to_v4l2_fh>`
(struct file \*filp)
- Retrieve the :c:type:`v4l2_fh` instance associated with a :c:type:`file`.
If struct 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 v4l2_fh, initializes it and adds it to
the struct video_device associated with the file struct.
:c:func:`v4l2_fh_release <v4l2_fh_release>`
(struct file \*filp)
- This deletes it from the struct 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
@@ -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
@@ -0,0 +1,5 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 fwnode kAPI
^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-fwnode.h
@@ -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.
@@ -0,0 +1,49 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 generic ISP parameters and statistics support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Design rationale
================
ISP configuration parameters and statistics are processed and collected by
drivers and exchanged with userspace through data types that usually
reflect the ISP peripheral registers layout.
Each ISP driver defines its own metadata output format for parameters and
a metadata capture format for statistics. The buffer layout is realized by a
set of C structures that reflects the registers layout. The number and types
of C structures is fixed by the format definition and becomes part of the Linux
kernel uAPI/uABI interface.
Because of the hard requirement of backward compatibility when extending the
user API/ABI interface, modifying an ISP driver capture or output metadata
format after it has been accepted by mainline is very hard if not impossible.
It generally happens, in fact, that after the first accepted revision of an ISP
driver the buffers layout need to be modified, either to support new hardware
blocks, to fix bugs or to support different revisions of the hardware.
Each of these situations would require defining a new metadata format, making it
really hard to maintain and extend drivers and requiring userspace to use
the correct format depending on the kernel revision in use.
V4L2 ISP configuration parameters
=================================
For these reasons, Video4Linux2 defines generic types for ISP configuration
parameters and statistics. Drivers are still expected to define their own
formats for their metadata output and capture nodes, but the buffers layout can
be defined using the extensible and versioned types defined by
include/uapi/linux/media/v4l2-isp.h.
Drivers are expected to provide the definitions of their supported ISP blocks
and the expected maximum size of a buffer.
For driver developers a set of helper functions to assist them with validation
of the buffer received from userspace is available in
drivers/media/v4l2-core/v4l2-isp.c
V4L2 ISP support driver documentation
=====================================
.. kernel-doc:: include/media/v4l2-isp.h
@@ -0,0 +1,10 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 JPEG header related functions and data structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-jpeg.h
:internal:
.. kernel-doc:: drivers/media/v4l2-core/v4l2-jpeg.c
:export:
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 Media Controller functions and data structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-mc.h
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 Media Bus functions and data structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-mediabus.h
@@ -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
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
V4L2 rect helper functions
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-rect.h
@@ -0,0 +1,644 @@
.. 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 exist 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 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 a sub-device driver implements sink pads, the subdev driver may set the
link_validate field in :c:type:`v4l2_subdev_pad_ops` to provide its own link
validation function. For every link in the pipeline, the link_validate pad
operation of the sink end of the link is called. In both cases 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.
Subdev registration
~~~~~~~~~~~~~~~~~~~
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.
Registering synchronous sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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``.
.. _media-registering-async-subdevs:
Registering asynchronous sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
Drivers must complete all initialization of the sub-device before
registering it using :c:func:`v4l2_async_register_subdev`, including
enabling runtime PM. This is because the sub-device becomes accessible
as soon as it gets registered.
Asynchronous sub-device notifiers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Bridge drivers in turn have to register a notifier object. This is performed
using the :c:func:`v4l2_async_nf_register` call. To unregister the notifier the
driver has to call :c:func:`v4l2_async_nf_unregister`. Before releasing memory
of an unregister notifier, it must be cleaned up by calling
:c:func:`v4l2_async_nf_cleanup`.
Before registering the notifier, bridge drivers must do two things: first, the
notifier must be initialized using the :c:func:`v4l2_async_nf_init`. Second,
bridge drivers can then begin to form a list of async connection descriptors
that the bridge device needs for its
operation. :c:func:`v4l2_async_nf_add_fwnode`,
:c:func:`v4l2_async_nf_add_fwnode_remote` and :c:func:`v4l2_async_nf_add_i2c`
Async connection descriptors describe connections to external sub-devices the
drivers for which are not yet probed. Based on an async connection, a media data
or ancillary link may be created when the related sub-device becomes
available. There may be one or more async connections to a given sub-device but
this is not known at the time of adding the connections to the notifier. Async
connections are bound as matching async sub-devices are found, one by one.
Asynchronous sub-device notifier for sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A driver that registers an asynchronous sub-device may also register an
asynchronous notifier. This is called an asynchronous sub-device notifier and the
process is similar to that of a bridge driver apart from that the notifier is
initialised using :c:func:`v4l2_async_subdev_nf_init` instead. A sub-device
notifier may complete only after the V4L2 device becomes available, i.e. there's
a path via async sub-devices and notifiers to a notifier that is not an
asynchronous sub-device notifier.
Asynchronous sub-device registration helper for camera sensor drivers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:c:func:`v4l2_async_register_subdev_sensor` is a helper function for sensor
drivers registering their own async connection, but it also registers a notifier
and further registers async connections for lens and flash devices found in
firmware. The notifier for the sub-device is unregistered and cleaned up with
the async sub-device, using :c:func:`v4l2_async_unregister_subdev`.
Asynchronous sub-device notifier example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These functions allocate an async connection descriptor which is of type struct
:c:type:`v4l2_async_connection` embedded in a driver-specific struct. The &struct
:c:type:`v4l2_async_connection` shall be the first member of this struct:
.. code-block:: c
struct my_async_connection {
struct v4l2_async_connection asc;
...
};
struct my_async_connection *my_asc;
struct fwnode_handle *ep;
...
my_asc = v4l2_async_nf_add_fwnode_remote(&notifier, ep,
struct my_async_connection);
fwnode_handle_put(ep);
if (IS_ERR(my_asc))
return PTR_ERR(my_asc);
Asynchronous sub-device notifier callbacks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The V4L2 core will then use these connection descriptors to match asynchronously
registered subdevices to them. If a match is detected the ``.bound()`` notifier
callback is called. After all connections have been bound the .complete()
callback is called. When a connection is removed from the system the
``.unbind()`` method is called. All three callbacks are optional.
Drivers can store any type of custom data in their driver-specific
:c:type:`v4l2_async_connection` wrapper. If any of that data requires special
handling when the structure is freed, drivers must implement the ``.destroy()``
notifier callback. The framework will call it right before freeing the
:c:type:`v4l2_async_connection`.
Calling subdev operations
~~~~~~~~~~~~~~~~~~~~~~~~~
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.
Once the subdev has been registered 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 do 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.
V4L2 sub-device userspace API
-----------------------------
Bridge drivers traditionally expose one or multiple video nodes to userspace,
and control subdevices through the :c:type:`v4l2_subdev_ops` operations in
response to video node operations. This hides the complexity of the underlying
hardware from applications. For complex devices, finer-grained control of the
device than what the video nodes offer may be required. In those cases, bridge
drivers that implement :ref:`the media controller API <media_controller>` may
opt for making the subdevice operations directly accessible from userspace.
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_FL_HAS_EVENTS`` :c:type:`v4l2_subdev`.flags 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.
Read-only sub-device userspace API
----------------------------------
Bridge drivers that control their connected subdevices through direct calls to
the kernel API realized by :c:type:`v4l2_subdev_ops` structure do not usually
want userspace to be able to change the same parameters through the subdevice
device node and thus do not usually register any.
It is sometimes useful to report to userspace the current subdevice
configuration through a read-only API, that does not permit applications to
change to the device parameters but allows interfacing to the subdevice device
node to inspect them.
For instance, to implement cameras based on computational photography, userspace
needs to know the detailed camera sensor configuration (in terms of skipping,
binning, cropping and scaling) for each supported output resolution. To support
such use cases, bridge drivers may expose the subdevice operations to userspace
through a read-only API.
To create a read-only device node for all the subdevices registered with the
``V4L2_SUBDEV_FL_HAS_DEVNODE`` set, the :c:type:`v4l2_device` driver should call
:c:func:`v4l2_device_register_ro_subdev_nodes`.
Access to the following ioctls for userspace applications is restricted on
sub-device device nodes registered with
:c:func:`v4l2_device_register_ro_subdev_nodes`.
``VIDIOC_SUBDEV_S_FMT``,
``VIDIOC_SUBDEV_S_CROP``,
``VIDIOC_SUBDEV_S_SELECTION``:
These ioctls are only allowed on a read-only subdevice device node
for the :ref:`V4L2_SUBDEV_FORMAT_TRY <v4l2-subdev-format-whence>`
formats and selection rectangles.
``VIDIOC_SUBDEV_S_FRAME_INTERVAL``,
``VIDIOC_SUBDEV_S_DV_TIMINGS``,
``VIDIOC_SUBDEV_S_STD``:
These ioctls are not allowed on a read-only subdevice node.
In case the ioctl is not allowed, or the format to modify is set to
``V4L2_SUBDEV_FORMAT_ACTIVE``, the core returns a negative error code and
the errno variable is set to ``-EPERM``.
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_client_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.
Centrally managed subdev active state
-------------------------------------
Traditionally V4L2 subdev drivers maintained internal state for the active
device configuration. This is often implemented as e.g. an array of struct
v4l2_mbus_framefmt, one entry for each pad, and similarly for crop and compose
rectangles.
In addition to the active configuration, each subdev file handle has a struct
v4l2_subdev_state, managed by the V4L2 core, which contains the try
configuration.
To simplify the subdev drivers the V4L2 subdev API now optionally supports a
centrally managed active configuration represented by
:c:type:`v4l2_subdev_state`. One instance of state, which contains the active
device configuration, is stored in the sub-device itself as part of
the :c:type:`v4l2_subdev` structure, while the core associates a try state to
each open file handle, to store the try configuration related to that file
handle.
Sub-device drivers can opt-in and use state to manage their active configuration
by initializing the subdevice state with a call to v4l2_subdev_init_finalize()
before registering the sub-device. They must also call v4l2_subdev_cleanup()
to release all the allocated resources before unregistering the sub-device.
The core automatically allocates and initializes a state for each open file
handle to store the try configurations and frees it when closing the file
handle.
V4L2 sub-device operations that use both the :ref:`ACTIVE and TRY formats
<v4l2-subdev-format-whence>` receive the correct state to operate on through
the 'state' parameter. The state must be locked and unlocked by the
caller by calling :c:func:`v4l2_subdev_lock_state()` and
:c:func:`v4l2_subdev_unlock_state()`. The caller can do so by calling the subdev
operation through the :c:func:`v4l2_subdev_call_state_active()` macro.
Operations that do not receive a state parameter implicitly operate on the
subdevice active state, which drivers can exclusively access by
calling :c:func:`v4l2_subdev_lock_and_get_active_state()`. The sub-device active
state must equally be released by calling :c:func:`v4l2_subdev_unlock_state()`.
Drivers must never manually access the state stored in the :c:type:`v4l2_subdev`
or in the file handle without going through the designated helpers.
While the V4L2 core passes the correct try or active state to the subdevice
operations, many existing device drivers pass a NULL state when calling
operations with :c:func:`v4l2_subdev_call()`. This legacy construct causes
issues with subdevice drivers that let the V4L2 core manage the active state,
as they expect to receive the appropriate state as a parameter. To help the
conversion of subdevice drivers to a managed active state without having to
convert all callers at the same time, an additional wrapper layer has been
added to v4l2_subdev_call(), which handles the NULL case by getting and locking
the callee's active state with :c:func:`v4l2_subdev_lock_and_get_active_state()`,
and unlocking the state after the call.
The whole subdev state is in reality split into three parts: the
v4l2_subdev_state, subdev controls and subdev driver's internal state. In the
future these parts should be combined into a single state. For the time being
we need a way to handle the locking for these parts. This can be accomplished
by sharing a lock. The v4l2_ctrl_handler already supports this via its 'lock'
pointer and the same model is used with states. The driver can do the following
before calling v4l2_subdev_init_finalize():
.. code-block:: c
sd->ctrl_handler->lock = &priv->mutex;
sd->state_lock = &priv->mutex;
This shares the driver's private mutex between the controls and the states.
Streams, multiplexed media pads and internal routing
----------------------------------------------------
A subdevice driver can implement support for multiplexed streams by setting
the V4L2_SUBDEV_FL_STREAMS subdev flag and implementing support for
centrally managed subdev active state, routing and stream based
configuration.
V4L2 sub-device functions and data structures
---------------------------------------------
.. kernel-doc:: include/media/v4l2-subdev.h
@@ -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
@@ -0,0 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0
Hauppauge TV EEPROM functions and data structures
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/tveeprom.h
@@ -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