summaryrefslogtreecommitdiffstats
path: root/Documentation/driver-api/media
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
commitace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch)
treeb2d64bc10158fdd5497876388cd68142ca374ed3 /Documentation/driver-api/media
parentInitial commit. (diff)
downloadlinux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz
linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'Documentation/driver-api/media')
-rw-r--r--Documentation/driver-api/media/camera-sensor.rst175
-rw-r--r--Documentation/driver-api/media/cec-core.rst502
-rw-r--r--Documentation/driver-api/media/drivers/bttv-devel.rst116
-rw-r--r--Documentation/driver-api/media/drivers/ccs/ccs-regs.asc1041
-rw-r--r--Documentation/driver-api/media/drivers/ccs/ccs.rst117
-rwxr-xr-xDocumentation/driver-api/media/drivers/ccs/mk-ccs-regs434
-rw-r--r--Documentation/driver-api/media/drivers/contributors.rst131
-rw-r--r--Documentation/driver-api/media/drivers/cx2341x-devel.rst3685
-rw-r--r--Documentation/driver-api/media/drivers/cx88-devel.rst113
-rw-r--r--Documentation/driver-api/media/drivers/dvb-usb.rst357
-rw-r--r--Documentation/driver-api/media/drivers/fimc-devel.rst33
-rw-r--r--Documentation/driver-api/media/drivers/frontends.rst32
-rw-r--r--Documentation/driver-api/media/drivers/index.rst40
-rw-r--r--Documentation/driver-api/media/drivers/pvrusb2.rst202
-rw-r--r--Documentation/driver-api/media/drivers/pxa_camera.rst194
-rw-r--r--Documentation/driver-api/media/drivers/radiotrack.rst168
-rw-r--r--Documentation/driver-api/media/drivers/rkisp1.rst43
-rw-r--r--Documentation/driver-api/media/drivers/saa7134-devel.rst67
-rw-r--r--Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst142
-rw-r--r--Documentation/driver-api/media/drivers/tuners.rst133
-rw-r--r--Documentation/driver-api/media/drivers/vidtv.rst513
-rw-r--r--Documentation/driver-api/media/drivers/vimc-devel.rst15
-rw-r--r--Documentation/driver-api/media/drivers/zoran.rst575
-rw-r--r--Documentation/driver-api/media/dtv-ca.rst6
-rw-r--r--Documentation/driver-api/media/dtv-common.rst53
-rw-r--r--Documentation/driver-api/media/dtv-core.rst39
-rw-r--r--Documentation/driver-api/media/dtv-demux.rst84
-rw-r--r--Documentation/driver-api/media/dtv-frontend.rst445
-rw-r--r--Documentation/driver-api/media/dtv-net.rst6
-rw-r--r--Documentation/driver-api/media/index.rst59
-rw-r--r--Documentation/driver-api/media/maintainer-entry-profile.rst206
-rw-r--r--Documentation/driver-api/media/mc-core.rst326
-rw-r--r--Documentation/driver-api/media/rc-core.rst88
-rw-r--r--Documentation/driver-api/media/tx-rx.rst133
-rw-r--r--Documentation/driver-api/media/v4l2-async.rst5
-rw-r--r--Documentation/driver-api/media/v4l2-cci.rst5
-rw-r--r--Documentation/driver-api/media/v4l2-common.rst8
-rw-r--r--Documentation/driver-api/media/v4l2-controls.rst823
-rw-r--r--Documentation/driver-api/media/v4l2-core.rst29
-rw-r--r--Documentation/driver-api/media/v4l2-dev.rst375
-rw-r--r--Documentation/driver-api/media/v4l2-device.rst146
-rw-r--r--Documentation/driver-api/media/v4l2-dv-timings.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-event.rst181
-rw-r--r--Documentation/driver-api/media/v4l2-fh.rst141
-rw-r--r--Documentation/driver-api/media/v4l2-flash-led-class.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-fwnode.rst5
-rw-r--r--Documentation/driver-api/media/v4l2-intro.rst76
-rw-r--r--Documentation/driver-api/media/v4l2-mc.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-mediabus.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-mem2mem.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-rect.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-subdev.rst637
-rw-r--r--Documentation/driver-api/media/v4l2-tuner.rst8
-rw-r--r--Documentation/driver-api/media/v4l2-tveeprom.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-videobuf.rst403
-rw-r--r--Documentation/driver-api/media/v4l2-videobuf2.rst12
56 files changed, 13169 insertions, 0 deletions
diff --git a/Documentation/driver-api/media/camera-sensor.rst b/Documentation/driver-api/media/camera-sensor.rst
new file mode 100644
index 0000000000..93f4f2536c
--- /dev/null
+++ b/Documentation/driver-api/media/camera-sensor.rst
@@ -0,0 +1,175 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Writing camera sensor drivers
+=============================
+
+CSI-2 and parallel (BT.601 and BT.656) busses
+---------------------------------------------
+
+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.
+
+ACPI
+~~~~
+
+Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
+can rely on this frequency being used.
+
+Devicetree
+~~~~~~~~~~
+
+The currently preferred way to achieve this is using ``assigned-clocks``,
+``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See
+``Documentation/devicetree/bindings/clock/clock-bindings.txt`` for more
+information. The driver then gets the frequency using ``clk_get_rate()``.
+
+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.
+
+Frame size
+----------
+
+There are two distinct ways to configure the frame size produced by camera
+sensors.
+
+Freely configurable camera sensor drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Freely configurable camera sensor drivers expose the device's internal
+processing pipeline as one or more sub-devices with different cropping and
+scaling configurations. The output size of the device is the result of a series
+of cropping and scaling operations from the device's pixel array's size.
+
+An example of such a driver is the CCS driver (see ``drivers/media/i2c/ccs``).
+
+Register list based drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Register list based drivers generally, instead of able to configure the device
+they control based on user requests, are limited to a number of preset
+configurations that combine a number of different parameters that on hardware
+level are independent. How a driver picks such configuration is based on the
+format set on a source pad at the end of the device's internal pipeline.
+
+Most sensor drivers are implemented this way, see e.g.
+``drivers/media/i2c/imx319.c`` for an example.
+
+Frame interval configuration
+----------------------------
+
+There are two different methods for obtaining possibilities for different frame
+intervals as well as configuring the frame interval. Which one to implement
+depends on the type of the device.
+
+Raw camera sensors
+~~~~~~~~~~~~~~~~~~
+
+Instead of a high level parameter such as frame interval, the frame interval is
+a result of the configuration of a number of camera sensor implementation
+specific parameters. Luckily, these parameters tend to be the same for more or
+less all modern raw camera sensors.
+
+The frame interval is calculated using the following equation::
+
+ frame interval = (analogue crop width + horizontal blanking) *
+ (analogue crop height + vertical blanking) / pixel rate
+
+The formula is bus independent and is applicable for raw timing parameters on
+large variety of devices beyond camera sensors. Devices that have no analogue
+crop, use the full source image size, i.e. pixel array size.
+
+Horizontal and vertical blanking are specified by ``V4L2_CID_HBLANK`` and
+``V4L2_CID_VBLANK``, respectively. The unit of the ``V4L2_CID_HBLANK`` control
+is pixels and the unit of the ``V4L2_CID_VBLANK`` is lines. The pixel rate in
+the sensor's **pixel array** is specified by ``V4L2_CID_PIXEL_RATE`` in the same
+sub-device. The unit of that control is pixels per second.
+
+Register list based drivers need to implement read-only sub-device nodes for the
+purpose. Devices that are not register list based need these to configure the
+device's internal processing pipeline.
+
+The first entity in the linear pipeline is the pixel array. The pixel array may
+be followed by other entities that are there to allow configuring binning,
+skipping, scaling or digital crop :ref:`v4l2-subdev-selections`.
+
+USB cameras etc. devices
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+USB video class hardware, as well as many cameras offering a similar higher
+level interface natively, generally use the concept of frame interval (or frame
+rate) on device level in firmware or hardware. This means lower level controls
+implemented by raw cameras may not be used on uAPI (or even kAPI) to control the
+frame interval on these devices.
+
+Power management
+----------------
+
+Always use runtime PM to manage the power states of your device. Camera sensor
+drivers are in no way special in this respect: they are responsible for
+controlling the power state of the device they otherwise control as well. In
+general, the device must be powered on at least when its registers are being
+accessed and when it is streaming.
+
+Existing camera sensor drivers may rely on the old
+struct v4l2_subdev_core_ops->s_power() callback for bridge or ISP drivers to
+manage their power state. This is however **deprecated**. If you feel you need
+to begin calling an s_power from an ISP or a bridge driver, instead please add
+runtime PM support to the sensor driver you are using. Likewise, new drivers
+should not use s_power.
+
+Please see examples in e.g. ``drivers/media/i2c/ov8856.c`` and
+``drivers/media/i2c/ccs/ccs-core.c``. The two drivers work in both ACPI
+and DT based systems.
+
+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_in_use(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
+----------------------------------
+
+Some systems have the camera sensor mounted upside down compared to its natural
+mounting rotation. In such cases, drivers shall expose the information to
+userspace with the :ref:`V4L2_CID_CAMERA_SENSOR_ROTATION
+<v4l2-camera-sensor-rotation>` control.
+
+Sensor drivers shall also report the sensor's mounting orientation with the
+:ref:`V4L2_CID_CAMERA_SENSOR_ORIENTATION <v4l2-camera-sensor-orientation>`.
+
+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.
+
+Sensor drivers that have any vertical or horizontal flips embedded in the
+register programming sequences shall initialize the V4L2_CID_HFLIP and
+V4L2_CID_VFLIP controls with the values programmed by the register sequences.
+The default values of these controls shall be 0 (disabled). Especially these
+controls shall not be inverted, independently of the sensor's mounting
+rotation.
diff --git a/Documentation/driver-api/media/cec-core.rst b/Documentation/driver-api/media/cec-core.rst
new file mode 100644
index 0000000000..f1ffdec388
--- /dev/null
+++ b/Documentation/driver-api/media/cec-core.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/bttv-devel.rst b/Documentation/driver-api/media/drivers/bttv-devel.rst
new file mode 100644
index 0000000000..0885a04563
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/bttv-devel.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
new file mode 100644
index 0000000000..bbf9213c33
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
@@ -0,0 +1,1041 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+# Copyright (C) 2019--2020 Intel Corporation
+
+# register rflags
+# - f field LSB MSB rflags
+# - e enum value # after a field
+# - e enum value [LSB MSB]
+# - b bool bit
+# - l arg name min max elsize [discontig...]
+#
+# rflags
+# 8, 16, 32 register bits (default is 8)
+# v1.1 defined in version 1.1
+# f formula
+# float_ireal iReal or IEEE 754; 32 bits
+# ireal unsigned iReal
+
+# general status registers
+module_model_id 0x0000 16
+module_revision_number_major 0x0002 8
+frame_count 0x0005 8
+pixel_order 0x0006 8
+- e GRBG 0
+- e RGGB 1
+- e BGGR 2
+- e GBRG 3
+MIPI_CCS_version 0x0007 8
+- e v1_0 0x10
+- e v1_1 0x11
+- f major 4 7
+- f minor 0 3
+data_pedestal 0x0008 16
+module_manufacturer_id 0x000e 16
+module_revision_number_minor 0x0010 8
+module_date_year 0x0012 8
+module_date_month 0x0013 8
+module_date_day 0x0014 8
+module_date_phase 0x0015 8
+- f 0 2
+- e ts 0
+- e es 1
+- e cs 2
+- e mp 3
+sensor_model_id 0x0016 16
+sensor_revision_number 0x0018 8
+sensor_firmware_version 0x001a 8
+serial_number 0x001c 32
+sensor_manufacturer_id 0x0020 16
+sensor_revision_number_16 0x0022 16
+
+# frame format description registers
+frame_format_model_type 0x0040 8
+- e 2-byte 1
+- e 4-byte 2
+frame_format_model_subtype 0x0041 8
+- f rows 0 3
+- f columns 4 7
+frame_format_descriptor(n) 0x0042 16 f
+- l n 0 14 2
+- f pixels 0 11
+- f pcode 12 15
+- e embedded 1
+- e dummy_pixel 2
+- e black_pixel 3
+- e dark_pixel 4
+- e visible_pixel 5
+- e manuf_specific_0 8
+- e manuf_specific_1 9
+- e manuf_specific_2 10
+- e manuf_specific_3 11
+- e manuf_specific_4 12
+- e manuf_specific_5 13
+- e manuf_specific_6 14
+frame_format_descriptor_4(n) 0x0060 32 f
+- l n 0 7 4
+- f pixels 0 15
+- f pcode 28 31
+- e embedded 1
+- e dummy_pixel 2
+- e black_pixel 3
+- e dark_pixel 4
+- e visible_pixel 5
+- e manuf_specific_0 8
+- e manuf_specific_1 9
+- e manuf_specific_2 10
+- e manuf_specific_3 11
+- e manuf_specific_4 12
+- e manuf_specific_5 13
+- e manuf_specific_6 14
+
+# analog gain description registers
+analog_gain_capability 0x0080 16
+- e global 0
+- e alternate_global 2
+analog_gain_code_min 0x0084 16
+analog_gain_code_max 0x0086 16
+analog_gain_code_step 0x0088 16
+analog_gain_type 0x008a 16
+analog_gain_m0 0x008c 16
+analog_gain_c0 0x008e 16
+analog_gain_m1 0x0090 16
+analog_gain_c1 0x0092 16
+analog_linear_gain_min 0x0094 16 v1.1
+analog_linear_gain_max 0x0096 16 v1.1
+analog_linear_gain_step_size 0x0098 16 v1.1
+analog_exponential_gain_min 0x009a 16 v1.1
+analog_exponential_gain_max 0x009c 16 v1.1
+analog_exponential_gain_step_size 0x009e 16 v1.1
+
+# data format description registers
+data_format_model_type 0x00c0 8
+- e normal 1
+- e extended 2
+data_format_model_subtype 0x00c1 8
+- f rows 0 3
+- f columns 4 7
+data_format_descriptor(n) 0x00c2 16 f
+- l n 0 15 2
+- f compressed 0 7
+- f uncompressed 8 15
+
+# general set-up registers
+mode_select 0x0100 8
+- e software_standby 0
+- e streaming 1
+image_orientation 0x0101 8
+- b horizontal_mirror 0
+- b vertical_flip 1
+software_reset 0x0103 8
+- e off 0
+- e on 1
+grouped_parameter_hold 0x0104 8
+mask_corrupted_frames 0x0105 8
+- e allow 0
+- e mask 1
+fast_standby_ctrl 0x0106 8
+- e complete_frames 0
+- e frame_truncation 1
+CCI_address_ctrl 0x0107 8
+2nd_CCI_if_ctrl 0x0108 8
+- b enable 0
+- b ack 1
+2nd_CCI_address_ctrl 0x0109 8
+CSI_channel_identifier 0x0110 8
+CSI_signaling_mode 0x0111 8
+- e csi_2_dphy 2
+- e csi_2_cphy 3
+CSI_data_format 0x0112 16
+CSI_lane_mode 0x0114 8
+DPCM_Frame_DT 0x011d 8
+Bottom_embedded_data_DT 0x011e 8
+Bottom_embedded_data_VC 0x011f 8
+
+gain_mode 0x0120 8
+- e global 0
+- e alternate 1
+ADC_bit_depth 0x0121 8
+emb_data_ctrl 0x0122 v1.1
+- b raw8_packing_for_raw16 0
+- b raw10_packing_for_raw20 1
+- b raw12_packing_for_raw24 2
+
+GPIO_TRIG_mode 0x0130 8
+extclk_frequency_mhz 0x0136 16 ireal
+temp_sensor_ctrl 0x0138 8
+- b enable 0
+temp_sensor_mode 0x0139 8
+temp_sensor_output 0x013a 8
+
+# integration time registers
+fine_integration_time 0x0200 16
+coarse_integration_time 0x0202 16
+
+# analog gain registers
+analog_gain_code_global 0x0204 16
+analog_linear_gain_global 0x0206 16 v1.1
+analog_exponential_gain_global 0x0208 16 v1.1
+
+# digital gain registers
+digital_gain_global 0x020e 16
+
+# hdr control registers
+Short_analog_gain_global 0x0216 16
+Short_digital_gain_global 0x0218 16
+
+HDR_mode 0x0220 8
+- b enabled 0
+- b separate_analog_gain 1
+- b upscaling 2
+- b reset_sync 3
+- b timing_mode 4
+- b exposure_ctrl_direct 5
+- b separate_digital_gain 6
+HDR_resolution_reduction 0x0221 8
+- f row 0 3
+- f column 4 7
+Exposure_ratio 0x0222 8
+HDR_internal_bit_depth 0x0223 8
+Direct_short_integration_time 0x0224 16
+Short_analog_linear_gain_global 0x0226 16 v1.1
+Short_analog_exponential_gain_global 0x0228 16 v1.1
+
+# clock set-up registers
+vt_pix_clk_div 0x0300 16
+vt_sys_clk_div 0x0302 16
+pre_pll_clk_div 0x0304 16
+#vt_pre_pll_clk_div 0x0304 16
+pll_multiplier 0x0306 16
+#vt_pll_multiplier 0x0306 16
+op_pix_clk_div 0x0308 16
+op_sys_clk_div 0x030a 16
+op_pre_pll_clk_div 0x030c 16
+op_pll_multiplier 0x030e 16
+pll_mode 0x0310 8
+- f 0 0
+- e single 0
+- e dual 1
+op_pix_clk_div_rev 0x0312 16 v1.1
+op_sys_clk_div_rev 0x0314 16 v1.1
+
+# frame timing registers
+frame_length_lines 0x0340 16
+line_length_pck 0x0342 16
+
+# image size registers
+x_addr_start 0x0344 16
+y_addr_start 0x0346 16
+x_addr_end 0x0348 16
+y_addr_end 0x034a 16
+x_output_size 0x034c 16
+y_output_size 0x034e 16
+
+# timing mode registers
+Frame_length_ctrl 0x0350 8
+- b automatic 0
+Timing_mode_ctrl 0x0352 8
+- b manual_readout 0
+- b delayed_exposure 1
+Start_readout_rs 0x0353 8
+- b manual_readout_start 0
+Frame_margin 0x0354 16
+
+# sub-sampling registers
+x_even_inc 0x0380 16
+x_odd_inc 0x0382 16
+y_even_inc 0x0384 16
+y_odd_inc 0x0386 16
+
+# monochrome readout registers
+monochrome_en 0x0390 v1.1
+- e enabled 0
+
+# image scaling registers
+Scaling_mode 0x0400 16
+- e no_scaling 0
+- e horizontal 1
+scale_m 0x0404 16
+scale_n 0x0406 16
+digital_crop_x_offset 0x0408 16
+digital_crop_y_offset 0x040a 16
+digital_crop_image_width 0x040c 16
+digital_crop_image_height 0x040e 16
+
+# image compression registers
+compression_mode 0x0500 16
+- e none 0
+- e dpcm_pcm_simple 1
+
+# test pattern registers
+test_pattern_mode 0x0600 16
+- e none 0
+- e solid_color 1
+- e color_bars 2
+- e fade_to_grey 3
+- e pn9 4
+- e color_tile 5
+test_data_red 0x0602 16
+test_data_greenR 0x0604 16
+test_data_blue 0x0606 16
+test_data_greenB 0x0608 16
+value_step_size_smooth 0x060a 8
+value_step_size_quantised 0x060b 8
+
+# phy configuration registers
+tclk_post 0x0800 8
+ths_prepare 0x0801 8
+ths_zero_min 0x0802 8
+ths_trail 0x0803 8
+tclk_trail_min 0x0804 8
+tclk_prepare 0x0805 8
+tclk_zero 0x0806 8
+tlpx 0x0807 8
+phy_ctrl 0x0808 8
+- e auto 0
+- e UI 1
+- e manual 2
+tclk_post_ex 0x080a 16
+ths_prepare_ex 0x080c 16
+ths_zero_min_ex 0x080e 16
+ths_trail_ex 0x0810 16
+tclk_trail_min_ex 0x0812 16
+tclk_prepare_ex 0x0814 16
+tclk_zero_ex 0x0816 16
+tlpx_ex 0x0818 16
+
+# link rate register
+requested_link_rate 0x0820 32 u16.16
+
+# equalization control registers
+DPHY_equalization_mode 0x0824 8 v1.1
+- b eq2 0
+PHY_equalization_ctrl 0x0825 8 v1.1
+- b enable 0
+
+# d-phy preamble control registers
+DPHY_preamble_ctrl 0x0826 8 v1.1
+- b enable 0
+DPHY_preamble_length 0x0826 8 v1.1
+
+# d-phy spread spectrum control registers
+PHY_SSC_ctrl 0x0828 8 v1.1
+- b enable 0
+
+# manual lp control register
+manual_LP_ctrl 0x0829 8 v1.1
+- b enable 0
+
+# additional phy configuration registers
+twakeup 0x082a v1.1
+tinit 0x082b v1.1
+ths_exit 0x082c v1.1
+ths_exit_ex 0x082e 16 v1.1
+
+# phy calibration configuration registers
+PHY_periodic_calibration_ctrl 0x0830 8
+- b frame_blanking 0
+PHY_periodic_calibration_interval 0x0831 8
+PHY_init_calibration_ctrl 0x0832 8
+- b stream_start 0
+DPHY_calibration_mode 0x0833 8 v1.1
+- b also_alternate 0
+CPHY_calibration_mode 0x0834 8 v1.1
+- e format_1 0
+- e format_2 1
+- e format_3 2
+t3_calpreamble_length 0x0835 8 v1.1
+t3_calpreamble_length_per 0x0836 8 v1.1
+t3_calaltseq_length 0x0837 8 v1.1
+t3_calaltseq_length_per 0x0838 8 v1.1
+FM2_init_seed 0x083a 16 v1.1
+t3_caludefseq_length 0x083c 16 v1.1
+t3_caludefseq_length_per 0x083e 16 v1.1
+
+# c-phy manual control registers
+TGR_Preamble_Length 0x0841 8
+- b preamable_prog_seq 7
+- f begin_preamble_length 0 5
+TGR_Post_Length 0x0842 8
+- f post_length 0 4
+TGR_Preamble_Prog_Sequence(n2) 0x0843
+- l n2 0 6 1
+- f symbol_n_1 3 5
+- f symbol_n 0 2
+t3_prepare 0x084e 16
+t3_lpx 0x0850 16
+
+# alps control register
+ALPS_ctrl 0x085a 8
+- b lvlp_dphy 0
+- b lvlp_cphy 1
+- b alp_cphy 2
+
+# lrte control registers
+TX_REG_CSI_EPD_EN_SSP_cphy 0x0860 16
+TX_REG_CSI_EPD_OP_SLP_cphy 0x0862 16
+TX_REG_CSI_EPD_EN_SSP_dphy 0x0864 16
+TX_REG_CSI_EPD_OP_SLP_dphy 0x0866 16
+TX_REG_CSI_EPD_MISC_OPTION_cphy 0x0868 v1.1
+TX_REG_CSI_EPD_MISC_OPTION_dphy 0x0869 v1.1
+
+# scrambling control registers
+Scrambling_ctrl 0x0870
+- b enabled 0
+- f 2 3
+- e 1_seed_cphy 0
+- e 4_seed_cphy 3
+lane_seed_value(seed, lane) 0x0872 16
+- l seed 0 3 0x10
+- l lane 0 7 0x2
+
+# usl control registers
+TX_USL_REV_ENTRY 0x08c0 16 v1.1
+TX_USL_REV_Clock_Counter 0x08c2 16 v1.1
+TX_USL_REV_LP_Counter 0x08c4 16 v1.1
+TX_USL_REV_Frame_Counter 0x08c6 16 v1.1
+TX_USL_REV_Chronological_Timer 0x08c8 16 v1.1
+TX_USL_FWD_ENTRY 0x08ca 16 v1.1
+TX_USL_GPIO 0x08cc 16 v1.1
+TX_USL_Operation 0x08ce 16 v1.1
+- b reset 0
+TX_USL_ALP_ctrl 0x08d0 16 v1.1
+- b clock_pause 0
+TX_USL_APP_BTA_ACK_TIMEOUT 0x08d2 16 v1.1
+TX_USL_SNS_BTA_ACK_TIMEOUT 0x08d2 16 v1.1
+USL_Clock_Mode_d_ctrl 0x08d2 v1.1
+- b cont_clock_standby 0
+- b cont_clock_vblank 1
+- b cont_clock_hblank 2
+
+# binning configuration registers
+binning_mode 0x0900 8
+binning_type 0x0901 8
+binning_weighting 0x0902 8
+
+# data transfer interface registers
+data_transfer_if_1_ctrl 0x0a00 8
+- b enable 0
+- b write 1
+- b clear_error 2
+data_transfer_if_1_status 0x0a01 8
+- b read_if_ready 0
+- b write_if_ready 1
+- b data_corrupted 2
+- b improper_if_usage 3
+data_transfer_if_1_page_select 0x0a02 8
+data_transfer_if_1_data(p) 0x0a04 8 f
+- l p 0 63 1
+
+# image processing and sensor correction configuration registers
+shading_correction_en 0x0b00 8
+- b enable 0
+luminance_correction_level 0x0b01 8
+green_imbalance_filter_en 0x0b02 8
+- b enable 0
+mapped_defect_correct_en 0x0b05 8
+- b enable 0
+single_defect_correct_en 0x0b06 8
+- b enable 0
+dynamic_couplet_correct_en 0x0b08 8
+- b enable 0
+combined_defect_correct_en 0x0b0a 8
+- b enable 0
+module_specific_correction_en 0x0b0c 8
+- b enable 0
+dynamic_triplet_defect_correct_en 0x0b13 8
+- b enable 0
+NF_ctrl 0x0b15 8
+- b luma 0
+- b chroma 1
+- b combined 2
+
+# optical black pixel readout registers
+OB_readout_control 0x0b30 8
+- b enable 0
+- b interleaving 1
+OB_virtual_channel 0x0b31 8
+OB_DT 0x0b32 8
+OB_data_format 0x0b33 8
+
+# color temperature feedback registers
+color_temperature 0x0b8c 16
+absolute_gain_greenr 0x0b8e 16
+absolute_gain_red 0x0b90 16
+absolute_gain_blue 0x0b92 16
+absolute_gain_greenb 0x0b94 16
+
+# cfa conversion registers
+CFA_conversion_ctrl 0x0ba0 v1.1
+- b bayer_conversion_enable 0
+
+# flash strobe and sa strobe control registers
+flash_strobe_adjustment 0x0c12 8
+flash_strobe_start_point 0x0c14 16
+tflash_strobe_delay_rs_ctrl 0x0c16 16
+tflash_strobe_width_high_rs_ctrl 0x0c18 16
+flash_mode_rs 0x0c1a 8
+- b continuous 0
+- b truncate 1
+- b async 3
+flash_trigger_rs 0x0c1b 8
+flash_status 0x0c1c 8
+- b retimed 0
+sa_strobe_mode 0x0c1d 8
+- b continuous 0
+- b truncate 1
+- b async 3
+- b adjust_edge 4
+sa_strobe_start_point 0x0c1e 16
+tsa_strobe_delay_ctrl 0x0c20 16
+tsa_strobe_width_ctrl 0x0c22 16
+sa_strobe_trigger 0x0c24 8
+sa_strobe_status 0x0c25 8
+- b retimed 0
+tSA_strobe_re_delay_ctrl 0x0c30 16
+tSA_strobe_fe_delay_ctrl 0x0c32 16
+
+# pdaf control registers
+PDAF_ctrl 0x0d00 16
+- b enable 0
+- b processed 1
+- b interleaved 2
+- b visible_pdaf_correction 3
+PDAF_VC 0x0d02 8
+PDAF_DT 0x0d03 8
+pd_x_addr_start 0x0d04 16
+pd_y_addr_start 0x0d06 16
+pd_x_addr_end 0x0d08 16
+pd_y_addr_end 0x0d0a 16
+
+# bracketing interface configuration registers
+bracketing_LUT_ctrl 0x0e00 8
+bracketing_LUT_mode 0x0e01 8
+- b continue_streaming 0
+- b loop_mode 1
+bracketing_LUT_entry_ctrl 0x0e02 8
+bracketing_LUT_frame(n) 0x0e10 v1.1 f
+- l n 0 0xef 1
+
+# integration time and gain parameter limit registers
+integration_time_capability 0x1000 16
+- b fine 0
+coarse_integration_time_min 0x1004 16
+coarse_integration_time_max_margin 0x1006 16
+fine_integration_time_min 0x1008 16
+fine_integration_time_max_margin 0x100a 16
+
+# digital gain parameter limit registers
+digital_gain_capability 0x1081
+- e none 0
+- e global 2
+digital_gain_min 0x1084 16
+digital_gain_max 0x1086 16
+digital_gain_step_size 0x1088 16
+
+# data pedestal capability registers
+Pedestal_capability 0x10e0 8 v1.1
+
+# adc capability registers
+ADC_capability 0x10f0 8
+- b bit_depth_ctrl 0
+ADC_bit_depth_capability 0x10f4 32 v1.1
+
+# video timing parameter limit registers
+min_ext_clk_freq_mhz 0x1100 32 float_ireal
+max_ext_clk_freq_mhz 0x1104 32 float_ireal
+min_pre_pll_clk_div 0x1108 16
+# min_vt_pre_pll_clk_div 0x1108 16
+max_pre_pll_clk_div 0x110a 16
+# max_vt_pre_pll_clk_div 0x110a 16
+min_pll_ip_clk_freq_mhz 0x110c 32 float_ireal
+# min_vt_pll_ip_clk_freq_mhz 0x110c 32 float_ireal
+max_pll_ip_clk_freq_mhz 0x1110 32 float_ireal
+# max_vt_pll_ip_clk_freq_mhz 0x1110 32 float_ireal
+min_pll_multiplier 0x1114 16
+# min_vt_pll_multiplier 0x1114 16
+max_pll_multiplier 0x1116 16
+# max_vt_pll_multiplier 0x1116 16
+min_pll_op_clk_freq_mhz 0x1118 32 float_ireal
+max_pll_op_clk_freq_mhz 0x111c 32 float_ireal
+
+# video timing set-up capability registers
+min_vt_sys_clk_div 0x1120 16
+max_vt_sys_clk_div 0x1122 16
+min_vt_sys_clk_freq_mhz 0x1124 32 float_ireal
+max_vt_sys_clk_freq_mhz 0x1128 32 float_ireal
+min_vt_pix_clk_freq_mhz 0x112c 32 float_ireal
+max_vt_pix_clk_freq_mhz 0x1130 32 float_ireal
+min_vt_pix_clk_div 0x1134 16
+max_vt_pix_clk_div 0x1136 16
+clock_calculation 0x1138
+- b lane_speed 0
+- b link_decoupled 1
+- b dual_pll_op_sys_ddr 2
+- b dual_pll_op_pix_ddr 3
+num_of_vt_lanes 0x1139
+num_of_op_lanes 0x113a
+op_bits_per_lane 0x113b 8 v1.1
+
+# frame timing parameter limits
+min_frame_length_lines 0x1140 16
+max_frame_length_lines 0x1142 16
+min_line_length_pck 0x1144 16
+max_line_length_pck 0x1146 16
+min_line_blanking_pck 0x1148 16
+min_frame_blanking_lines 0x114a 16
+min_line_length_pck_step_size 0x114c
+timing_mode_capability 0x114d
+- b auto_frame_length 0
+- b rolling_shutter_manual_readout 2
+- b delayed_exposure_start 3
+- b manual_exposure_embedded_data 4
+frame_margin_max_value 0x114e 16
+frame_margin_min_value 0x1150
+gain_delay_type 0x1151
+- e fixed 0
+- e variable 1
+
+# output clock set-up capability registers
+min_op_sys_clk_div 0x1160 16
+max_op_sys_clk_div 0x1162 16
+min_op_sys_clk_freq_mhz 0x1164 32 float_ireal
+max_op_sys_clk_freq_mhz 0x1168 32 float_ireal
+min_op_pix_clk_div 0x116c 16
+max_op_pix_clk_div 0x116e 16
+min_op_pix_clk_freq_mhz 0x1170 32 float_ireal
+max_op_pix_clk_freq_mhz 0x1174 32 float_ireal
+
+# image size parameter limit registers
+x_addr_min 0x1180 16
+y_addr_min 0x1182 16
+x_addr_max 0x1184 16
+y_addr_max 0x1186 16
+min_x_output_size 0x1188 16
+min_y_output_size 0x118a 16
+max_x_output_size 0x118c 16
+max_y_output_size 0x118e 16
+
+x_addr_start_div_constant 0x1190 v1.1
+y_addr_start_div_constant 0x1191 v1.1
+x_addr_end_div_constant 0x1192 v1.1
+y_addr_end_div_constant 0x1193 v1.1
+x_size_div 0x1194 v1.1
+y_size_div 0x1195 v1.1
+x_output_div 0x1196 v1.1
+y_output_div 0x1197 v1.1
+non_flexible_resolution_support 0x1198 v1.1
+- b new_pix_addr 0
+- b new_output_res 1
+- b output_crop_no_pad 2
+- b output_size_lane_dep 3
+
+min_op_pre_pll_clk_div 0x11a0 16
+max_op_pre_pll_clk_div 0x11a2 16
+min_op_pll_ip_clk_freq_mhz 0x11a4 32 float_ireal
+max_op_pll_ip_clk_freq_mhz 0x11a8 32 float_ireal
+min_op_pll_multiplier 0x11ac 16
+max_op_pll_multiplier 0x11ae 16
+min_op_pll_op_clk_freq_mhz 0x11b0 32 float_ireal
+max_op_pll_op_clk_freq_mhz 0x11b4 32 float_ireal
+clock_tree_pll_capability 0x11b8 8
+- b dual_pll 0
+- b single_pll 1
+- b ext_divider 2
+- b flexible_op_pix_clk_div 3
+clock_capa_type_capability 0x11b9 v1.1
+- b ireal 0
+
+# sub-sampling parameters limit registers
+min_even_inc 0x11c0 16
+min_odd_inc 0x11c2 16
+max_even_inc 0x11c4 16
+max_odd_inc 0x11c6 16
+aux_subsamp_capability 0x11c8 v1.1
+- b factor_power_of_2 1
+aux_subsamp_mono_capability 0x11c9 v1.1
+- b factor_power_of_2 1
+monochrome_capability 0x11ca v1.1
+- e inc_odd 0
+- e inc_even 1
+pixel_readout_capability 0x11cb v1.1
+- e bayer 0
+- e monochrome 1
+- e bayer_and_mono 2
+min_even_inc_mono 0x11cc 16 v1.1
+max_even_inc_mono 0x11ce 16 v1.1
+min_odd_inc_mono 0x11d0 16 v1.1
+max_odd_inc_mono 0x11d2 16 v1.1
+min_even_inc_bc2 0x11d4 16 v1.1
+max_even_inc_bc2 0x11d6 16 v1.1
+min_odd_inc_bc2 0x11d8 16 v1.1
+max_odd_inc_bc2 0x11da 16 v1.1
+min_even_inc_mono_bc2 0x11dc 16 v1.1
+max_even_inc_mono_bc2 0x11de 16 v1.1
+min_odd_inc_mono_bc2 0x11f0 16 v1.1
+max_odd_inc_mono_bc2 0x11f2 16 v1.1
+
+# image scaling limit parameters
+scaling_capability 0x1200 16
+- e none 0
+- e horizontal 1
+- e reserved 2
+scaler_m_min 0x1204 16
+scaler_m_max 0x1206 16
+scaler_n_min 0x1208 16
+scaler_n_max 0x120a 16
+digital_crop_capability 0x120e
+- e none 0
+- e input_crop 1
+
+# hdr limit registers
+hdr_capability_1 0x1210
+- b 2x2_binning 0
+- b combined_analog_gain 1
+- b separate_analog_gain 2
+- b upscaling 3
+- b reset_sync 4
+- b direct_short_exp_timing 5
+- b direct_short_exp_synthesis 6
+min_hdr_bit_depth 0x1211
+hdr_resolution_sub_types 0x1212
+hdr_resolution_sub_type(n) 0x1213
+- l n 0 1 1
+- f row 0 3
+- f column 4 7
+hdr_capability_2 0x121b
+- b combined_digital_gain 0
+- b separate_digital_gain 1
+- b timing_mode 3
+- b synthesis_mode 4
+max_hdr_bit_depth 0x121c
+
+# usl capability register
+usl_support_capability 0x1230 v1.1
+- b clock_tree 0
+- b rev_clock_tree 1
+- b rev_clock_calc 2
+usl_clock_mode_d_capability 0x1231 v1.1
+- b cont_clock_standby 0
+- b cont_clock_vblank 1
+- b cont_clock_hblank 2
+- b noncont_clock_standby 3
+- b noncont_clock_vblank 4
+- b noncont_clock_hblank 5
+min_op_sys_clk_div_rev 0x1234 v1.1
+max_op_sys_clk_div_rev 0x1236 v1.1
+min_op_pix_clk_div_rev 0x1238 v1.1
+max_op_pix_clk_div_rev 0x123a v1.1
+min_op_sys_clk_freq_rev_mhz 0x123c 32 v1.1 float_ireal
+max_op_sys_clk_freq_rev_mhz 0x1240 32 v1.1 float_ireal
+min_op_pix_clk_freq_rev_mhz 0x1244 32 v1.1 float_ireal
+max_op_pix_clk_freq_rev_mhz 0x1248 32 v1.1 float_ireal
+max_bitrate_rev_d_mode_mbps 0x124c 32 v1.1 ireal
+max_symrate_rev_c_mode_msps 0x1250 32 v1.1 ireal
+
+# image compression capability registers
+compression_capability 0x1300
+- b dpcm_pcm_simple 0
+
+# test mode capability registers
+test_mode_capability 0x1310 16
+- b solid_color 0
+- b color_bars 1
+- b fade_to_grey 2
+- b pn9 3
+- b color_tile 5
+pn9_data_format1 0x1312
+pn9_data_format2 0x1313
+pn9_data_format3 0x1314
+pn9_data_format4 0x1315
+pn9_misc_capability 0x1316
+- f num_pixels 0 2
+- b compression 3
+test_pattern_capability 0x1317 v1.1
+- b no_repeat 1
+pattern_size_div_m1 0x1318 v1.1
+
+# fifo capability registers
+fifo_support_capability 0x1502
+- e none 0
+- e derating 1
+- e derating_overrating 2
+
+# csi-2 capability registers
+phy_ctrl_capability 0x1600
+- b auto_phy_ctl 0
+- b ui_phy_ctl 1
+- b dphy_time_ui_reg_1_ctl 2
+- b dphy_time_ui_reg_2_ctl 3
+- b dphy_time_ctl 4
+- b dphy_ext_time_ui_reg_1_ctl 5
+- b dphy_ext_time_ui_reg_2_ctl 6
+- b dphy_ext_time_ctl 7
+csi_dphy_lane_mode_capability 0x1601
+- b 1_lane 0
+- b 2_lane 1
+- b 3_lane 2
+- b 4_lane 3
+- b 5_lane 4
+- b 6_lane 5
+- b 7_lane 6
+- b 8_lane 7
+csi_signaling_mode_capability 0x1602
+- b csi_dphy 2
+- b csi_cphy 3
+fast_standby_capability 0x1603
+- e no_frame_truncation 0
+- e frame_truncation 1
+csi_address_control_capability 0x1604
+- b cci_addr_change 0
+- b 2nd_cci_addr 1
+- b sw_changeable_2nd_cci_addr 2
+data_type_capability 0x1605
+- b dpcm_programmable 0
+- b bottom_embedded_dt_programmable 1
+- b bottom_embedded_vc_programmable 2
+- b ext_vc_range 3
+csi_cphy_lane_mode_capability 0x1606
+- b 1_lane 0
+- b 2_lane 1
+- b 3_lane 2
+- b 4_lane 3
+- b 5_lane 4
+- b 6_lane 5
+- b 7_lane 6
+- b 8_lane 7
+emb_data_capability 0x1607 v1.1
+- b two_bytes_per_raw16 0
+- b two_bytes_per_raw20 1
+- b two_bytes_per_raw24 2
+- b no_one_byte_per_raw16 3
+- b no_one_byte_per_raw20 4
+- b no_one_byte_per_raw24 5
+max_per_lane_bitrate_lane_d_mode_mbps(n) 0x1608 32 ireal
+- l n 0 7 4 4,0x32
+temp_sensor_capability 0x1618
+- b supported 0
+- b CCS_format 1
+- b reset_0x80 2
+max_per_lane_bitrate_lane_c_mode_mbps(n) 0x161a 32 ireal
+- l n 0 7 4 4,0x30
+dphy_equalization_capability 0x162b
+- b equalization_ctrl 0
+- b eq1 1
+- b eq2 2
+cphy_equalization_capability 0x162c
+- b equalization_ctrl 0
+dphy_preamble_capability 0x162d
+- b preamble_seq_ctrl 0
+dphy_ssc_capability 0x162e
+- b supported 0
+cphy_calibration_capability 0x162f
+- b manual 0
+- b manual_streaming 1
+- b format_1_ctrl 2
+- b format_2_ctrl 3
+- b format_3_ctrl 4
+dphy_calibration_capability 0x1630
+- b manual 0
+- b manual_streaming 1
+- b alternate_seq 2
+phy_ctrl_capability_2 0x1631
+- b tgr_length 0
+- b tgr_preamble_prog_seq 1
+- b extra_cphy_manual_timing 2
+- b clock_based_manual_cdphy 3
+- b clock_based_manual_dphy 4
+- b clock_based_manual_cphy 5
+- b manual_lp_dphy 6
+- b manual_lp_cphy 7
+lrte_cphy_capability 0x1632
+- b pdq_short 0
+- b spacer_short 1
+- b pdq_long 2
+- b spacer_long 3
+- b spacer_no_pdq 4
+lrte_dphy_capability 0x1633
+- b pdq_short_opt1 0
+- b spacer_short_opt1 1
+- b pdq_long_opt1 2
+- b spacer_long_opt1 3
+- b spacer_short_opt2 4
+- b spacer_long_opt2 5
+- b spacer_no_pdq_opt1 6
+- b spacer_variable_opt2 7
+alps_capability_dphy 0x1634
+- e lvlp_not_supported 0 0x3
+- e lvlp_supported 1 0x3
+- e controllable_lvlp 2 0x3
+alps_capability_cphy 0x1635
+- e lvlp_not_supported 0 0x3
+- e lvlp_supported 1 0x3
+- e controllable_lvlp 2 0x3
+- e alp_not_supported 0xc 0xc
+- e alp_supported 0xd 0xc
+- e controllable_alp 0xe 0xc
+scrambling_capability 0x1636
+- b scrambling_supported 0
+- f max_seeds_per_lane_c 1 2
+- e 1 0
+- e 4 3
+- f num_seed_regs 3 5
+- e 0 0
+- e 1 1
+- e 4 4
+- b num_seed_per_lane 6
+dphy_manual_constant 0x1637
+cphy_manual_constant 0x1638
+CSI2_interface_capability_misc 0x1639 v1.1
+- b eotp_short_pkt_opt2 0
+PHY_ctrl_capability_3 0x165c v1.1
+- b dphy_timing_not_multiple 0
+- b dphy_min_timing_value_1 1
+- b twakeup_supported 2
+- b tinit_supported 3
+- b ths_exit_supported 4
+- b cphy_timing_not_multiple 5
+- b cphy_min_timing_value_1 6
+dphy_sf 0x165d v1.1
+cphy_sf 0x165e v1.1
+- f twakeup 0 3
+- f tinit 4 7
+dphy_limits_1 0x165f v1.1
+- f ths_prepare 0 3
+- f ths_zero 4 7
+dphy_limits_2 0x1660 v1.1
+- f ths_trail 0 3
+- f tclk_trail_min 4 7
+dphy_limits_3 0x1661 v1.1
+- f tclk_prepare 0 3
+- f tclk_zero 4 7
+dphy_limits_4 0x1662 v1.1
+- f tclk_post 0 3
+- f tlpx 4 7
+dphy_limits_5 0x1663 v1.1
+- f ths_exit 0 3
+- f twakeup 4 7
+dphy_limits_6 0x1664 v1.1
+- f tinit 0 3
+cphy_limits_1 0x1665 v1.1
+- f t3_prepare_max 0 3
+- f t3_lpx_max 4 7
+cphy_limits_2 0x1666 v1.1
+- f ths_exit_max 0 3
+- f twakeup_max 4 7
+cphy_limits_3 0x1667 v1.1
+- f tinit_max 0 3
+
+# binning capability registers
+min_frame_length_lines_bin 0x1700 16
+max_frame_length_lines_bin 0x1702 16
+min_line_length_pck_bin 0x1704 16
+max_line_length_pck_bin 0x1706 16
+min_line_blanking_pck_bin 0x1708 16
+fine_integration_time_min_bin 0x170a 16
+fine_integration_time_max_margin_bin 0x170c 16
+binning_capability 0x1710
+- e unsupported 0
+- e binning_then_subsampling 1
+- e subsampling_then_binning 2
+binning_weighting_capability 0x1711
+- b averaged 0
+- b summed 1
+- b bayer_corrected 2
+- b module_specific_weight 3
+binning_sub_types 0x1712
+binning_sub_type(n) 0x1713
+- l n 0 63 1
+- f row 0 3
+- f column 4 7
+binning_weighting_mono_capability 0x1771 v1.1
+- b averaged 0
+- b summed 1
+- b bayer_corrected 2
+- b module_specific_weight 3
+binning_sub_types_mono 0x1772 v1.1
+binning_sub_type_mono(n) 0x1773 v1.1 f
+- l n 0 63 1
+
+# data transfer interface capability registers
+data_transfer_if_capability 0x1800
+- b supported 0
+- b polling 2
+
+# sensor correction capability registers
+shading_correction_capability 0x1900
+- b color_shading 0
+- b luminance_correction 1
+green_imbalance_capability 0x1901
+- b supported 0
+module_specific_correction_capability 0x1903
+defect_correction_capability 0x1904 16
+- b mapped_defect 0
+- b dynamic_couplet 2
+- b dynamic_single 5
+- b combined_dynamic 8
+defect_correction_capability_2 0x1906 16
+- b dynamic_triplet 3
+nf_capability 0x1908
+- b luma 0
+- b chroma 1
+- b combined 2
+
+# optical black readout capability registers
+ob_readout_capability 0x1980
+- b controllable_readout 0
+- b visible_pixel_readout 1
+- b different_vc_readout 2
+- b different_dt_readout 3
+- b prog_data_format 4
+
+# color feedback capability registers
+color_feedback_capability 0x1987
+- b kelvin 0
+- b awb_gain 1
+
+# cfa pattern capability registers
+CFA_pattern_capability 0x1990 v1.1
+- e bayer 0
+- e monochrome 1
+- e 4x4_quad_bayer 2
+- e vendor_specific 3
+CFA_pattern_conversion_capability 0x1991 v1.1
+- b bayer 0
+
+# timer capability registers
+flash_mode_capability 0x1a02
+- b single_strobe 0
+sa_strobe_mode_capability 0x1a03
+- b fixed_width 0
+- b edge_ctrl 1
+
+# soft reset capability registers
+reset_max_delay 0x1a10 v1.1
+reset_min_time 0x1a11 v1.1
+
+# pdaf capability registers
+pdaf_capability_1 0x1b80
+- b supported 0
+- b processed_bottom_embedded 1
+- b processed_interleaved 2
+- b raw_bottom_embedded 3
+- b raw_interleaved 4
+- b visible_pdaf_correction 5
+- b vc_interleaving 6
+- b dt_interleaving 7
+pdaf_capability_2 0x1b81
+- b ROI 0
+- b after_digital_crop 1
+- b ctrl_retimed 2
+
+# bracketing interface capability registers
+bracketing_lut_capability_1 0x1c00
+- b coarse_integration 0
+- b global_analog_gain 1
+- b flash 4
+- b global_digital_gain 5
+- b alternate_global_analog_gain 6
+bracketing_lut_capability_2 0x1c01
+- b single_bracketing_mode 0
+- b looped_bracketing_mode 1
+bracketing_lut_size 0x1c02
diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst
new file mode 100644
index 0000000000..7389204afc
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst
@@ -0,0 +1,117 @@
+.. SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+
+.. include:: <isonum.txt>
+
+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. It exposes three sub-devices representing the pixel array,
+the binner and the scaler.
+
+As the capabilities of individual devices vary, the driver exposes
+interfaces based on the capabilities that exist in hardware.
+
+Pixel Array sub-device
+----------------------
+
+The pixel array sub-device represents the camera sensor's pixel matrix, as well
+as analogue crop functionality present in many compliant devices. The analogue
+crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the
+entity. The size of the pixel matrix can be obtained by getting the
+``V4L2_SEL_TGT_NATIVE_SIZE`` target.
+
+Binner
+------
+
+The binner sub-device represents the binning functionality on the sensor. For
+that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
+sink pad (0).
+
+Additionally, if a device has no scaler or digital crop functionality, the
+source pad (1) expses another digital crop selection rectangle that can only
+crop at the end of the lines and frames.
+
+Scaler
+------
+
+The scaler sub-device represents the digital crop and scaling functionality of
+the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to
+configure the digital crop on the sink pad (0) when digital crop is supported.
+Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the
+sink pad (0) as well.
+
+Additionally, if the scaler sub-device exists, its source pad (1) exposes
+another digital crop selection rectangle that can only crop at the end of the
+lines and frames.
+
+Digital and analogue crop
+-------------------------
+
+Digital crop functionality is referred to as cropping that effectively works by
+dropping some data on the floor. Analogue crop, on the other hand, means that
+the cropped information is never retrieved. In case of camera sensors, the
+analogue data is never read from the pixel matrix that are outside the
+configured selection rectangle that designates crop. The difference has an
+effect in device timing and likely also in power consumption.
+
+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.
+
+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
diff --git a/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs
new file mode 100755
index 0000000000..2a4edc7e05
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs
@@ -0,0 +1,434 @@
+#!/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";
+}
+
+sub bit_def($) {
+ my $bit = shift @_;
+
+ return "BIT($bit)" if defined $kernel;
+ return "(1U << $bit)" if $bit =~ /^[a-zA-Z0-9_]+$/;
+ return "(1U << ($bit))";
+}
+
+print $H <<EOF
+#ifndef __${uc_header}__
+#define __${uc_header}__
+
+EOF
+ ;
+
+print $H "#include <linux/bits.h>\n\n" if defined $kernel;
+
+print $H <<EOF
+#define CCS_FL_BASE 16
+EOF
+ ;
+
+print $H "#define CCS_FL_16BIT " . bit_def("CCS_FL_BASE") . "\n";
+print $H "#define CCS_FL_32BIT " . bit_def("CCS_FL_BASE + 1") . "\n";
+print $H "#define CCS_FL_FLOAT_IREAL " . bit_def("CCS_FL_BASE + 2") . "\n";
+print $H "#define CCS_FL_IREAL " . bit_def("CCS_FL_BASE + 3") . "\n";
+
+print $H <<EOF
+#define CCS_R_ADDR(r) ((r) & 0xffff)
+
+EOF
+ ;
+
+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_size(@) {
+ my @flags = @_;
+
+ return 2 if grep /^16$/, @flags;
+ return 4 if grep /^32$/, @flags;
+ return 1;
+}
+
+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;
+
+ 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 .= ")\n";
+ $lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
+
+ print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
+ $this{arglist}, $reg_formula);
+
+ 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 $size = elem_size(@flags);
+ $flagstring .= "| CCS_FL_16BIT " if $size eq "2";
+ $flagstring .= "| CCS_FL_32BIT " if $size eq "4";
+ $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 = "($addr | $flagstring)" if $flagstring ne "";
+
+ 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,
+ base_addr => $base_addr,
+ argparams => {},
+ args => $args,
+ arglist => $arglist,
+ elsize => $size,
+ );
+
+ 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);
diff --git a/Documentation/driver-api/media/drivers/contributors.rst b/Documentation/driver-api/media/drivers/contributors.rst
new file mode 100644
index 0000000000..f23b6e6faf
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/contributors.rst
@@ -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)
diff --git a/Documentation/driver-api/media/drivers/cx2341x-devel.rst b/Documentation/driver-api/media/drivers/cx2341x-devel.rst
new file mode 100644
index 0000000000..97699df6ea
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/cx2341x-devel.rst
@@ -0,0 +1,3685 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The cx2341x driver
+==================
+
+Memory at cx2341x chips
+-----------------------
+
+This section describes the cx2341x memory map and documents some of the
+register space.
+
+.. note:: the memory long words are little-endian ('intel format').
+
+.. warning::
+
+ This information was figured out from searching through the memory
+ and registers, this information may not be correct and is certainly
+ not complete, and was not derived from anything more than searching
+ through the memory space with commands like:
+
+ .. code-block:: none
+
+ ivtvctl -O min=0x02000000,max=0x020000ff
+
+ So take this as is, I'm always searching for more stuff, it's a large
+ register space :-).
+
+Memory Map
+~~~~~~~~~~
+
+The cx2341x exposes its entire 64M memory space to the PCI host via the PCI BAR0
+(Base Address Register 0). The addresses here are offsets relative to the
+address held in BAR0.
+
+.. code-block:: none
+
+ 0x00000000-0x00ffffff Encoder memory space
+ 0x00000000-0x0003ffff Encode.rom
+ ???-??? MPEG buffer(s)
+ ???-??? Raw video capture buffer(s)
+ ???-??? Raw audio capture buffer(s)
+ ???-??? Display buffers (6 or 9)
+
+ 0x01000000-0x01ffffff Decoder memory space
+ 0x01000000-0x0103ffff Decode.rom
+ ???-??? MPEG buffers(s)
+ 0x0114b000-0x0115afff Audio.rom (deprecated?)
+
+ 0x02000000-0x0200ffff Register Space
+
+Registers
+~~~~~~~~~
+
+The registers occupy the 64k space starting at the 0x02000000 offset from BAR0.
+All of these registers are 32 bits wide.
+
+.. code-block:: none
+
+ DMA Registers 0x000-0xff:
+
+ 0x00 - Control:
+ 0=reset/cancel, 1=read, 2=write, 4=stop
+ 0x04 - DMA status:
+ 1=read busy, 2=write busy, 4=read error, 8=write error, 16=link list error
+ 0x08 - pci DMA pointer for read link list
+ 0x0c - pci DMA pointer for write link list
+ 0x10 - read/write DMA enable:
+ 1=read enable, 2=write enable
+ 0x14 - always 0xffffffff, if set any lower instability occurs, 0x00 crashes
+ 0x18 - ??
+ 0x1c - always 0x20 or 32, smaller values slow down DMA transactions
+ 0x20 - always value of 0x780a010a
+ 0x24-0x3c - usually just random values???
+ 0x40 - Interrupt status
+ 0x44 - Write a bit here and shows up in Interrupt status 0x40
+ 0x48 - Interrupt Mask
+ 0x4C - always value of 0xfffdffff,
+ if changed to 0xffffffff DMA write interrupts break.
+ 0x50 - always 0xffffffff
+ 0x54 - always 0xffffffff (0x4c, 0x50, 0x54 seem like interrupt masks, are
+ 3 processors on chip, Java ones, VPU, SPU, APU, maybe these are the
+ interrupt masks???).
+ 0x60-0x7C - random values
+ 0x80 - first write linked list reg, for Encoder Memory addr
+ 0x84 - first write linked list reg, for pci memory addr
+ 0x88 - first write linked list reg, for length of buffer in memory addr
+ (|0x80000000 or this for last link)
+ 0x8c-0xdc - rest of write linked list reg, 8 sets of 3 total, DMA goes here
+ from linked list addr in reg 0x0c, firmware must push through or
+ something.
+ 0xe0 - first (and only) read linked list reg, for pci memory addr
+ 0xe4 - first (and only) read linked list reg, for Decoder memory addr
+ 0xe8 - first (and only) read linked list reg, for length of buffer
+ 0xec-0xff - Nothing seems to be in these registers, 0xec-f4 are 0x00000000.
+
+Memory locations for Encoder Buffers 0x700-0x7ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for encoding, have to shift them by <<1 first.
+
+- 0x07F8: Encoder SDRAM refresh
+- 0x07FC: Encoder SDRAM pre-charge
+
+Memory locations for Decoder Buffers 0x800-0x8ff:
+
+These registers show offsets of memory locations pertaining to each
+buffer area used for decoding, have to shift them by <<1 first.
+
+- 0x08F8: Decoder SDRAM refresh
+- 0x08FC: Decoder SDRAM pre-charge
+
+Other memory locations:
+
+- 0x2800: Video Display Module control
+- 0x2D00: AO (audio output?) control
+- 0x2D24: Bytes Flushed
+- 0x7000: LSB I2C write clock bit (inverted)
+- 0x7004: LSB I2C write data bit (inverted)
+- 0x7008: LSB I2C read clock bit
+- 0x700c: LSB I2C read data bit
+- 0x9008: GPIO get input state
+- 0x900c: GPIO set output state
+- 0x9020: GPIO direction (Bit7 (GPIO 0..7) - 0:input, 1:output)
+- 0x9050: SPU control
+- 0x9054: Reset HW blocks
+- 0x9058: VPU control
+- 0xA018: Bit6: interrupt pending?
+- 0xA064: APU command
+
+
+Interrupt Status Register
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The definition of the bits in the interrupt status register 0x0040, and the
+interrupt mask 0x0048. If a bit is cleared in the mask, then we want our ISR to
+execute.
+
+- bit 31 Encoder Start Capture
+- bit 30 Encoder EOS
+- bit 29 Encoder VBI capture
+- bit 28 Encoder Video Input Module reset event
+- bit 27 Encoder DMA complete
+- bit 24 Decoder audio mode change detection event (through event notification)
+- bit 22 Decoder data request
+- bit 20 Decoder DMA complete
+- bit 19 Decoder VBI re-insertion
+- bit 18 Decoder DMA err (linked-list bad)
+
+Missing documentation
+---------------------
+
+- Encoder API post(?)
+- Decoder API post(?)
+- Decoder VTRACE event
+
+
+The cx2341x firmware upload
+---------------------------
+
+This document describes how to upload the cx2341x firmware to the card.
+
+How to find
+~~~~~~~~~~~
+
+See the web pages of the various projects that uses this chip for information
+on how to obtain the firmware.
+
+The firmware stored in a Windows driver can be detected as follows:
+
+- Each firmware image is 256k bytes.
+- The 1st 32-bit word of the Encoder image is 0x0000da7
+- The 1st 32-bit word of the Decoder image is 0x00003a7
+- The 2nd 32-bit word of both images is 0xaa55bb66
+
+How to load
+~~~~~~~~~~~
+
+- Issue the FWapi command to stop the encoder if it is running. Wait for the
+ command to complete.
+- Issue the FWapi command to stop the decoder if it is running. Wait for the
+ command to complete.
+- Issue the I2C command to the digitizer to stop emitting VSYNC events.
+- Issue the FWapi command to halt the encoder's firmware.
+- Sleep for 10ms.
+- Issue the FWapi command to halt the decoder's firmware.
+- Sleep for 10ms.
+- Write 0x00000000 to register 0x2800 to stop the Video Display Module.
+- Write 0x00000005 to register 0x2D00 to stop the AO (audio output?).
+- Write 0x00000000 to register 0xA064 to ping? the APU.
+- Write 0xFFFFFFFE to register 0x9058 to stop the VPU.
+- Write 0xFFFFFFFF to register 0x9054 to reset the HW blocks.
+- Write 0x00000001 to register 0x9050 to stop the SPU.
+- Sleep for 10ms.
+- Write 0x0000001A to register 0x07FC to init the Encoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x07F8 to init the Encoder SDRAM's refresh to 1us.
+- Write 0x0000001A to register 0x08FC to init the Decoder SDRAM's pre-charge.
+- Write 0x80000640 to register 0x08F8 to init the Decoder SDRAM's refresh to 1us.
+- Sleep for 512ms. (600ms is recommended)
+- Transfer the encoder's firmware image to offset 0 in Encoder memory space.
+- Transfer the decoder's firmware image to offset 0 in Decoder memory space.
+- Use a read-modify-write operation to Clear bit 0 of register 0x9050 to
+ re-enable the SPU.
+- Sleep for 1 second.
+- Use a read-modify-write operation to Clear bits 3 and 0 of register 0x9058
+ to re-enable the VPU.
+- Sleep for 1 second.
+- Issue status API commands to both firmware images to verify.
+
+
+How to call the firmware API
+----------------------------
+
+The preferred calling convention is known as the firmware mailbox. The
+mailboxes are basically a fixed length array that serves as the call-stack.
+
+Firmware mailboxes can be located by searching the encoder and decoder memory
+for a 16 byte signature. That signature will be located on a 256-byte boundary.
+
+Signature:
+
+.. code-block:: none
+
+ 0x78, 0x56, 0x34, 0x12, 0x12, 0x78, 0x56, 0x34,
+ 0x34, 0x12, 0x78, 0x56, 0x56, 0x34, 0x12, 0x78
+
+The firmware implements 20 mailboxes of 20 32-bit words. The first 10 are
+reserved for API calls. The second 10 are used by the firmware for event
+notification.
+
+ ====== =================
+ Index Name
+ ====== =================
+ 0 Flags
+ 1 Command
+ 2 Return value
+ 3 Timeout
+ 4-19 Parameter/Result
+ ====== =================
+
+
+The flags are defined in the following table. The direction is from the
+perspective of the firmware.
+
+ ==== ========== ============================================
+ Bit Direction Purpose
+ ==== ========== ============================================
+ 2 O Firmware has processed the command.
+ 1 I Driver has finished setting the parameters.
+ 0 I Driver is using this mailbox.
+ ==== ========== ============================================
+
+The command is a 32-bit enumerator. The API specifics may be found in this
+chapter.
+
+The return value is a 32-bit enumerator. Only two values are currently defined:
+
+- 0=success
+- -1=command undefined.
+
+There are 16 parameters/results 32-bit fields. The driver populates these fields
+with values for all the parameters required by the call. The driver overwrites
+these fields with result values returned by the call.
+
+The timeout value protects the card from a hung driver thread. If the driver
+doesn't handle the completed call within the timeout specified, the firmware
+will reset that mailbox.
+
+To make an API call, the driver iterates over each mailbox looking for the
+first one available (bit 0 has been cleared). The driver sets that bit, fills
+in the command enumerator, the timeout value and any required parameters. The
+driver then sets the parameter ready bit (bit 1). The firmware scans the
+mailboxes for pending commands, processes them, sets the result code, populates
+the result value array with that call's return values and sets the call
+complete bit (bit 2). Once bit 2 is set, the driver should retrieve the results
+and clear all the flags. If the driver does not perform this task within the
+time set in the timeout register, the firmware will reset that mailbox.
+
+Event notifications are sent from the firmware to the host. The host tells the
+firmware which events it is interested in via an API call. That call tells the
+firmware which notification mailbox to use. The firmware signals the host via
+an interrupt. Only the 16 Results fields are used, the Flags, Command, Return
+value and Timeout words are not used.
+
+
+OSD firmware API description
+----------------------------
+
+.. note:: this API is part of the decoder firmware, so it's cx23415 only.
+
+
+
+CX2341X_OSD_GET_FRAMEBUFFER
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 65/0x41
+
+Description
+^^^^^^^^^^^
+
+Return base and length of contiguous OSD memory.
+
+Result[0]
+^^^^^^^^^
+
+OSD base address
+
+Result[1]
+^^^^^^^^^
+
+OSD length
+
+
+
+CX2341X_OSD_GET_PIXEL_FORMAT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 66/0x42
+
+Description
+^^^^^^^^^^^
+
+Query OSD format
+
+Result[0]
+^^^^^^^^^
+
+0=8bit index
+1=16bit RGB 5:6:5
+2=16bit ARGB 1:5:5:5
+3=16bit ARGB 1:4:4:4
+4=32bit ARGB 8:8:8:8
+
+
+
+CX2341X_OSD_SET_PIXEL_FORMAT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 67/0x43
+
+Description
+^^^^^^^^^^^
+
+Assign pixel format
+
+Param[0]
+^^^^^^^^
+
+- 0=8bit index
+- 1=16bit RGB 5:6:5
+- 2=16bit ARGB 1:5:5:5
+- 3=16bit ARGB 1:4:4:4
+- 4=32bit ARGB 8:8:8:8
+
+
+
+CX2341X_OSD_GET_STATE
+~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 68/0x44
+
+Description
+^^^^^^^^^^^
+
+Query OSD state
+
+Result[0]
+^^^^^^^^^
+
+- Bit 0 0=off, 1=on
+- Bits 1:2 alpha control
+- Bits 3:5 pixel format
+
+
+
+CX2341X_OSD_SET_STATE
+~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 69/0x45
+
+Description
+^^^^^^^^^^^
+
+OSD switch
+
+Param[0]
+^^^^^^^^
+
+0=off, 1=on
+
+
+
+CX2341X_OSD_GET_OSD_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 70/0x46
+
+Description
+^^^^^^^^^^^
+
+Retrieve coordinates of OSD area blended with video
+
+Result[0]
+^^^^^^^^^
+
+OSD buffer address
+
+Result[1]
+^^^^^^^^^
+
+Stride in pixels
+
+Result[2]
+^^^^^^^^^
+
+Lines in OSD buffer
+
+Result[3]
+^^^^^^^^^
+
+Horizontal offset in buffer
+
+Result[4]
+^^^^^^^^^
+
+Vertical offset in buffer
+
+
+
+CX2341X_OSD_SET_OSD_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 71/0x47
+
+Description
+^^^^^^^^^^^
+
+Assign the coordinates of the OSD area to blend with video
+
+Param[0]
+^^^^^^^^
+
+buffer address
+
+Param[1]
+^^^^^^^^
+
+buffer stride in pixels
+
+Param[2]
+^^^^^^^^
+
+lines in buffer
+
+Param[3]
+^^^^^^^^
+
+horizontal offset
+
+Param[4]
+^^^^^^^^
+
+vertical offset
+
+
+
+CX2341X_OSD_GET_SCREEN_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 72/0x48
+
+Description
+^^^^^^^^^^^
+
+Retrieve OSD screen area coordinates
+
+Result[0]
+^^^^^^^^^
+
+top left horizontal offset
+
+Result[1]
+^^^^^^^^^
+
+top left vertical offset
+
+Result[2]
+^^^^^^^^^
+
+bottom right horizontal offset
+
+Result[3]
+^^^^^^^^^
+
+bottom right vertical offset
+
+
+
+CX2341X_OSD_SET_SCREEN_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 73/0x49
+
+Description
+^^^^^^^^^^^
+
+Assign the coordinates of the screen area to blend with video
+
+Param[0]
+^^^^^^^^
+
+top left horizontal offset
+
+Param[1]
+^^^^^^^^
+
+top left vertical offset
+
+Param[2]
+^^^^^^^^
+
+bottom left horizontal offset
+
+Param[3]
+^^^^^^^^
+
+bottom left vertical offset
+
+
+
+CX2341X_OSD_GET_GLOBAL_ALPHA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 74/0x4A
+
+Description
+^^^^^^^^^^^
+
+Retrieve OSD global alpha
+
+Result[0]
+^^^^^^^^^
+
+global alpha: 0=off, 1=on
+
+Result[1]
+^^^^^^^^^
+
+bits 0:7 global alpha
+
+
+
+CX2341X_OSD_SET_GLOBAL_ALPHA
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 75/0x4B
+
+Description
+^^^^^^^^^^^
+
+Update global alpha
+
+Param[0]
+^^^^^^^^
+
+global alpha: 0=off, 1=on
+
+Param[1]
+^^^^^^^^
+
+global alpha (8 bits)
+
+Param[2]
+^^^^^^^^
+
+local alpha: 0=on, 1=off
+
+
+
+CX2341X_OSD_SET_BLEND_COORDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 78/0x4C
+
+Description
+^^^^^^^^^^^
+
+Move start of blending area within display buffer
+
+Param[0]
+^^^^^^^^
+
+horizontal offset in buffer
+
+Param[1]
+^^^^^^^^
+
+vertical offset in buffer
+
+
+
+CX2341X_OSD_GET_FLICKER_STATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 79/0x4F
+
+Description
+^^^^^^^^^^^
+
+Retrieve flicker reduction module state
+
+Result[0]
+^^^^^^^^^
+
+flicker state: 0=off, 1=on
+
+
+
+CX2341X_OSD_SET_FLICKER_STATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 80/0x50
+
+Description
+^^^^^^^^^^^
+
+Set flicker reduction module state
+
+Param[0]
+^^^^^^^^
+
+State: 0=off, 1=on
+
+
+
+CX2341X_OSD_BLT_COPY
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 82/0x52
+
+Description
+^^^^^^^^^^^
+
+BLT copy
+
+Param[0]
+^^^^^^^^
+
+.. code-block:: none
+
+ '0000' zero
+ '0001' ~destination AND ~source
+ '0010' ~destination AND source
+ '0011' ~destination
+ '0100' destination AND ~source
+ '0101' ~source
+ '0110' destination XOR source
+ '0111' ~destination OR ~source
+ '1000' ~destination AND ~source
+ '1001' destination XNOR source
+ '1010' source
+ '1011' ~destination OR source
+ '1100' destination
+ '1101' destination OR ~source
+ '1110' destination OR source
+ '1111' one
+
+
+Param[1]
+^^^^^^^^
+
+Resulting alpha blending
+
+- '01' source_alpha
+- '10' destination_alpha
+- '11' source_alpha*destination_alpha+1
+ (zero if both source and destination alpha are zero)
+
+Param[2]
+^^^^^^^^
+
+.. code-block:: none
+
+ '00' output_pixel = source_pixel
+
+ '01' if source_alpha=0:
+ output_pixel = destination_pixel
+ if 256 > source_alpha > 1:
+ output_pixel = ((source_alpha + 1)*source_pixel +
+ (255 - source_alpha)*destination_pixel)/256
+
+ '10' if destination_alpha=0:
+ output_pixel = source_pixel
+ if 255 > destination_alpha > 0:
+ output_pixel = ((255 - destination_alpha)*source_pixel +
+ (destination_alpha + 1)*destination_pixel)/256
+
+ '11' if source_alpha=0:
+ source_temp = 0
+ if source_alpha=255:
+ source_temp = source_pixel*256
+ if 255 > source_alpha > 0:
+ source_temp = source_pixel*(source_alpha + 1)
+ if destination_alpha=0:
+ destination_temp = 0
+ if destination_alpha=255:
+ destination_temp = destination_pixel*256
+ if 255 > destination_alpha > 0:
+ destination_temp = destination_pixel*(destination_alpha + 1)
+ output_pixel = (source_temp + destination_temp)/256
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+source stride in dwords
+
+Param[9]
+^^^^^^^^
+
+source rectangle start address
+
+
+
+CX2341X_OSD_BLT_FILL
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 83/0x53
+
+Description
+^^^^^^^^^^^
+
+BLT fill color
+
+Param[0]
+^^^^^^^^
+
+Same as Param[0] on API 0x52
+
+Param[1]
+^^^^^^^^
+
+Same as Param[1] on API 0x52
+
+Param[2]
+^^^^^^^^
+
+Same as Param[2] on API 0x52
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+color fill value
+
+
+
+CX2341X_OSD_BLT_TEXT
+~~~~~~~~~~~~~~~~~~~~
+
+Enum: 84/0x54
+
+Description
+^^^^^^^^^^^
+
+BLT for 8 bit alpha text source
+
+Param[0]
+^^^^^^^^
+
+Same as Param[0] on API 0x52
+
+Param[1]
+^^^^^^^^
+
+Same as Param[1] on API 0x52
+
+Param[2]
+^^^^^^^^
+
+Same as Param[2] on API 0x52
+
+Param[3]
+^^^^^^^^
+
+width
+
+Param[4]
+^^^^^^^^
+
+height
+
+Param[5]
+^^^^^^^^
+
+destination pixel mask
+
+Param[6]
+^^^^^^^^
+
+destination rectangle start address
+
+Param[7]
+^^^^^^^^
+
+destination stride in dwords
+
+Param[8]
+^^^^^^^^
+
+source stride in dwords
+
+Param[9]
+^^^^^^^^
+
+source rectangle start address
+
+Param[10]
+^^^^^^^^^
+
+color fill value
+
+
+
+CX2341X_OSD_SET_FRAMEBUFFER_WINDOW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 86/0x56
+
+Description
+^^^^^^^^^^^
+
+Positions the main output window on the screen. The coordinates must be
+such that the entire window fits on the screen.
+
+Param[0]
+^^^^^^^^
+
+window width
+
+Param[1]
+^^^^^^^^
+
+window height
+
+Param[2]
+^^^^^^^^
+
+top left window corner horizontal offset
+
+Param[3]
+^^^^^^^^
+
+top left window corner vertical offset
+
+
+
+CX2341X_OSD_SET_CHROMA_KEY
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 96/0x60
+
+Description
+^^^^^^^^^^^
+
+Chroma key switch and color
+
+Param[0]
+^^^^^^^^
+
+state: 0=off, 1=on
+
+Param[1]
+^^^^^^^^
+
+color
+
+
+
+CX2341X_OSD_GET_ALPHA_CONTENT_INDEX
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 97/0x61
+
+Description
+^^^^^^^^^^^
+
+Retrieve alpha content index
+
+Result[0]
+^^^^^^^^^
+
+alpha content index, Range 0:15
+
+
+
+CX2341X_OSD_SET_ALPHA_CONTENT_INDEX
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 98/0x62
+
+Description
+^^^^^^^^^^^
+
+Assign alpha content index
+
+Param[0]
+^^^^^^^^
+
+alpha content index, range 0:15
+
+
+Encoder firmware API description
+--------------------------------
+
+CX2341X_ENC_PING_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 128/0x80
+
+Description
+^^^^^^^^^^^
+
+Does nothing. Can be used to check if the firmware is responding.
+
+
+
+CX2341X_ENC_START_CAPTURE
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 129/0x81
+
+Description
+^^^^^^^^^^^
+
+Commences the capture of video, audio and/or VBI data. All encoding
+parameters must be initialized prior to this API call. Captures frames
+continuously or until a predefined number of frames have been captured.
+
+Param[0]
+^^^^^^^^
+
+Capture stream type:
+
+ - 0=MPEG
+ - 1=Raw
+ - 2=Raw passthrough
+ - 3=VBI
+
+
+Param[1]
+^^^^^^^^
+
+Bitmask:
+
+ - Bit 0 when set, captures YUV
+ - Bit 1 when set, captures PCM audio
+ - Bit 2 when set, captures VBI (same as param[0]=3)
+ - Bit 3 when set, the capture destination is the decoder
+ (same as param[0]=2)
+ - Bit 4 when set, the capture destination is the host
+
+.. note:: this parameter is only meaningful for RAW capture type.
+
+
+
+CX2341X_ENC_STOP_CAPTURE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 130/0x82
+
+Description
+^^^^^^^^^^^
+
+Ends a capture in progress
+
+Param[0]
+^^^^^^^^
+
+- 0=stop at end of GOP (generates IRQ)
+- 1=stop immediate (no IRQ)
+
+Param[1]
+^^^^^^^^
+
+Stream type to stop, see param[0] of API 0x81
+
+Param[2]
+^^^^^^^^
+
+Subtype, see param[1] of API 0x81
+
+
+
+CX2341X_ENC_SET_AUDIO_ID
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 137/0x89
+
+Description
+^^^^^^^^^^^
+
+Assigns the transport stream ID of the encoded audio stream
+
+Param[0]
+^^^^^^^^
+
+Audio Stream ID
+
+
+
+CX2341X_ENC_SET_VIDEO_ID
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 139/0x8B
+
+Description
+^^^^^^^^^^^
+
+Set video transport stream ID
+
+Param[0]
+^^^^^^^^
+
+Video stream ID
+
+
+
+CX2341X_ENC_SET_PCR_ID
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 141/0x8D
+
+Description
+^^^^^^^^^^^
+
+Assigns the transport stream ID for PCR packets
+
+Param[0]
+^^^^^^^^
+
+PCR Stream ID
+
+
+
+CX2341X_ENC_SET_FRAME_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 143/0x8F
+
+Description
+^^^^^^^^^^^
+
+Set video frames per second. Change occurs at start of new GOP.
+
+Param[0]
+^^^^^^^^
+
+- 0=30fps
+- 1=25fps
+
+
+
+CX2341X_ENC_SET_FRAME_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 145/0x91
+
+Description
+^^^^^^^^^^^
+
+Select video stream encoding resolution.
+
+Param[0]
+^^^^^^^^
+
+Height in lines. Default 480
+
+Param[1]
+^^^^^^^^
+
+Width in pixels. Default 720
+
+
+
+CX2341X_ENC_SET_BIT_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 149/0x95
+
+Description
+^^^^^^^^^^^
+
+Assign average video stream bitrate.
+
+Param[0]
+^^^^^^^^
+
+0=variable bitrate, 1=constant bitrate
+
+Param[1]
+^^^^^^^^
+
+bitrate in bits per second
+
+Param[2]
+^^^^^^^^
+
+peak bitrate in bits per second, divided by 400
+
+Param[3]
+^^^^^^^^
+
+Mux bitrate in bits per second, divided by 400. May be 0 (default).
+
+Param[4]
+^^^^^^^^
+
+Rate Control VBR Padding
+
+Param[5]
+^^^^^^^^
+
+VBV Buffer used by encoder
+
+.. note::
+
+ #) Param\[3\] and Param\[4\] seem to be always 0
+ #) Param\[5\] doesn't seem to be used.
+
+
+
+CX2341X_ENC_SET_GOP_PROPERTIES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 151/0x97
+
+Description
+^^^^^^^^^^^
+
+Setup the GOP structure
+
+Param[0]
+^^^^^^^^
+
+GOP size (maximum is 34)
+
+Param[1]
+^^^^^^^^
+
+Number of B frames between the I and P frame, plus 1.
+For example: IBBPBBPBBPBB --> GOP size: 12, number of B frames: 2+1 = 3
+
+.. note::
+
+ GOP size must be a multiple of (B-frames + 1).
+
+
+
+CX2341X_ENC_SET_ASPECT_RATIO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 153/0x99
+
+Description
+^^^^^^^^^^^
+
+Sets the encoding aspect ratio. Changes in the aspect ratio take effect
+at the start of the next GOP.
+
+Param[0]
+^^^^^^^^
+
+- '0000' forbidden
+- '0001' 1:1 square
+- '0010' 4:3
+- '0011' 16:9
+- '0100' 2.21:1
+- '0101' to '1111' reserved
+
+
+
+CX2341X_ENC_SET_DNR_FILTER_MODE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 155/0x9B
+
+Description
+^^^^^^^^^^^
+
+Assign Dynamic Noise Reduction operating mode
+
+Param[0]
+^^^^^^^^
+
+Bit0: Spatial filter, set=auto, clear=manual
+Bit1: Temporal filter, set=auto, clear=manual
+
+Param[1]
+^^^^^^^^
+
+Median filter:
+
+- 0=Disabled
+- 1=Horizontal
+- 2=Vertical
+- 3=Horiz/Vert
+- 4=Diagonal
+
+
+
+CX2341X_ENC_SET_DNR_FILTER_PROPS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 157/0x9D
+
+Description
+^^^^^^^^^^^
+
+These Dynamic Noise Reduction filter values are only meaningful when
+the respective filter is set to "manual" (See API 0x9B)
+
+Param[0]
+^^^^^^^^
+
+Spatial filter: default 0, range 0:15
+
+Param[1]
+^^^^^^^^
+
+Temporal filter: default 0, range 0:31
+
+
+
+CX2341X_ENC_SET_CORING_LEVELS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 159/0x9F
+
+Description
+^^^^^^^^^^^
+
+Assign Dynamic Noise Reduction median filter properties.
+
+Param[0]
+^^^^^^^^
+
+Threshold above which the luminance median filter is enabled.
+Default: 0, range 0:255
+
+Param[1]
+^^^^^^^^
+
+Threshold below which the luminance median filter is enabled.
+Default: 255, range 0:255
+
+Param[2]
+^^^^^^^^
+
+Threshold above which the chrominance median filter is enabled.
+Default: 0, range 0:255
+
+Param[3]
+^^^^^^^^
+
+Threshold below which the chrominance median filter is enabled.
+Default: 255, range 0:255
+
+
+
+CX2341X_ENC_SET_SPATIAL_FILTER_TYPE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 161/0xA1
+
+Description
+^^^^^^^^^^^
+
+Assign spatial prefilter parameters
+
+Param[0]
+^^^^^^^^
+
+Luminance filter
+
+- 0=Off
+- 1=1D Horizontal
+- 2=1D Vertical
+- 3=2D H/V Separable (default)
+- 4=2D Symmetric non-separable
+
+Param[1]
+^^^^^^^^
+
+Chrominance filter
+
+- 0=Off
+- 1=1D Horizontal (default)
+
+
+
+CX2341X_ENC_SET_VBI_LINE
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 183/0xB7
+
+Description
+^^^^^^^^^^^
+
+Selects VBI line number.
+
+Param[0]
+^^^^^^^^
+
+- Bits 0:4 line number
+- Bit 31 0=top_field, 1=bottom_field
+- Bits 0:31 all set specifies "all lines"
+
+Param[1]
+^^^^^^^^
+
+VBI line information features: 0=disabled, 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Slicing: 0=None, 1=Closed Caption
+Almost certainly not implemented. Set to 0.
+
+Param[3]
+^^^^^^^^
+
+Luminance samples in this line.
+Almost certainly not implemented. Set to 0.
+
+Param[4]
+^^^^^^^^
+
+Chrominance samples in this line
+Almost certainly not implemented. Set to 0.
+
+
+
+CX2341X_ENC_SET_STREAM_TYPE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 185/0xB9
+
+Description
+^^^^^^^^^^^
+
+Assign stream type
+
+.. note::
+
+ Transport stream is not working in recent firmwares.
+ And in older firmwares the timestamps in the TS seem to be
+ unreliable.
+
+Param[0]
+^^^^^^^^
+
+- 0=Program stream
+- 1=Transport stream
+- 2=MPEG1 stream
+- 3=PES A/V stream
+- 5=PES Video stream
+- 7=PES Audio stream
+- 10=DVD stream
+- 11=VCD stream
+- 12=SVCD stream
+- 13=DVD_S1 stream
+- 14=DVD_S2 stream
+
+
+
+CX2341X_ENC_SET_OUTPUT_PORT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 187/0xBB
+
+Description
+^^^^^^^^^^^
+
+Assign stream output port. Normally 0 when the data is copied through
+the PCI bus (DMA), and 1 when the data is streamed to another chip
+(pvrusb and cx88-blackbird).
+
+Param[0]
+^^^^^^^^
+
+- 0=Memory (default)
+- 1=Streaming
+- 2=Serial
+
+Param[1]
+^^^^^^^^
+
+Unknown, but leaving this to 0 seems to work best. Indications are that
+this might have to do with USB support, although passing anything but 0
+only breaks things.
+
+
+
+CX2341X_ENC_SET_AUDIO_PROPERTIES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 189/0xBD
+
+Description
+^^^^^^^^^^^
+
+Set audio stream properties, may be called while encoding is in progress.
+
+.. note::
+
+ All bitfields are consistent with ISO11172 documentation except
+ bits 2:3 which ISO docs define as:
+
+ - '11' Layer I
+ - '10' Layer II
+ - '01' Layer III
+ - '00' Undefined
+
+ This discrepancy may indicate a possible error in the documentation.
+ Testing indicated that only Layer II is actually working, and that
+ the minimum bitrate should be 192 kbps.
+
+Param[0]
+^^^^^^^^
+
+Bitmask:
+
+.. code-block:: none
+
+ 0:1 '00' 44.1Khz
+ '01' 48Khz
+ '10' 32Khz
+ '11' reserved
+
+ 2:3 '01'=Layer I
+ '10'=Layer II
+
+ 4:7 Bitrate:
+ Index | Layer I | Layer II
+ ------+-------------+------------
+ '0000' | free format | free format
+ '0001' | 32 kbit/s | 32 kbit/s
+ '0010' | 64 kbit/s | 48 kbit/s
+ '0011' | 96 kbit/s | 56 kbit/s
+ '0100' | 128 kbit/s | 64 kbit/s
+ '0101' | 160 kbit/s | 80 kbit/s
+ '0110' | 192 kbit/s | 96 kbit/s
+ '0111' | 224 kbit/s | 112 kbit/s
+ '1000' | 256 kbit/s | 128 kbit/s
+ '1001' | 288 kbit/s | 160 kbit/s
+ '1010' | 320 kbit/s | 192 kbit/s
+ '1011' | 352 kbit/s | 224 kbit/s
+ '1100' | 384 kbit/s | 256 kbit/s
+ '1101' | 416 kbit/s | 320 kbit/s
+ '1110' | 448 kbit/s | 384 kbit/s
+
+ .. note::
+
+ For Layer II, not all combinations of total bitrate
+ and mode are allowed. See ISO11172-3 3-Annex B,
+ Table 3-B.2
+
+ 8:9 '00'=Stereo
+ '01'=JointStereo
+ '10'=Dual
+ '11'=Mono
+
+ .. note::
+
+ The cx23415 cannot decode Joint Stereo properly.
+
+ 10:11 Mode Extension used in joint_stereo mode.
+ In Layer I and II they indicate which subbands are in
+ intensity_stereo. All other subbands are coded in stereo.
+ '00' subbands 4-31 in intensity_stereo, bound==4
+ '01' subbands 8-31 in intensity_stereo, bound==8
+ '10' subbands 12-31 in intensity_stereo, bound==12
+ '11' subbands 16-31 in intensity_stereo, bound==16
+
+ 12:13 Emphasis:
+ '00' None
+ '01' 50/15uS
+ '10' reserved
+ '11' CCITT J.17
+
+ 14 CRC:
+ '0' off
+ '1' on
+
+ 15 Copyright:
+ '0' off
+ '1' on
+
+ 16 Generation:
+ '0' copy
+ '1' original
+
+
+
+CX2341X_ENC_HALT_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 195/0xC3
+
+Description
+^^^^^^^^^^^
+
+The firmware is halted and no further API calls are serviced until the
+firmware is uploaded again.
+
+
+
+CX2341X_ENC_GET_VERSION
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 196/0xC4
+
+Description
+^^^^^^^^^^^
+
+Returns the version of the encoder firmware.
+
+Result[0]
+^^^^^^^^^
+
+Version bitmask:
+- Bits 0:15 build
+- Bits 16:23 minor
+- Bits 24:31 major
+
+
+
+CX2341X_ENC_SET_GOP_CLOSURE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 197/0xC5
+
+Description
+^^^^^^^^^^^
+
+Assigns the GOP open/close property.
+
+Param[0]
+^^^^^^^^
+
+- 0=Open
+- 1=Closed
+
+
+
+CX2341X_ENC_GET_SEQ_END
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 198/0xC6
+
+Description
+^^^^^^^^^^^
+
+Obtains the sequence end code of the encoder's buffer. When a capture
+is started a number of interrupts are still generated, the last of
+which will have Result[0] set to 1 and Result[1] will contain the size
+of the buffer.
+
+Result[0]
+^^^^^^^^^
+
+State of the transfer (1 if last buffer)
+
+Result[1]
+^^^^^^^^^
+
+If Result[0] is 1, this contains the size of the last buffer, undefined
+otherwise.
+
+
+
+CX2341X_ENC_SET_PGM_INDEX_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 199/0xC7
+
+Description
+^^^^^^^^^^^
+
+Sets the Program Index Information.
+The information is stored as follows:
+
+.. code-block:: c
+
+ struct info {
+ u32 length; // Length of this frame
+ u32 offset_low; // Offset in the file of the
+ u32 offset_high; // start of this frame
+ u32 mask1; // Bits 0-2 are the type mask:
+ // 1=I, 2=P, 4=B
+ // 0=End of Program Index, other fields
+ // are invalid.
+ u32 pts; // The PTS of the frame
+ u32 mask2; // Bit 0 is bit 32 of the pts.
+ };
+ u32 table_ptr;
+ struct info index[400];
+
+The table_ptr is the encoder memory address in the table were
+*new* entries will be written.
+
+.. note:: This is a ringbuffer, so the table_ptr will wraparound.
+
+Param[0]
+^^^^^^^^
+
+Picture Mask:
+- 0=No index capture
+- 1=I frames
+- 3=I,P frames
+- 7=I,P,B frames
+
+(Seems to be ignored, it always indexes I, P and B frames)
+
+Param[1]
+^^^^^^^^
+
+Elements requested (up to 400)
+
+Result[0]
+^^^^^^^^^
+
+Offset in the encoder memory of the start of the table.
+
+Result[1]
+^^^^^^^^^
+
+Number of allocated elements up to a maximum of Param[1]
+
+
+
+CX2341X_ENC_SET_VBI_CONFIG
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 200/0xC8
+
+Description
+^^^^^^^^^^^
+
+Configure VBI settings
+
+Param[0]
+^^^^^^^^
+
+Bitmap:
+
+.. code-block:: none
+
+ 0 Mode '0' Sliced, '1' Raw
+ 1:3 Insertion:
+ '000' insert in extension & user data
+ '001' insert in private packets
+ '010' separate stream and user data
+ '111' separate stream and private data
+ 8:15 Stream ID (normally 0xBD)
+
+Param[1]
+^^^^^^^^
+
+Frames per interrupt (max 8). Only valid in raw mode.
+
+Param[2]
+^^^^^^^^
+
+Total raw VBI frames. Only valid in raw mode.
+
+Param[3]
+^^^^^^^^
+
+Start codes
+
+Param[4]
+^^^^^^^^
+
+Stop codes
+
+Param[5]
+^^^^^^^^
+
+Lines per frame
+
+Param[6]
+^^^^^^^^
+
+Byte per line
+
+Result[0]
+^^^^^^^^^
+
+Observed frames per interrupt in raw mode only. Rage 1 to Param[1]
+
+Result[1]
+^^^^^^^^^
+
+Observed number of frames in raw mode. Range 1 to Param[2]
+
+Result[2]
+^^^^^^^^^
+
+Memory offset to start or raw VBI data
+
+
+
+CX2341X_ENC_SET_DMA_BLOCK_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 201/0xC9
+
+Description
+^^^^^^^^^^^
+
+Set DMA transfer block size
+
+Param[0]
+^^^^^^^^
+
+DMA transfer block size in bytes or frames. When unit is bytes,
+supported block sizes are 2^7, 2^8 and 2^9 bytes.
+
+Param[1]
+^^^^^^^^
+
+Unit: 0=bytes, 1=frames
+
+
+
+CX2341X_ENC_GET_PREV_DMA_INFO_MB_10
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 202/0xCA
+
+Description
+^^^^^^^^^^^
+
+Returns information on the previous DMA transfer in conjunction with
+bit 27 of the interrupt mask. Uses mailbox 10.
+
+Result[0]
+^^^^^^^^^
+
+Type of stream
+
+Result[1]
+^^^^^^^^^
+
+Address Offset
+
+Result[2]
+^^^^^^^^^
+
+Maximum size of transfer
+
+
+
+CX2341X_ENC_GET_PREV_DMA_INFO_MB_9
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 203/0xCB
+
+Description
+^^^^^^^^^^^
+
+Returns information on the previous DMA transfer in conjunction with
+bit 27 or 18 of the interrupt mask. Uses mailbox 9.
+
+Result[0]
+^^^^^^^^^
+
+Status bits:
+- 0 read completed
+- 1 write completed
+- 2 DMA read error
+- 3 DMA write error
+- 4 Scatter-Gather array error
+
+Result[1]
+^^^^^^^^^
+
+DMA type
+
+Result[2]
+^^^^^^^^^
+
+Presentation Time Stamp bits 0..31
+
+Result[3]
+^^^^^^^^^
+
+Presentation Time Stamp bit 32
+
+
+
+CX2341X_ENC_SCHED_DMA_TO_HOST
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 204/0xCC
+
+Description
+^^^^^^^^^^^
+
+Setup DMA to host operation
+
+Param[0]
+^^^^^^^^
+
+Memory address of link list
+
+Param[1]
+^^^^^^^^
+
+Length of link list (wtf: what units ???)
+
+Param[2]
+^^^^^^^^
+
+DMA type (0=MPEG)
+
+
+
+CX2341X_ENC_INITIALIZE_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 205/0xCD
+
+Description
+^^^^^^^^^^^
+
+Initializes the video input
+
+
+
+CX2341X_ENC_SET_FRAME_DROP_RATE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 208/0xD0
+
+Description
+^^^^^^^^^^^
+
+For each frame captured, skip specified number of frames.
+
+Param[0]
+^^^^^^^^
+
+Number of frames to skip
+
+
+
+CX2341X_ENC_PAUSE_ENCODER
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 210/0xD2
+
+Description
+^^^^^^^^^^^
+
+During a pause condition, all frames are dropped instead of being encoded.
+
+Param[0]
+^^^^^^^^
+
+- 0=Pause encoding
+- 1=Continue encoding
+
+
+
+CX2341X_ENC_REFRESH_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 211/0xD3
+
+Description
+^^^^^^^^^^^
+
+Refreshes the video input
+
+
+
+CX2341X_ENC_SET_COPYRIGHT
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 212/0xD4
+
+Description
+^^^^^^^^^^^
+
+Sets stream copyright property
+
+Param[0]
+^^^^^^^^
+
+
+- 0=Stream is not copyrighted
+- 1=Stream is copyrighted
+
+
+
+CX2341X_ENC_SET_EVENT_NOTIFICATION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 213/0xD5
+
+Description
+^^^^^^^^^^^
+
+Setup firmware to notify the host about a particular event. Host must
+unmask the interrupt bit.
+
+Param[0]
+^^^^^^^^
+
+Event (0=refresh encoder input)
+
+Param[1]
+^^^^^^^^
+
+Notification 0=disabled 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Interrupt bit
+
+Param[3]
+^^^^^^^^
+
+Mailbox slot, -1 if no mailbox required.
+
+
+
+CX2341X_ENC_SET_NUM_VSYNC_LINES
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 214/0xD6
+
+Description
+^^^^^^^^^^^
+
+Depending on the analog video decoder used, this assigns the number
+of lines for field 1 and 2.
+
+Param[0]
+^^^^^^^^
+
+Field 1 number of lines:
+- 0x00EF for SAA7114
+- 0x00F0 for SAA7115
+- 0x0105 for Micronas
+
+Param[1]
+^^^^^^^^
+
+Field 2 number of lines:
+- 0x00EF for SAA7114
+- 0x00F0 for SAA7115
+- 0x0106 for Micronas
+
+
+
+CX2341X_ENC_SET_PLACEHOLDER
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 215/0xD7
+
+Description
+^^^^^^^^^^^
+
+Provides a mechanism of inserting custom user data in the MPEG stream.
+
+Param[0]
+^^^^^^^^
+
+- 0=extension & user data
+- 1=private packet with stream ID 0xBD
+
+Param[1]
+^^^^^^^^
+
+Rate at which to insert data, in units of frames (for private packet)
+or GOPs (for ext. & user data)
+
+Param[2]
+^^^^^^^^
+
+Number of data DWORDs (below) to insert
+
+Param[3]
+^^^^^^^^
+
+Custom data 0
+
+Param[4]
+^^^^^^^^
+
+Custom data 1
+
+Param[5]
+^^^^^^^^
+
+Custom data 2
+
+Param[6]
+^^^^^^^^
+
+Custom data 3
+
+Param[7]
+^^^^^^^^
+
+Custom data 4
+
+Param[8]
+^^^^^^^^
+
+Custom data 5
+
+Param[9]
+^^^^^^^^
+
+Custom data 6
+
+Param[10]
+^^^^^^^^^
+
+Custom data 7
+
+Param[11]
+^^^^^^^^^
+
+Custom data 8
+
+
+
+CX2341X_ENC_MUTE_VIDEO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 217/0xD9
+
+Description
+^^^^^^^^^^^
+
+Video muting
+
+Param[0]
+^^^^^^^^
+
+Bit usage:
+
+.. code-block:: none
+
+ 0 '0'=video not muted
+ '1'=video muted, creates frames with the YUV color defined below
+ 1:7 Unused
+ 8:15 V chrominance information
+ 16:23 U chrominance information
+ 24:31 Y luminance information
+
+
+
+CX2341X_ENC_MUTE_AUDIO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 218/0xDA
+
+Description
+^^^^^^^^^^^
+
+Audio muting
+
+Param[0]
+^^^^^^^^
+
+- 0=audio not muted
+- 1=audio muted (produces silent mpeg audio stream)
+
+
+
+CX2341X_ENC_SET_VERT_CROP_LINE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 219/0xDB
+
+Description
+^^^^^^^^^^^
+
+Something to do with 'Vertical Crop Line'
+
+Param[0]
+^^^^^^^^
+
+If saa7114 and raw VBI capture and 60 Hz, then set to 10001.
+Else 0.
+
+
+
+CX2341X_ENC_MISC
+~~~~~~~~~~~~~~~~
+
+Enum: 220/0xDC
+
+Description
+^^^^^^^^^^^
+
+Miscellaneous actions. Not known for 100% what it does. It's really a
+sort of ioctl call. The first parameter is a command number, the second
+the value.
+
+Param[0]
+^^^^^^^^
+
+Command number:
+
+.. code-block:: none
+
+ 1=set initial SCR value when starting encoding (works).
+ 2=set quality mode (apparently some test setting).
+ 3=setup advanced VIM protection handling.
+ Always 1 for the cx23416 and 0 for cx23415.
+ 4=generate DVD compatible PTS timestamps
+ 5=USB flush mode
+ 6=something to do with the quantization matrix
+ 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
+ packets to the MPEG. The size of these packets is 2048 bytes (including
+ the header of 6 bytes: 0x000001bf + length). The payload is zeroed and
+ it is up to the application to fill them in. These packets are apparently
+ inserted every four frames.
+ 8=enable scene change detection (seems to be a failure)
+ 9=set history parameters of the video input module
+ 10=set input field order of VIM
+ 11=set quantization matrix
+ 12=reset audio interface after channel change or input switch (has no argument).
+ Needed for the cx2584x, not needed for the mspx4xx, but it doesn't seem to
+ do any harm calling it regardless.
+ 13=set audio volume delay
+ 14=set audio delay
+
+
+Param[1]
+^^^^^^^^
+
+Command value.
+
+Decoder firmware API description
+--------------------------------
+
+.. note:: this API is part of the decoder firmware, so it's cx23415 only.
+
+
+
+CX2341X_DEC_PING_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 0/0x00
+
+Description
+^^^^^^^^^^^
+
+This API call does nothing. It may be used to check if the firmware
+is responding.
+
+
+
+CX2341X_DEC_START_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 1/0x01
+
+Description
+^^^^^^^^^^^
+
+Begin or resume playback.
+
+Param[0]
+^^^^^^^^
+
+0 based frame number in GOP to begin playback from.
+
+Param[1]
+^^^^^^^^
+
+Specifies the number of muted audio frames to play before normal
+audio resumes. (This is not implemented in the firmware, leave at 0)
+
+
+
+CX2341X_DEC_STOP_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 2/0x02
+
+Description
+^^^^^^^^^^^
+
+Ends playback and clears all decoder buffers. If PTS is not zero,
+playback stops at specified PTS.
+
+Param[0]
+^^^^^^^^
+
+Display 0=last frame, 1=black
+
+.. note::
+
+ this takes effect immediately, so if you want to wait for a PTS,
+ then use '0', otherwise the screen goes to black at once.
+ You can call this later (even if there is no playback) with a 1 value
+ to set the screen to black.
+
+Param[1]
+^^^^^^^^
+
+PTS low
+
+Param[2]
+^^^^^^^^
+
+PTS high
+
+
+
+CX2341X_DEC_SET_PLAYBACK_SPEED
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 3/0x03
+
+Description
+^^^^^^^^^^^
+
+Playback stream at speed other than normal. There are two modes of
+operation:
+
+ - Smooth: host transfers entire stream and firmware drops unused
+ frames.
+ - Coarse: host drops frames based on indexing as required to achieve
+ desired speed.
+
+Param[0]
+^^^^^^^^
+
+.. code-block:: none
+
+ Bitmap:
+ 0:7 0 normal
+ 1 fast only "1.5 times"
+ n nX fast, 1/nX slow
+ 30 Framedrop:
+ '0' during 1.5 times play, every other B frame is dropped
+ '1' during 1.5 times play, stream is unchanged (bitrate
+ must not exceed 8mbps)
+ 31 Speed:
+ '0' slow
+ '1' fast
+
+.. note::
+
+ n is limited to 2. Anything higher does not result in
+ faster playback. Instead the host should start dropping frames.
+
+Param[1]
+^^^^^^^^
+
+Direction: 0=forward, 1=reverse
+
+.. note::
+
+ to make reverse playback work you have to write full GOPs in
+ reverse order.
+
+Param[2]
+^^^^^^^^
+
+.. code-block:: none
+
+ Picture mask:
+ 1=I frames
+ 3=I, P frames
+ 7=I, P, B frames
+
+Param[3]
+^^^^^^^^
+
+B frames per GOP (for reverse play only)
+
+.. note::
+
+ for reverse playback the Picture Mask should be set to I or I, P.
+ Adding B frames to the mask will result in corrupt video. This field
+ has to be set to the correct value in order to keep the timing correct.
+
+Param[4]
+^^^^^^^^
+
+Mute audio: 0=disable, 1=enable
+
+Param[5]
+^^^^^^^^
+
+Display 0=frame, 1=field
+
+Param[6]
+^^^^^^^^
+
+Specifies the number of muted audio frames to play before normal audio
+resumes. (Not implemented in the firmware, leave at 0)
+
+
+
+CX2341X_DEC_STEP_VIDEO
+~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 5/0x05
+
+Description
+^^^^^^^^^^^
+
+Each call to this API steps the playback to the next unit defined below
+in the current playback direction.
+
+Param[0]
+^^^^^^^^
+
+0=frame, 1=top field, 2=bottom field
+
+
+
+CX2341X_DEC_SET_DMA_BLOCK_SIZE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 8/0x08
+
+Description
+^^^^^^^^^^^
+
+Set DMA transfer block size. Counterpart to API 0xC9
+
+Param[0]
+^^^^^^^^
+
+DMA transfer block size in bytes. A different size may be specified
+when issuing the DMA transfer command.
+
+
+
+CX2341X_DEC_GET_XFER_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 9/0x09
+
+Description
+^^^^^^^^^^^
+
+This API call may be used to detect an end of stream condition.
+
+Result[0]
+^^^^^^^^^
+
+Stream type
+
+Result[1]
+^^^^^^^^^
+
+Address offset
+
+Result[2]
+^^^^^^^^^
+
+Maximum bytes to transfer
+
+Result[3]
+^^^^^^^^^
+
+Buffer fullness
+
+
+
+CX2341X_DEC_GET_DMA_STATUS
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 10/0x0A
+
+Description
+^^^^^^^^^^^
+
+Status of the last DMA transfer
+
+Result[0]
+^^^^^^^^^
+
+Bit 1 set means transfer complete
+Bit 2 set means DMA error
+Bit 3 set means linked list error
+
+Result[1]
+^^^^^^^^^
+
+DMA type: 0=MPEG, 1=OSD, 2=YUV
+
+
+
+CX2341X_DEC_SCHED_DMA_FROM_HOST
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 11/0x0B
+
+Description
+^^^^^^^^^^^
+
+Setup DMA from host operation. Counterpart to API 0xCC
+
+Param[0]
+^^^^^^^^
+
+Memory address of link list
+
+Param[1]
+^^^^^^^^
+
+Total # of bytes to transfer
+
+Param[2]
+^^^^^^^^
+
+DMA type (0=MPEG, 1=OSD, 2=YUV)
+
+
+
+CX2341X_DEC_PAUSE_PLAYBACK
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 13/0x0D
+
+Description
+^^^^^^^^^^^
+
+Freeze playback immediately. In this mode, when internal buffers are
+full, no more data will be accepted and data request IRQs will be
+masked.
+
+Param[0]
+^^^^^^^^
+
+Display: 0=last frame, 1=black
+
+
+
+CX2341X_DEC_HALT_FW
+~~~~~~~~~~~~~~~~~~~
+
+Enum: 14/0x0E
+
+Description
+^^^^^^^^^^^
+
+The firmware is halted and no further API calls are serviced until
+the firmware is uploaded again.
+
+
+
+CX2341X_DEC_SET_STANDARD
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 16/0x10
+
+Description
+^^^^^^^^^^^
+
+Selects display standard
+
+Param[0]
+^^^^^^^^
+
+0=NTSC, 1=PAL
+
+
+
+CX2341X_DEC_GET_VERSION
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 17/0x11
+
+Description
+^^^^^^^^^^^
+
+Returns decoder firmware version information
+
+Result[0]
+^^^^^^^^^
+
+Version bitmask:
+ - Bits 0:15 build
+ - Bits 16:23 minor
+ - Bits 24:31 major
+
+
+
+CX2341X_DEC_SET_STREAM_INPUT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 20/0x14
+
+Description
+^^^^^^^^^^^
+
+Select decoder stream input port
+
+Param[0]
+^^^^^^^^
+
+0=memory (default), 1=streaming
+
+
+
+CX2341X_DEC_GET_TIMING_INFO
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 21/0x15
+
+Description
+^^^^^^^^^^^
+
+Returns timing information from start of playback
+
+Result[0]
+^^^^^^^^^
+
+Frame count by decode order
+
+Result[1]
+^^^^^^^^^
+
+Video PTS bits 0:31 by display order
+
+Result[2]
+^^^^^^^^^
+
+Video PTS bit 32 by display order
+
+Result[3]
+^^^^^^^^^
+
+SCR bits 0:31 by display order
+
+Result[4]
+^^^^^^^^^
+
+SCR bit 32 by display order
+
+
+
+CX2341X_DEC_SET_AUDIO_MODE
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 22/0x16
+
+Description
+^^^^^^^^^^^
+
+Select audio mode
+
+Param[0]
+^^^^^^^^
+
+Dual mono mode action
+ 0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
+
+Param[1]
+^^^^^^^^
+
+Stereo mode action:
+ 0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
+
+
+
+CX2341X_DEC_SET_EVENT_NOTIFICATION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 23/0x17
+
+Description
+^^^^^^^^^^^
+
+Setup firmware to notify the host about a particular event.
+Counterpart to API 0xD5
+
+Param[0]
+^^^^^^^^
+
+Event:
+ - 0=Audio mode change between mono, (joint) stereo and dual channel.
+ - 3=Decoder started
+ - 4=Unknown: goes off 10-15 times per second while decoding.
+ - 5=Some sync event: goes off once per frame.
+
+Param[1]
+^^^^^^^^
+
+Notification 0=disabled, 1=enabled
+
+Param[2]
+^^^^^^^^
+
+Interrupt bit
+
+Param[3]
+^^^^^^^^
+
+Mailbox slot, -1 if no mailbox required.
+
+
+
+CX2341X_DEC_SET_DISPLAY_BUFFERS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 24/0x18
+
+Description
+^^^^^^^^^^^
+
+Number of display buffers. To decode all frames in reverse playback you
+must use nine buffers.
+
+Param[0]
+^^^^^^^^
+
+0=six buffers, 1=nine buffers
+
+
+
+CX2341X_DEC_EXTRACT_VBI
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 25/0x19
+
+Description
+^^^^^^^^^^^
+
+Extracts VBI data
+
+Param[0]
+^^^^^^^^
+
+0=extract from extension & user data, 1=extract from private packets
+
+Result[0]
+^^^^^^^^^
+
+VBI table location
+
+Result[1]
+^^^^^^^^^
+
+VBI table size
+
+
+
+CX2341X_DEC_SET_DECODER_SOURCE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 26/0x1A
+
+Description
+^^^^^^^^^^^
+
+Selects decoder source. Ensure that the parameters passed to this
+API match the encoder settings.
+
+Param[0]
+^^^^^^^^
+
+Mode: 0=MPEG from host, 1=YUV from encoder, 2=YUV from host
+
+Param[1]
+^^^^^^^^
+
+YUV picture width
+
+Param[2]
+^^^^^^^^
+
+YUV picture height
+
+Param[3]
+^^^^^^^^
+
+Bitmap: see Param[0] of API 0xBD
+
+
+
+CX2341X_DEC_SET_PREBUFFERING
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enum: 30/0x1E
+
+Description
+^^^^^^^^^^^
+
+Decoder prebuffering, when enabled up to 128KB are buffered for
+streams <8mpbs or 640KB for streams >8mbps
+
+Param[0]
+^^^^^^^^
+
+0=off, 1=on
+
+PVR350 Video decoder registers 0x02002800 -> 0x02002B00
+-------------------------------------------------------
+
+Author: Ian Armstrong <ian@iarmst.demon.co.uk>
+
+Version: v0.4
+
+Date: 12 March 2007
+
+
+This list has been worked out through trial and error. There will be mistakes
+and omissions. Some registers have no obvious effect so it's hard to say what
+they do, while others interact with each other, or require a certain load
+sequence. Horizontal filter setup is one example, with six registers working
+in unison and requiring a certain load sequence to correctly configure. The
+indexed colour palette is much easier to set at just two registers, but again
+it requires a certain load sequence.
+
+Some registers are fussy about what they are set to. Load in a bad value & the
+decoder will fail. A firmware reload will often recover, but sometimes a reset
+is required. For registers containing size information, setting them to 0 is
+generally a bad idea. For other control registers i.e. 2878, you'll only find
+out what values are bad when it hangs.
+
+.. code-block:: none
+
+ --------------------------------------------------------------------------------
+ 2800
+ bit 0
+ Decoder enable
+ 0 = disable
+ 1 = enable
+ --------------------------------------------------------------------------------
+ 2804
+ bits 0:31
+ Decoder horizontal Y alias register 1
+ ---------------
+ 2808
+ bits 0:31
+ Decoder horizontal Y alias register 2
+ ---------------
+ 280C
+ bits 0:31
+ Decoder horizontal Y alias register 3
+ ---------------
+ 2810
+ bits 0:31
+ Decoder horizontal Y alias register 4
+ ---------------
+ 2814
+ bits 0:31
+ Decoder horizontal Y alias register 5
+ ---------------
+ 2818
+ bits 0:31
+ Decoder horizontal Y alias trigger
+
+ These six registers control the horizontal aliasing filter for the Y plane.
+ The first five registers must all be loaded before accessing the trigger
+ (2818), as this register actually clocks the data through for the first
+ five.
+
+ To correctly program set the filter, this whole procedure must be done 16
+ times. The actual register contents are copied from a lookup-table in the
+ firmware which contains 4 different filter settings.
+
+ --------------------------------------------------------------------------------
+ 281C
+ bits 0:31
+ Decoder horizontal UV alias register 1
+ ---------------
+ 2820
+ bits 0:31
+ Decoder horizontal UV alias register 2
+ ---------------
+ 2824
+ bits 0:31
+ Decoder horizontal UV alias register 3
+ ---------------
+ 2828
+ bits 0:31
+ Decoder horizontal UV alias register 4
+ ---------------
+ 282C
+ bits 0:31
+ Decoder horizontal UV alias register 5
+ ---------------
+ 2830
+ bits 0:31
+ Decoder horizontal UV alias trigger
+
+ These six registers control the horizontal aliasing for the UV plane.
+ Operation is the same as the Y filter, with 2830 being the trigger
+ register.
+
+ --------------------------------------------------------------------------------
+ 2834
+ bits 0:15
+ Decoder Y source width in pixels
+
+ bits 16:31
+ Decoder Y destination width in pixels
+ ---------------
+ 2838
+ bits 0:15
+ Decoder UV source width in pixels
+
+ bits 16:31
+ Decoder UV destination width in pixels
+
+ NOTE: For both registers, the resulting image must be fully visible on
+ screen. If the image exceeds the right edge both the source and destination
+ size must be adjusted to reflect the visible portion. For the source width,
+ you must take into account the scaling when calculating the new value.
+ --------------------------------------------------------------------------------
+
+ 283C
+ bits 0:31
+ Decoder Y horizontal scaling
+ Normally = Reg 2854 >> 2
+ ---------------
+ 2840
+ bits 0:31
+ Decoder ?? unknown - horizontal scaling
+ Usually 0x00080514
+ ---------------
+ 2844
+ bits 0:31
+ Decoder UV horizontal scaling
+ Normally = Reg 2854 >> 2
+ ---------------
+ 2848
+ bits 0:31
+ Decoder ?? unknown - horizontal scaling
+ Usually 0x00100514
+ ---------------
+ 284C
+ bits 0:31
+ Decoder ?? unknown - Y plane
+ Usually 0x00200020
+ ---------------
+ 2850
+ bits 0:31
+ Decoder ?? unknown - UV plane
+ Usually 0x00200020
+ ---------------
+ 2854
+ bits 0:31
+ Decoder 'master' value for horizontal scaling
+ ---------------
+ 2858
+ bits 0:31
+ Decoder ?? unknown
+ Usually 0
+ ---------------
+ 285C
+ bits 0:31
+ Decoder ?? unknown
+ Normally = Reg 2854 >> 1
+ ---------------
+ 2860
+ bits 0:31
+ Decoder ?? unknown
+ Usually 0
+ ---------------
+ 2864
+ bits 0:31
+ Decoder ?? unknown
+ Normally = Reg 2854 >> 1
+ ---------------
+ 2868
+ bits 0:31
+ Decoder ?? unknown
+ Usually 0
+
+ Most of these registers either control horizontal scaling, or appear linked
+ to it in some way. Register 2854 contains the 'master' value & the other
+ registers can be calculated from that one. You must also remember to
+ correctly set the divider in Reg 2874.
+
+ To enlarge:
+ Reg 2854 = (source_width * 0x00200000) / destination_width
+ Reg 2874 = No divide
+
+ To reduce from full size down to half size:
+ Reg 2854 = (source_width/2 * 0x00200000) / destination width
+ Reg 2874 = Divide by 2
+
+ To reduce from half size down to quarter size:
+ Reg 2854 = (source_width/4 * 0x00200000) / destination width
+ Reg 2874 = Divide by 4
+
+ The result is always rounded up.
+
+ --------------------------------------------------------------------------------
+ 286C
+ bits 0:15
+ Decoder horizontal Y buffer offset
+
+ bits 15:31
+ Decoder horizontal UV buffer offset
+
+ Offset into the video image buffer. If the offset is gradually incremented,
+ the on screen image will move left & wrap around higher up on the right.
+
+ --------------------------------------------------------------------------------
+ 2870
+ bits 0:15
+ Decoder horizontal Y output offset
+
+ bits 16:31
+ Decoder horizontal UV output offset
+
+ Offsets the actual video output. Controls output alignment of the Y & UV
+ planes. The higher the value, the greater the shift to the left. Use
+ reg 2890 to move the image right.
+
+ --------------------------------------------------------------------------------
+ 2874
+ bits 0:1
+ Decoder horizontal Y output size divider
+ 00 = No divide
+ 01 = Divide by 2
+ 10 = Divide by 3
+
+ bits 4:5
+ Decoder horizontal UV output size divider
+ 00 = No divide
+ 01 = Divide by 2
+ 10 = Divide by 3
+
+ bit 8
+ Decoder ?? unknown
+ 0 = Normal
+ 1 = Affects video output levels
+
+ bit 16
+ Decoder ?? unknown
+ 0 = Normal
+ 1 = Disable horizontal filter
+
+ --------------------------------------------------------------------------------
+ 2878
+ bit 0
+ ?? unknown
+
+ bit 1
+ osd on/off
+ 0 = osd off
+ 1 = osd on
+
+ bit 2
+ Decoder + osd video timing
+ 0 = NTSC
+ 1 = PAL
+
+ bits 3:4
+ ?? unknown
+
+ bit 5
+ Decoder + osd
+ Swaps upper & lower fields
+
+ --------------------------------------------------------------------------------
+ 287C
+ bits 0:10
+ Decoder & osd ?? unknown
+ Moves entire screen horizontally. Starts at 0x005 with the screen
+ shifted heavily to the right. Incrementing in steps of 0x004 will
+ gradually shift the screen to the left.
+
+ bits 11:31
+ ?? unknown
+
+ Normally contents are 0x00101111 (NTSC) or 0x1010111d (PAL)
+
+ --------------------------------------------------------------------------------
+ 2880 -------- ?? unknown
+ 2884 -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 2888
+ bit 0
+ Decoder + osd ?? unknown
+ 0 = Normal
+ 1 = Misaligned fields (Correctable through 289C & 28A4)
+
+ bit 4
+ ?? unknown
+
+ bit 8
+ ?? unknown
+
+ Warning: Bad values will require a firmware reload to recover.
+ Known to be bad are 0x000,0x011,0x100,0x111
+ --------------------------------------------------------------------------------
+ 288C
+ bits 0:15
+ osd ?? unknown
+ Appears to affect the osd position stability. The higher the value the
+ more unstable it becomes. Decoder output remains stable.
+
+ bits 16:31
+ osd ?? unknown
+ Same as bits 0:15
+
+ --------------------------------------------------------------------------------
+ 2890
+ bits 0:11
+ Decoder output horizontal offset.
+
+ Horizontal offset moves the video image right. A small left shift is
+ possible, but it's better to use reg 2870 for that due to its greater
+ range.
+
+ NOTE: Video corruption will occur if video window is shifted off the right
+ edge. To avoid this read the notes for 2834 & 2838.
+ --------------------------------------------------------------------------------
+ 2894
+ bits 0:23
+ Decoder output video surround colour.
+
+ Contains the colour (in yuv) used to fill the screen when the video is
+ running in a window.
+ --------------------------------------------------------------------------------
+ 2898
+ bits 0:23
+ Decoder video window colour
+ Contains the colour (in yuv) used to fill the video window when the
+ video is turned off.
+
+ bit 24
+ Decoder video output
+ 0 = Video on
+ 1 = Video off
+
+ bit 28
+ Decoder plane order
+ 0 = Y,UV
+ 1 = UV,Y
+
+ bit 29
+ Decoder second plane byte order
+ 0 = Normal (UV)
+ 1 = Swapped (VU)
+
+ In normal usage, the first plane is Y & the second plane is UV. Though the
+ order of the planes can be swapped, only the byte order of the second plane
+ can be swapped. This isn't much use for the Y plane, but can be useful for
+ the UV plane.
+
+ --------------------------------------------------------------------------------
+ 289C
+ bits 0:15
+ Decoder vertical field offset 1
+
+ bits 16:31
+ Decoder vertical field offset 2
+
+ Controls field output vertical alignment. The higher the number, the lower
+ the image on screen. Known starting values are 0x011E0017 (NTSC) &
+ 0x01500017 (PAL)
+ --------------------------------------------------------------------------------
+ 28A0
+ bits 0:15
+ Decoder & osd width in pixels
+
+ bits 16:31
+ Decoder & osd height in pixels
+
+ All output from the decoder & osd are disabled beyond this area. Decoder
+ output will simply go black outside of this region. If the osd tries to
+ exceed this area it will become corrupt.
+ --------------------------------------------------------------------------------
+ 28A4
+ bits 0:11
+ osd left shift.
+
+ Has a range of 0x770->0x7FF. With the exception of 0, any value outside of
+ this range corrupts the osd.
+ --------------------------------------------------------------------------------
+ 28A8
+ bits 0:15
+ osd vertical field offset 1
+
+ bits 16:31
+ osd vertical field offset 2
+
+ Controls field output vertical alignment. The higher the number, the lower
+ the image on screen. Known starting values are 0x011E0017 (NTSC) &
+ 0x01500017 (PAL)
+ --------------------------------------------------------------------------------
+ 28AC -------- ?? unknown
+ |
+ V
+ 28BC -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 28C0
+ bit 0
+ Current output field
+ 0 = first field
+ 1 = second field
+
+ bits 16:31
+ Current scanline
+ The scanline counts from the top line of the first field
+ through to the last line of the second field.
+ --------------------------------------------------------------------------------
+ 28C4 -------- ?? unknown
+ |
+ V
+ 28F8 -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 28FC
+ bit 0
+ ?? unknown
+ 0 = Normal
+ 1 = Breaks decoder & osd output
+ --------------------------------------------------------------------------------
+ 2900
+ bits 0:31
+ Decoder vertical Y alias register 1
+ ---------------
+ 2904
+ bits 0:31
+ Decoder vertical Y alias register 2
+ ---------------
+ 2908
+ bits 0:31
+ Decoder vertical Y alias trigger
+
+ These three registers control the vertical aliasing filter for the Y plane.
+ Operation is similar to the horizontal Y filter (2804). The only real
+ difference is that there are only two registers to set before accessing
+ the trigger register (2908). As for the horizontal filter, the values are
+ taken from a lookup table in the firmware, and the procedure must be
+ repeated 16 times to fully program the filter.
+ --------------------------------------------------------------------------------
+ 290C
+ bits 0:31
+ Decoder vertical UV alias register 1
+ ---------------
+ 2910
+ bits 0:31
+ Decoder vertical UV alias register 2
+ ---------------
+ 2914
+ bits 0:31
+ Decoder vertical UV alias trigger
+
+ These three registers control the vertical aliasing filter for the UV
+ plane. Operation is the same as the Y filter, with 2914 being the trigger.
+ --------------------------------------------------------------------------------
+ 2918
+ bits 0:15
+ Decoder Y source height in pixels
+
+ bits 16:31
+ Decoder Y destination height in pixels
+ ---------------
+ 291C
+ bits 0:15
+ Decoder UV source height in pixels divided by 2
+
+ bits 16:31
+ Decoder UV destination height in pixels
+
+ NOTE: For both registers, the resulting image must be fully visible on
+ screen. If the image exceeds the bottom edge both the source and
+ destination size must be adjusted to reflect the visible portion. For the
+ source height, you must take into account the scaling when calculating the
+ new value.
+ --------------------------------------------------------------------------------
+ 2920
+ bits 0:31
+ Decoder Y vertical scaling
+ Normally = Reg 2930 >> 2
+ ---------------
+ 2924
+ bits 0:31
+ Decoder Y vertical scaling
+ Normally = Reg 2920 + 0x514
+ ---------------
+ 2928
+ bits 0:31
+ Decoder UV vertical scaling
+ When enlarging = Reg 2930 >> 2
+ When reducing = Reg 2930 >> 3
+ ---------------
+ 292C
+ bits 0:31
+ Decoder UV vertical scaling
+ Normally = Reg 2928 + 0x514
+ ---------------
+ 2930
+ bits 0:31
+ Decoder 'master' value for vertical scaling
+ ---------------
+ 2934
+ bits 0:31
+ Decoder ?? unknown - Y vertical scaling
+ ---------------
+ 2938
+ bits 0:31
+ Decoder Y vertical scaling
+ Normally = Reg 2930
+ ---------------
+ 293C
+ bits 0:31
+ Decoder ?? unknown - Y vertical scaling
+ ---------------
+ 2940
+ bits 0:31
+ Decoder UV vertical scaling
+ When enlarging = Reg 2930 >> 1
+ When reducing = Reg 2930
+ ---------------
+ 2944
+ bits 0:31
+ Decoder ?? unknown - UV vertical scaling
+ ---------------
+ 2948
+ bits 0:31
+ Decoder UV vertical scaling
+ Normally = Reg 2940
+ ---------------
+ 294C
+ bits 0:31
+ Decoder ?? unknown - UV vertical scaling
+
+ Most of these registers either control vertical scaling, or appear linked
+ to it in some way. Register 2930 contains the 'master' value & all other
+ registers can be calculated from that one. You must also remember to
+ correctly set the divider in Reg 296C
+
+ To enlarge:
+ Reg 2930 = (source_height * 0x00200000) / destination_height
+ Reg 296C = No divide
+
+ To reduce from full size down to half size:
+ Reg 2930 = (source_height/2 * 0x00200000) / destination height
+ Reg 296C = Divide by 2
+
+ To reduce from half down to quarter.
+ Reg 2930 = (source_height/4 * 0x00200000) / destination height
+ Reg 296C = Divide by 4
+
+ --------------------------------------------------------------------------------
+ 2950
+ bits 0:15
+ Decoder Y line index into display buffer, first field
+
+ bits 16:31
+ Decoder Y vertical line skip, first field
+ --------------------------------------------------------------------------------
+ 2954
+ bits 0:15
+ Decoder Y line index into display buffer, second field
+
+ bits 16:31
+ Decoder Y vertical line skip, second field
+ --------------------------------------------------------------------------------
+ 2958
+ bits 0:15
+ Decoder UV line index into display buffer, first field
+
+ bits 16:31
+ Decoder UV vertical line skip, first field
+ --------------------------------------------------------------------------------
+ 295C
+ bits 0:15
+ Decoder UV line index into display buffer, second field
+
+ bits 16:31
+ Decoder UV vertical line skip, second field
+ --------------------------------------------------------------------------------
+ 2960
+ bits 0:15
+ Decoder destination height minus 1
+
+ bits 16:31
+ Decoder destination height divided by 2
+ --------------------------------------------------------------------------------
+ 2964
+ bits 0:15
+ Decoder Y vertical offset, second field
+
+ bits 16:31
+ Decoder Y vertical offset, first field
+
+ These two registers shift the Y plane up. The higher the number, the
+ greater the shift.
+ --------------------------------------------------------------------------------
+ 2968
+ bits 0:15
+ Decoder UV vertical offset, second field
+
+ bits 16:31
+ Decoder UV vertical offset, first field
+
+ These two registers shift the UV plane up. The higher the number, the
+ greater the shift.
+ --------------------------------------------------------------------------------
+ 296C
+ bits 0:1
+ Decoder vertical Y output size divider
+ 00 = No divide
+ 01 = Divide by 2
+ 10 = Divide by 4
+
+ bits 8:9
+ Decoder vertical UV output size divider
+ 00 = No divide
+ 01 = Divide by 2
+ 10 = Divide by 4
+ --------------------------------------------------------------------------------
+ 2970
+ bit 0
+ Decoder ?? unknown
+ 0 = Normal
+ 1 = Affect video output levels
+
+ bit 16
+ Decoder ?? unknown
+ 0 = Normal
+ 1 = Disable vertical filter
+
+ --------------------------------------------------------------------------------
+ 2974 -------- ?? unknown
+ |
+ V
+ 29EF -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 2A00
+ bits 0:2
+ osd colour mode
+ 000 = 8 bit indexed
+ 001 = 16 bit (565)
+ 010 = 15 bit (555)
+ 011 = 12 bit (444)
+ 100 = 32 bit (8888)
+
+ bits 4:5
+ osd display bpp
+ 01 = 8 bit
+ 10 = 16 bit
+ 11 = 32 bit
+
+ bit 8
+ osd global alpha
+ 0 = Off
+ 1 = On
+
+ bit 9
+ osd local alpha
+ 0 = Off
+ 1 = On
+
+ bit 10
+ osd colour key
+ 0 = Off
+ 1 = On
+
+ bit 11
+ osd ?? unknown
+ Must be 1
+
+ bit 13
+ osd colour space
+ 0 = ARGB
+ 1 = AYVU
+
+ bits 16:31
+ osd ?? unknown
+ Must be 0x001B (some kind of buffer pointer ?)
+
+ When the bits-per-pixel is set to 8, the colour mode is ignored and
+ assumed to be 8 bit indexed. For 16 & 32 bits-per-pixel the colour depth
+ is honoured, and when using a colour depth that requires fewer bytes than
+ allocated the extra bytes are used as padding. So for a 32 bpp with 8 bit
+ index colour, there are 3 padding bytes per pixel. It's also possible to
+ select 16bpp with a 32 bit colour mode. This results in the pixel width
+ being doubled, but the color key will not work as expected in this mode.
+
+ Colour key is as it suggests. You designate a colour which will become
+ completely transparent. When using 565, 555 or 444 colour modes, the
+ colour key is always 16 bits wide. The colour to key on is set in Reg 2A18.
+
+ Local alpha works differently depending on the colour mode. For 32bpp & 8
+ bit indexed, local alpha is a per-pixel 256 step transparency, with 0 being
+ transparent and 255 being solid. For the 16bpp modes 555 & 444, the unused
+ bit(s) act as a simple transparency switch, with 0 being solid & 1 being
+ fully transparent. There is no local alpha support for 16bit 565.
+
+ Global alpha is a 256 step transparency that applies to the entire osd,
+ with 0 being transparent & 255 being solid.
+
+ It's possible to combine colour key, local alpha & global alpha.
+ --------------------------------------------------------------------------------
+ 2A04
+ bits 0:15
+ osd x coord for left edge
+
+ bits 16:31
+ osd y coord for top edge
+ ---------------
+ 2A08
+ bits 0:15
+ osd x coord for right edge
+
+ bits 16:31
+ osd y coord for bottom edge
+
+ For both registers, (0,0) = top left corner of the display area. These
+ registers do not control the osd size, only where it's positioned & how
+ much is visible. The visible osd area cannot exceed the right edge of the
+ display, otherwise the osd will become corrupt. See reg 2A10 for
+ setting osd width.
+ --------------------------------------------------------------------------------
+ 2A0C
+ bits 0:31
+ osd buffer index
+
+ An index into the osd buffer. Slowly incrementing this moves the osd left,
+ wrapping around onto the right edge
+ --------------------------------------------------------------------------------
+ 2A10
+ bits 0:11
+ osd buffer 32 bit word width
+
+ Contains the width of the osd measured in 32 bit words. This means that all
+ colour modes are restricted to a byte width which is divisible by 4.
+ --------------------------------------------------------------------------------
+ 2A14
+ bits 0:15
+ osd height in pixels
+
+ bits 16:32
+ osd line index into buffer
+ osd will start displaying from this line.
+ --------------------------------------------------------------------------------
+ 2A18
+ bits 0:31
+ osd colour key
+
+ Contains the colour value which will be transparent.
+ --------------------------------------------------------------------------------
+ 2A1C
+ bits 0:7
+ osd global alpha
+
+ Contains the global alpha value (equiv ivtvfbctl --alpha XX)
+ --------------------------------------------------------------------------------
+ 2A20 -------- ?? unknown
+ |
+ V
+ 2A2C -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 2A30
+ bits 0:7
+ osd colour to change in indexed palette
+ ---------------
+ 2A34
+ bits 0:31
+ osd colour for indexed palette
+
+ To set the new palette, first load the index of the colour to change into
+ 2A30, then load the new colour into 2A34. The full palette is 256 colours,
+ so the index range is 0x00-0xFF
+ --------------------------------------------------------------------------------
+ 2A38 -------- ?? unknown
+ 2A3C -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 2A40
+ bits 0:31
+ osd ?? unknown
+
+ Affects overall brightness, wrapping around to black
+ --------------------------------------------------------------------------------
+ 2A44
+ bits 0:31
+ osd ?? unknown
+
+ Green tint
+ --------------------------------------------------------------------------------
+ 2A48
+ bits 0:31
+ osd ?? unknown
+
+ Red tint
+ --------------------------------------------------------------------------------
+ 2A4C
+ bits 0:31
+ osd ?? unknown
+
+ Affects overall brightness, wrapping around to black
+ --------------------------------------------------------------------------------
+ 2A50
+ bits 0:31
+ osd ?? unknown
+
+ Colour shift
+ --------------------------------------------------------------------------------
+ 2A54
+ bits 0:31
+ osd ?? unknown
+
+ Colour shift
+ --------------------------------------------------------------------------------
+ 2A58 -------- ?? unknown
+ |
+ V
+ 2AFC -------- ?? unknown
+ --------------------------------------------------------------------------------
+ 2B00
+ bit 0
+ osd filter control
+ 0 = filter off
+ 1 = filter on
+
+ bits 1:4
+ osd ?? unknown
+
+ --------------------------------------------------------------------------------
+
+The cx231xx DMA engine
+----------------------
+
+
+This page describes the structures and procedures used by the cx2341x DMA
+engine.
+
+Introduction
+~~~~~~~~~~~~
+
+The cx2341x PCI interface is busmaster capable. This means it has a DMA
+engine to efficiently transfer large volumes of data between the card and main
+memory without requiring help from a CPU. Like most hardware, it must operate
+on contiguous physical memory. This is difficult to come by in large quantities
+on virtual memory machines.
+
+Therefore, it also supports a technique called "scatter-gather". The card can
+transfer multiple buffers in one operation. Instead of allocating one large
+contiguous buffer, the driver can allocate several smaller buffers.
+
+In practice, I've seen the average transfer to be roughly 80K, but transfers
+above 128K were not uncommon, particularly at startup. The 128K figure is
+important, because that is the largest block that the kernel can normally
+allocate. Even still, 128K blocks are hard to come by, so the driver writer is
+urged to choose a smaller block size and learn the scatter-gather technique.
+
+Mailbox #10 is reserved for DMA transfer information.
+
+Note: the hardware expects little-endian data ('intel format').
+
+Flow
+~~~~
+
+This section describes, in general, the order of events when handling DMA
+transfers. Detailed information follows this section.
+
+- The card raises the Encoder interrupt.
+- The driver reads the transfer type, offset and size from Mailbox #10.
+- The driver constructs the scatter-gather array from enough free dma buffers
+ to cover the size.
+- The driver schedules the DMA transfer via the ScheduleDMAtoHost API call.
+- The card raises the DMA Complete interrupt.
+- The driver checks the DMA status register for any errors.
+- The driver post-processes the newly transferred buffers.
+
+NOTE! It is possible that the Encoder and DMA Complete interrupts get raised
+simultaneously. (End of the last, start of the next, etc.)
+
+Mailbox #10
+~~~~~~~~~~~
+
+The Flags, Command, Return Value and Timeout fields are ignored.
+
+- Name: Mailbox #10
+- Results[0]: Type: 0: MPEG.
+- Results[1]: Offset: The position relative to the card's memory space.
+- Results[2]: Size: The exact number of bytes to transfer.
+
+My speculation is that since the StartCapture API has a capture type of "RAW"
+available, that the type field will have other values that correspond to YUV
+and PCM data.
+
+Scatter-Gather Array
+~~~~~~~~~~~~~~~~~~~~
+
+The scatter-gather array is a contiguously allocated block of memory that
+tells the card the source and destination of each data-block to transfer.
+Card "addresses" are derived from the offset supplied by Mailbox #10. Host
+addresses are the physical memory location of the target DMA buffer.
+
+Each S-G array element is a struct of three 32-bit words. The first word is
+the source address, the second is the destination address. Both take up the
+entire 32 bits. The lowest 18 bits of the third word is the transfer byte
+count. The high-bit of the third word is the "last" flag. The last-flag tells
+the card to raise the DMA_DONE interrupt. From hard personal experience, if
+you forget to set this bit, the card will still "work" but the stream will
+most likely get corrupted.
+
+The transfer count must be a multiple of 256. Therefore, the driver will need
+to track how much data in the target buffer is valid and deal with it
+accordingly.
+
+Array Element:
+
+- 32-bit Source Address
+- 32-bit Destination Address
+- 14-bit reserved (high bit is the last flag)
+- 18-bit byte count
+
+DMA Transfer Status
+~~~~~~~~~~~~~~~~~~~
+
+Register 0x0004 holds the DMA Transfer Status:
+
+- bit 0: read completed
+- bit 1: write completed
+- bit 2: DMA read error
+- bit 3: DMA write error
+- bit 4: Scatter-Gather array error
diff --git a/Documentation/driver-api/media/drivers/cx88-devel.rst b/Documentation/driver-api/media/drivers/cx88-devel.rst
new file mode 100644
index 0000000000..cfe7c03f49
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/cx88-devel.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/dvb-usb.rst b/Documentation/driver-api/media/drivers/dvb-usb.rst
new file mode 100644
index 0000000000..b2d5d9e62b
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/dvb-usb.rst
@@ -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.
diff --git a/Documentation/driver-api/media/drivers/fimc-devel.rst b/Documentation/driver-api/media/drivers/fimc-devel.rst
new file mode 100644
index 0000000000..4c6b7c8be1
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/fimc-devel.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/frontends.rst b/Documentation/driver-api/media/drivers/frontends.rst
new file mode 100644
index 0000000000..7b8336ece6
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/frontends.rst
@@ -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
+
diff --git a/Documentation/driver-api/media/drivers/index.rst b/Documentation/driver-api/media/drivers/index.rst
new file mode 100644
index 0000000000..c4123a16b5
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/index.rst
@@ -0,0 +1,40 @@
+.. 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
+
+
+Digital TV drivers
+==================
+
+.. toctree::
+ :maxdepth: 5
+
+ dvb-usb
+ frontends
+ vidtv
+ contributors
diff --git a/Documentation/driver-api/media/drivers/pvrusb2.rst b/Documentation/driver-api/media/drivers/pvrusb2.rst
new file mode 100644
index 0000000000..cbd9359c24
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/pvrusb2.rst
@@ -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).
diff --git a/Documentation/driver-api/media/drivers/pxa_camera.rst b/Documentation/driver-api/media/drivers/pxa_camera.rst
new file mode 100644
index 0000000000..46919919ba
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -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.
diff --git a/Documentation/driver-api/media/drivers/radiotrack.rst b/Documentation/driver-api/media/drivers/radiotrack.rst
new file mode 100644
index 0000000000..a85cb6205d
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/radiotrack.rst
@@ -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)
diff --git a/Documentation/driver-api/media/drivers/rkisp1.rst b/Documentation/driver-api/media/drivers/rkisp1.rst
new file mode 100644
index 0000000000..ea336958a3
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/rkisp1.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/saa7134-devel.rst b/Documentation/driver-api/media/drivers/saa7134-devel.rst
new file mode 100644
index 0000000000..167fd729bc
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/saa7134-devel.rst
@@ -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.
diff --git a/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst b/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst
new file mode 100644
index 0000000000..822fcb8368
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/sh_mobile_ceu_camera.rst
@@ -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)
diff --git a/Documentation/driver-api/media/drivers/tuners.rst b/Documentation/driver-api/media/drivers/tuners.rst
new file mode 100644
index 0000000000..d7924141c5
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/tuners.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst
new file mode 100644
index 0000000000..54f269f478
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/vidtv.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/vimc-devel.rst b/Documentation/driver-api/media/drivers/vimc-devel.rst
new file mode 100644
index 0000000000..9e984f914b
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/vimc-devel.rst
@@ -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
diff --git a/Documentation/driver-api/media/drivers/zoran.rst b/Documentation/driver-api/media/drivers/zoran.rst
new file mode 100644
index 0000000000..b205e10c31
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/zoran.rst
@@ -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 Argentinia, Uruguay, an 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.
diff --git a/Documentation/driver-api/media/dtv-ca.rst b/Documentation/driver-api/media/dtv-ca.rst
new file mode 100644
index 0000000000..8a09862b42
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-ca.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Conditional Access kABI
+----------------------------------
+
+.. kernel-doc:: include/media/dvb_ca_en50221.h
diff --git a/Documentation/driver-api/media/dtv-common.rst b/Documentation/driver-api/media/dtv-common.rst
new file mode 100644
index 0000000000..207a22bcaf
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-common.rst
@@ -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
diff --git a/Documentation/driver-api/media/dtv-core.rst b/Documentation/driver-api/media/dtv-core.rst
new file mode 100644
index 0000000000..82c5b85ed9
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-core.rst
@@ -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
diff --git a/Documentation/driver-api/media/dtv-demux.rst b/Documentation/driver-api/media/dtv-demux.rst
new file mode 100644
index 0000000000..1441241426
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-demux.rst
@@ -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
diff --git a/Documentation/driver-api/media/dtv-frontend.rst b/Documentation/driver-api/media/dtv-frontend.rst
new file mode 100644
index 0000000000..ea43cdb5b0
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-frontend.rst
@@ -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
diff --git a/Documentation/driver-api/media/dtv-net.rst b/Documentation/driver-api/media/dtv-net.rst
new file mode 100644
index 0000000000..deb6bffe96
--- /dev/null
+++ b/Documentation/driver-api/media/dtv-net.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Digital TV Network kABI
+-----------------------
+
+.. kernel-doc:: include/media/dvb_net.h
diff --git a/Documentation/driver-api/media/index.rst b/Documentation/driver-api/media/index.rst
new file mode 100644
index 0000000000..08e2065674
--- /dev/null
+++ b/Documentation/driver-api/media/index.rst
@@ -0,0 +1,59 @@
+.. 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.
+
+
+.. only:: html
+
+ .. class:: toc-title
+
+ Table of Contents
+
+.. toctree::
+ :maxdepth: 5
+ :numbered:
+
+ maintainer-entry-profile
+
+ 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.
diff --git a/Documentation/driver-api/media/maintainer-entry-profile.rst b/Documentation/driver-api/media/maintainer-entry-profile.rst
new file mode 100644
index 0000000000..ffc712a5f6
--- /dev/null
+++ b/Documentation/driver-api/media/maintainer-entry-profile.rst
@@ -0,0 +1,206 @@
+Media Subsystem Profile
+=======================
+
+Overview
+--------
+
+The media subsystem covers support for a variety of devices: stream
+capture, analog and digital TV streams, cameras, remote controllers, HDMI CEC
+and media pipeline control.
+
+It covers, mainly, the contents of those directories:
+
+ - drivers/media
+ - drivers/staging/media
+ - Documentation/admin-guide/media
+ - Documentation/driver-api/media
+ - Documentation/userspace-api/media
+ - Documentation/devicetree/bindings/media/\ [1]_
+ - include/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 via 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 files.
+
+Due to the size and wide scope of the media subsystem, media's
+maintainership model is to have sub-maintainers that have a broad
+knowledge of a specific aspect of the subsystem. It is the sub-maintainers'
+task to review the patches, providing feedback to users if the patches are
+following the subsystem rules and are properly using the media kernel and
+userspace APIs.
+
+Patches for the media subsystem must be sent to the media mailing list
+at linux-media@vger.kernel.org as plain text only e-mail. Emails with
+HTML will be automatically rejected by the mail server. It could be wise
+to also copy the sub-maintainer(s).
+
+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 a few minutes, then
+probably something went wrong on your submission. Please check if the
+email is in plain text\ [2]_ only and if your emailer is not mangling
+whitespaces before complaining or submitting them again.
+
+You can check if the mailing list server accepted your patch, by looking at:
+
+ - https://lore.kernel.org/linux-media/
+
+.. [2] If your email contains HTML, the mailing list server will simply
+ drop it, without any further notice.
+
+
+Media maintainers
++++++++++++++++++
+
+At the media subsystem, we have a group of senior developers that
+are responsible for doing the code reviews at the drivers (also known as
+sub-maintainers), and another senior developer responsible for the
+subsystem as a whole. For core changes, whenever possible, multiple
+media maintainers do the review.
+
+The media maintainers that work on specific areas of the subsystem are:
+
+- Remote Controllers (infrared):
+ Sean Young <sean@mess.org>
+
+- HDMI CEC:
+ Hans Verkuil <hverkuil@xs4all.nl>
+
+- Media controller drivers:
+ Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+- ISP, v4l2-async, v4l2-fwnode, v4l2-flash-led-class and Sensor drivers:
+ Sakari Ailus <sakari.ailus@linux.intel.com>
+
+- V4L2 drivers and core V4L2 frameworks:
+ Hans Verkuil <hverkuil@xs4all.nl>
+
+The subsystem maintainer is:
+ Mauro Carvalho Chehab <mchehab@kernel.org>
+
+Media maintainers may delegate a patch to other media maintainers as needed.
+On such case, checkpatch's ``delegate`` field indicates who's currently
+responsible for reviewing a patch.
+
+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 Tool
+==================== =======================================================
+V4L2 drivers\ [3]_ ``v4l2-compliance``
+V4L2 virtual drivers ``contrib/test/test-media``
+CEC drivers ``cec-compliance``
+==================== =======================================================
+
+.. [3] The ``v4l2-compliance`` also covers the media controller usage inside
+ V4L2 drivers.
+
+Other compilance tools are under development to check other parts of the
+subsystem.
+
+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.
+
+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 need to have a big identifier name,
+ which keeps hard to honor the 80 columns limit;
+ - on arithmetic expressions, when breaking lines makes them harder to
+ read;
+ - when they avoid a line to end with an open parenthesis or an open
+ bracket.
+
+Key Cycle Dates
+---------------
+
+New submissions can be sent at any time, but if they intend 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 is at https://patchwork.linuxtv.org, it should
+be sooner or later handled, so you don't need to re-submit a patch.
+
+Except for 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 at the test and what it was tested.
diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst
new file mode 100644
index 0000000000..2456950ce8
--- /dev/null
+++ b/Documentation/driver-api/media/mc-core.rst
@@ -0,0 +1,326 @@
+.. 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 iterate over entities in a graph.
+
+To iterate over all entities belonging to a media device, drivers can use
+the media_device_for_each_entity macro, defined in
+``include/media/media-device.h``.
+
+.. code-block:: c
+
+ struct media_entity *entity;
+
+ media_device_for_each_entity(entity, mdev) {
+ // entity will point to each entity in turn
+ ...
+ }
+
+Drivers might also need to iterate over all entities in a graph that can be
+reached only through enabled links starting at a given entity. The media
+framework provides a depth-first graph traversal API for that purpose.
+
+.. note::
+
+ Graphs with cycles (whether directed or undirected) are **NOT**
+ supported by the graph traversal API. To prevent infinite loops, the graph
+ traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
+ currently defined as 16.
+
+Drivers initiate a graph traversal by calling
+:c:func:`media_graph_walk_start()`
+
+The graph structure, provided by the caller, is initialized to start graph
+traversal at the given entity.
+
+Drivers can then retrieve the next entity by calling
+:c:func:`media_graph_walk_next()`
+
+When the graph traversal is complete the function will return ``NULL``.
+
+Graph traversal can be interrupted at any moment. No cleanup function call
+is required and the graph structure can be freed normally.
+
+Helper functions can be used to find a link between two given pads, or a pad
+connected to another pad through an enabled link
+(:c:func:`media_entity_find_link()`, :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.
+
+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
diff --git a/Documentation/driver-api/media/rc-core.rst b/Documentation/driver-api/media/rc-core.rst
new file mode 100644
index 0000000000..53f5e643b6
--- /dev/null
+++ b/Documentation/driver-api/media/rc-core.rst
@@ -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
diff --git a/Documentation/driver-api/media/tx-rx.rst b/Documentation/driver-api/media/tx-rx.rst
new file mode 100644
index 0000000000..e1e9258dd8
--- /dev/null
+++ b/Documentation/driver-api/media/tx-rx.rst
@@ -0,0 +1,133 @@
+.. 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 or a CSI-2
+receiver in an SoC.
+
+Bus types
+---------
+
+The following busses 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
+^^^^^^^^
+
+`BT.601`_ and `BT.656`_ are the most common parallel busses.
+
+.. _`BT.601`: https://en.wikipedia.org/wiki/Rec._601
+.. _`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 busses.
+
+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).
+
+``.s_stream()`` callback
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The struct struct v4l2_subdev_video_ops->s_stream() callback is used by the
+receiver driver to control the transmitter driver's streaming state.
+
+
+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 ``V4L2_CID_LINK_FREQ`` integer64 menu item.
+ * - nr_of_lanes
+ - Number of data lanes used on the CSI-2 link. This can
+ be obtained from the OF endpoint configuration.
+ * - 2
+ - 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
+
+.. 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 modes
+^^^^^^^^^^^^^^^^^^^^^^
+
+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 mode, 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 mode. 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 mode setup are waived
+from calling the two callbacks.
+
+Stopping the transmitter
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A transmitter stops sending the stream of images as a result of
+calling the ``.s_stream()`` callback. Some transmitters may stop the
+stream at a frame boundary whereas others stop immediately,
+effectively leaving the current frame unfinished. The receiver driver
+should not make assumptions either way, but function properly in both
+cases.
diff --git a/Documentation/driver-api/media/v4l2-async.rst b/Documentation/driver-api/media/v4l2-async.rst
new file mode 100644
index 0000000000..3422330b3b
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-async.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 async kAPI
+^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/driver-api/media/v4l2-cci.rst b/Documentation/driver-api/media/v4l2-cci.rst
new file mode 100644
index 0000000000..dd297a40ed
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-cci.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 CCI kAPI
+^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-cci.h
diff --git a/Documentation/driver-api/media/v4l2-common.rst b/Documentation/driver-api/media/v4l2-common.rst
new file mode 100644
index 0000000000..b1e70eb56a
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-common.rst
@@ -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
diff --git a/Documentation/driver-api/media/v4l2-controls.rst b/Documentation/driver-api/media/v4l2-controls.rst
new file mode 100644
index 0000000000..b2e9180482
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-controls.rst
@@ -0,0 +1,823 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Controls
+=============
+
+Introduction
+------------
+
+The V4L2 control API seems simple enough, but quickly becomes very hard to
+implement correctly in drivers. But much of the code needed to handle controls
+is actually not driver specific and can be moved to the V4L core framework.
+
+After all, the only part that a driver developer is interested in is:
+
+1) How do I add a control?
+2) How do I set the control's value? (i.e. s_ctrl)
+
+And occasionally:
+
+3) How do I get the control's value? (i.e. g_volatile_ctrl)
+4) How do I validate the user's proposed control value? (i.e. try_ctrl)
+
+All the rest is something that can be done centrally.
+
+The control framework was created in order to implement all the rules of the
+V4L2 specification with respect to controls in a central place. And to make
+life as easy as possible for the driver developer.
+
+Note that the control framework relies on the presence of a struct
+:c:type:`v4l2_device` for V4L2 drivers and struct v4l2_subdev for
+sub-device drivers.
+
+
+Objects in the framework
+------------------------
+
+There are two main objects:
+
+The :c:type:`v4l2_ctrl` object describes the control properties and keeps
+track of the control's value (both the current value and the proposed new
+value).
+
+:c:type:`v4l2_ctrl_handler` is the object that keeps track of controls. It
+maintains a list of v4l2_ctrl objects that it owns and another list of
+references to controls, possibly to controls owned by other handlers.
+
+
+Basic usage for V4L2 and sub-device drivers
+-------------------------------------------
+
+1) Prepare the driver:
+
+.. code-block:: c
+
+ #include <media/v4l2-ctrls.h>
+
+1.1) Add the handler to your driver's top-level struct:
+
+For V4L2 drivers:
+
+.. code-block:: c
+
+ struct foo_dev {
+ ...
+ struct v4l2_device v4l2_dev;
+ ...
+ struct v4l2_ctrl_handler ctrl_handler;
+ ...
+ };
+
+For sub-device drivers:
+
+.. code-block:: c
+
+ struct foo_dev {
+ ...
+ struct v4l2_subdev sd;
+ ...
+ struct v4l2_ctrl_handler ctrl_handler;
+ ...
+ };
+
+1.2) Initialize the handler:
+
+.. code-block:: c
+
+ v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
+
+The second argument is a hint telling the function how many controls this
+handler is expected to handle. It will allocate a hashtable based on this
+information. It is a hint only.
+
+1.3) Hook the control handler into the driver:
+
+For V4L2 drivers:
+
+.. code-block:: c
+
+ foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
+
+For sub-device drivers:
+
+.. code-block:: c
+
+ foo->sd.ctrl_handler = &foo->ctrl_handler;
+
+1.4) Clean up the handler at the end:
+
+.. code-block:: c
+
+ v4l2_ctrl_handler_free(&foo->ctrl_handler);
+
+
+2) Add controls:
+
+You add non-menu controls by calling :c:func:`v4l2_ctrl_new_std`:
+
+.. code-block:: c
+
+ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s32 min, s32 max, u32 step, s32 def);
+
+Menu and integer menu controls are added by calling
+:c:func:`v4l2_ctrl_new_std_menu`:
+
+.. code-block:: c
+
+ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s32 max, s32 skip_mask, s32 def);
+
+Menu controls with a driver specific menu are added by calling
+:c:func:`v4l2_ctrl_new_std_menu_items`:
+
+.. code-block:: c
+
+ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
+ struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops, u32 id, s32 max,
+ s32 skip_mask, s32 def, const char * const *qmenu);
+
+Standard compound controls can be added by calling
+:c:func:`v4l2_ctrl_new_std_compound`:
+
+.. code-block:: c
+
+ struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops, u32 id,
+ const union v4l2_ctrl_ptr p_def);
+
+Integer menu controls with a driver specific menu can be added by calling
+:c:func:`v4l2_ctrl_new_int_menu`:
+
+.. code-block:: c
+
+ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s32 max, s32 def, const s64 *qmenu_int);
+
+These functions are typically called right after the
+:c:func:`v4l2_ctrl_handler_init`:
+
+.. code-block:: c
+
+ static const s64 exp_bias_qmenu[] = {
+ -2, -1, 0, 1, 2
+ };
+ static const char * const test_pattern[] = {
+ "Disabled",
+ "Vertical Bars",
+ "Solid Black",
+ "Solid White",
+ };
+
+ v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
+ v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+ v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_CONTRAST, 0, 255, 1, 128);
+ v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_POWER_LINE_FREQUENCY,
+ V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
+ V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
+ v4l2_ctrl_new_int_menu(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_EXPOSURE_BIAS,
+ ARRAY_SIZE(exp_bias_qmenu) - 1,
+ ARRAY_SIZE(exp_bias_qmenu) / 2 - 1,
+ exp_bias_qmenu);
+ v4l2_ctrl_new_std_menu_items(&foo->ctrl_handler, &foo_ctrl_ops,
+ V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern) - 1, 0,
+ 0, test_pattern);
+ ...
+ if (foo->ctrl_handler.error) {
+ int err = foo->ctrl_handler.error;
+
+ v4l2_ctrl_handler_free(&foo->ctrl_handler);
+ return err;
+ }
+
+The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
+the new control, but if you do not need to access the pointer outside the
+control ops, then there is no need to store it.
+
+The :c:func:`v4l2_ctrl_new_std` function will fill in most fields based on
+the control ID except for the min, max, step and default values. These are
+passed in the last four arguments. These values are driver specific while
+control attributes like type, name, flags are all global. The control's
+current value will be set to the default value.
+
+The :c:func:`v4l2_ctrl_new_std_menu` function is very similar but it is
+used for menu controls. There is no min argument since that is always 0 for
+menu controls, and instead of a step there is a skip_mask argument: if bit
+X is 1, then menu item X is skipped.
+
+The :c:func:`v4l2_ctrl_new_int_menu` function creates a new standard
+integer menu control with driver-specific items in the menu. It differs
+from v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and
+takes as the last argument an array of signed 64-bit integers that form an
+exact menu item list.
+
+The :c:func:`v4l2_ctrl_new_std_menu_items` function is very similar to
+v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the
+driver specific menu for an otherwise standard menu control. A good example
+for this control is the test pattern control for capture/display/sensors
+devices that have the capability to generate test patterns. These test
+patterns are hardware specific, so the contents of the menu will vary from
+device to device.
+
+Note that if something fails, the function will return NULL or an error and
+set ctrl_handler->error to the error code. If ctrl_handler->error was already
+set, then it will just return and do nothing. This is also true for
+v4l2_ctrl_handler_init if it cannot allocate the internal data structure.
+
+This makes it easy to init the handler and just add all controls and only check
+the error code at the end. Saves a lot of repetitive error checking.
+
+It is recommended to add controls in ascending control ID order: it will be
+a bit faster that way.
+
+3) Optionally force initial control setup:
+
+.. code-block:: c
+
+ v4l2_ctrl_handler_setup(&foo->ctrl_handler);
+
+This will call s_ctrl for all controls unconditionally. Effectively this
+initializes the hardware to the default control values. It is recommended
+that you do this as this ensures that both the internal data structures and
+the hardware are in sync.
+
+4) Finally: implement the :c:type:`v4l2_ctrl_ops`
+
+.. code-block:: c
+
+ static const struct v4l2_ctrl_ops foo_ctrl_ops = {
+ .s_ctrl = foo_s_ctrl,
+ };
+
+Usually all you need is s_ctrl:
+
+.. code-block:: c
+
+ static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ write_reg(0x123, ctrl->val);
+ break;
+ case V4L2_CID_CONTRAST:
+ write_reg(0x456, ctrl->val);
+ break;
+ }
+ return 0;
+ }
+
+The control ops are called with the v4l2_ctrl pointer as argument.
+The new control value has already been validated, so all you need to do is
+to actually update the hardware registers.
+
+You're done! And this is sufficient for most of the drivers we have. No need
+to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL
+and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported.
+
+
+.. note::
+
+ The remainder sections deal with more advanced controls topics and scenarios.
+ In practice the basic usage as described above is sufficient for most drivers.
+
+
+Inheriting Sub-device Controls
+------------------------------
+
+When a sub-device is registered with a V4L2 driver by calling
+v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev
+and v4l2_device are set, then the controls of the subdev will become
+automatically available in the V4L2 driver as well. If the subdev driver
+contains controls that already exist in the V4L2 driver, then those will be
+skipped (so a V4L2 driver can always override a subdev control).
+
+What happens here is that v4l2_device_register_subdev() calls
+v4l2_ctrl_add_handler() adding the controls of the subdev to the controls
+of v4l2_device.
+
+
+Accessing Control Values
+------------------------
+
+The following union is used inside the control framework to access control
+values:
+
+.. code-block:: c
+
+ union v4l2_ctrl_ptr {
+ s32 *p_s32;
+ s64 *p_s64;
+ char *p_char;
+ void *p;
+ };
+
+The v4l2_ctrl struct contains these fields that can be used to access both
+current and new values:
+
+.. code-block:: c
+
+ s32 val;
+ struct {
+ s32 val;
+ } cur;
+
+
+ union v4l2_ctrl_ptr p_new;
+ union v4l2_ctrl_ptr p_cur;
+
+If the control has a simple s32 type, 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
diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst
new file mode 100644
index 0000000000..239045ecc8
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-core.rst
@@ -0,0 +1,29 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Video4Linux devices
+-------------------
+
+.. toctree::
+ :maxdepth: 1
+
+ v4l2-intro
+ v4l2-dev
+ v4l2-device
+ v4l2-fh
+ v4l2-subdev
+ v4l2-event
+ v4l2-controls
+ v4l2-videobuf
+ v4l2-videobuf2
+ v4l2-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
diff --git a/Documentation/driver-api/media/v4l2-dev.rst b/Documentation/driver-api/media/v4l2-dev.rst
new file mode 100644
index 0000000000..99e3b5fa74
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-dev.rst
@@ -0,0 +1,375 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Video device' s internal representation
+=======================================
+
+The actual device nodes in the ``/dev`` directory are created using the
+:c:type:`video_device` struct (``v4l2-dev.h``). This struct can either be
+allocated dynamically or embedded in a larger struct.
+
+To allocate it dynamically use :c:func:`video_device_alloc`:
+
+.. code-block:: c
+
+ struct video_device *vdev = video_device_alloc();
+
+ if (vdev == NULL)
+ return -ENOMEM;
+
+ vdev->release = video_device_release;
+
+If you embed it in a larger struct, then you must set the ``release()``
+callback to your own function:
+
+.. code-block:: c
+
+ struct video_device *vdev = &my_vdev->vdev;
+
+ vdev->release = my_vdev_release;
+
+The ``release()`` callback must be set and it is called when the last user
+of the video device exits.
+
+The default :c:func:`video_device_release` callback currently
+just calls ``kfree`` to free the allocated memory.
+
+There is also a :c:func:`video_device_release_empty` function that does
+nothing (is empty) and should be used if the struct is embedded and there
+is nothing to do when it is released.
+
+You should also set these fields of :c:type:`video_device`:
+
+- :c:type:`video_device`->v4l2_dev: must be set to the :c:type:`v4l2_device`
+ parent device.
+
+- :c:type:`video_device`->name: set to something descriptive and unique.
+
+- :c:type:`video_device`->vfl_dir: set this to ``VFL_DIR_RX`` for capture
+ devices (``VFL_DIR_RX`` has value 0, so this is normally already the
+ default), set to ``VFL_DIR_TX`` for output devices and ``VFL_DIR_M2M`` for mem2mem (codec) devices.
+
+- :c:type:`video_device`->fops: set to the :c:type:`v4l2_file_operations`
+ struct.
+
+- :c:type:`video_device`->ioctl_ops: if you use the :c:type:`v4l2_ioctl_ops`
+ to simplify ioctl maintenance (highly recommended to use this and it might
+ become compulsory in the future!), then set this to your
+ :c:type:`v4l2_ioctl_ops` struct. The :c:type:`video_device`->vfl_type and
+ :c:type:`video_device`->vfl_dir fields are used to disable ops that do not
+ match the type/dir combination. E.g. VBI ops are disabled for non-VBI nodes,
+ and output ops are disabled for a capture device. This makes it possible to
+ provide just one :c:type:`v4l2_ioctl_ops` struct for both vbi and
+ video nodes.
+
+- :c:type:`video_device`->lock: leave to ``NULL`` if you want to do all the
+ locking in the driver. Otherwise you give it a pointer to a struct
+ ``mutex_lock`` and before the :c:type:`video_device`->unlocked_ioctl
+ file operation is called this lock will be taken by the core and released
+ afterwards. See the next section for more details.
+
+- :c:type:`video_device`->queue: a pointer to the struct 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``.
+
+If you use the old :ref:`videobuf framework <vb_framework>` then you must
+pass the :c:type:`video_device`->lock to the videobuf queue initialize
+function: if videobuf has to wait for a frame to arrive, then it will
+temporarily unlock the lock and relock it afterwards. If your driver also
+waits in the code, then you should do the same to allow other
+processes to access the device node while the first process is waiting for
+something.
+
+In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the
+``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable.
+If you use the ``queue->lock`` pointer, then you can use the helper functions
+:c:func:`vb2_ops_wait_prepare` and :c:func:`vb2_ops_wait_finish`.
+
+The implementation of a hotplug disconnect should also take the lock from
+:c:type:`video_device` before calling v4l2_device_disconnect. If you are also
+using :c:type:`video_device`->queue->lock, then you have to first lock
+:c:type:`video_device`->queue->lock followed by :c:type:`video_device`->lock.
+That way you can be sure no ioctl is running when you call
+:c:func:`v4l2_device_disconnect`.
+
+Video device registration
+-------------------------
+
+Next you register the video device with :c:func:`video_register_device`.
+This will create the character device for you.
+
+.. code-block:: c
+
+ err = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (err) {
+ video_device_release(vdev); /* or kfree(my_vdev); */
+ return err;
+ }
+
+If the :c:type:`v4l2_device` parent device has a not ``NULL`` mdev field,
+the video device entity will be automatically registered with the media
+device.
+
+Which device is registered depends on the type argument. The following
+types exist:
+
+========================== ==================== ==============================
+:c:type:`vfl_devnode_type` Device name Usage
+========================== ==================== ==============================
+``VFL_TYPE_VIDEO`` ``/dev/videoX`` for video input/output devices
+``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e.
+ closed captions, teletext)
+``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners
+``VFL_TYPE_SUBDEV`` ``/dev/v4l-subdevX`` for V4L2 subdevices
+``VFL_TYPE_SDR`` ``/dev/swradioX`` for Software Defined Radio
+ (SDR) tuners
+``VFL_TYPE_TOUCH`` ``/dev/v4l-touchX`` for touch sensors
+========================== ==================== ==============================
+
+The last argument gives you a certain amount of control over the device
+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
diff --git a/Documentation/driver-api/media/v4l2-device.rst b/Documentation/driver-api/media/v4l2-device.rst
new file mode 100644
index 0000000000..7bd9c45f55
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-device.rst
@@ -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
diff --git a/Documentation/driver-api/media/v4l2-dv-timings.rst b/Documentation/driver-api/media/v4l2-dv-timings.rst
new file mode 100644
index 0000000000..b178f93151
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-dv-timings.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 DV Timings functions
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-dv-timings.h
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst
new file mode 100644
index 0000000000..52d4fbc5d8
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-event.rst
@@ -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
+
diff --git a/Documentation/driver-api/media/v4l2-fh.rst b/Documentation/driver-api/media/v4l2-fh.rst
new file mode 100644
index 0000000000..3eeaa8da0c
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-fh.rst
@@ -0,0 +1,141 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 File handlers
+------------------
+
+struct v4l2_fh provides a way to easily keep file handle specific
+data that is used by the V4L2 framework.
+
+.. attention::
+ New drivers must use struct v4l2_fh
+ since it is also used to implement priority handling
+ (:ref:`VIDIOC_G_PRIORITY`).
+
+The users of :c:type:`v4l2_fh` (in the V4L2 framework, not the driver) know
+whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
+by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
+This bit is set whenever :c:func:`v4l2_fh_init` is called.
+
+struct v4l2_fh is allocated as a part of the driver's own file handle
+structure and ``file->private_data`` is set to it in the driver's ``open()``
+function by the driver.
+
+In many cases the struct v4l2_fh will be embedded in a larger
+structure. In that case you should call:
+
+#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
+#) :c:func:`v4l2_fh_del` and :c:func:`v4l2_fh_exit` in ``release()``
+
+Drivers can extract their own file handle structure by using the container_of
+macro.
+
+Example:
+
+.. code-block:: c
+
+ struct my_fh {
+ int blah;
+ struct v4l2_fh fh;
+ };
+
+ ...
+
+ int my_open(struct file *file)
+ {
+ struct my_fh *my_fh;
+ struct video_device *vfd;
+ int ret;
+
+ ...
+
+ my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+
+ ...
+
+ v4l2_fh_init(&my_fh->fh, vfd);
+
+ ...
+
+ file->private_data = &my_fh->fh;
+ v4l2_fh_add(&my_fh->fh);
+ return 0;
+ }
+
+ int my_release(struct file *file)
+ {
+ struct v4l2_fh *fh = file->private_data;
+ struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
+
+ ...
+ v4l2_fh_del(&my_fh->fh);
+ v4l2_fh_exit(&my_fh->fh);
+ kfree(my_fh);
+ return 0;
+ }
+
+Below is a short description of the :c:type:`v4l2_fh` functions used:
+
+:c:func:`v4l2_fh_init <v4l2_fh_init>`
+(:c:type:`fh <v4l2_fh>`, :c:type:`vdev <video_device>`)
+
+
+- Initialise the file handle. This **MUST** be performed in the driver's
+ :c:type:`v4l2_file_operations`->open() handler.
+
+
+:c:func:`v4l2_fh_add <v4l2_fh_add>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Add a :c:type:`v4l2_fh` to :c:type:`video_device` file handle list.
+ Must be called once the file handle is completely initialized.
+
+:c:func:`v4l2_fh_del <v4l2_fh_del>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Unassociate the file handle from :c:type:`video_device`. The file handle
+ exit function may now be called.
+
+:c:func:`v4l2_fh_exit <v4l2_fh_exit>`
+(:c:type:`fh <v4l2_fh>`)
+
+- Uninitialise the file handle. After uninitialisation the :c:type:`v4l2_fh`
+ memory can be freed.
+
+
+If struct 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
diff --git a/Documentation/driver-api/media/v4l2-flash-led-class.rst b/Documentation/driver-api/media/v4l2-flash-led-class.rst
new file mode 100644
index 0000000000..2aa6bed9b8
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-flash-led-class.rst
@@ -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
diff --git a/Documentation/driver-api/media/v4l2-fwnode.rst b/Documentation/driver-api/media/v4l2-fwnode.rst
new file mode 100644
index 0000000000..e313b6cddc
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-fwnode.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 fwnode kAPI
+^^^^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-fwnode.h
diff --git a/Documentation/driver-api/media/v4l2-intro.rst b/Documentation/driver-api/media/v4l2-intro.rst
new file mode 100644
index 0000000000..4d54fa9d7a
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-intro.rst
@@ -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.
diff --git a/Documentation/driver-api/media/v4l2-mc.rst b/Documentation/driver-api/media/v4l2-mc.rst
new file mode 100644
index 0000000000..0c352ac588
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mc.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Media Controller functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-mc.h
diff --git a/Documentation/driver-api/media/v4l2-mediabus.rst b/Documentation/driver-api/media/v4l2-mediabus.rst
new file mode 100644
index 0000000000..1f2254cba9
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mediabus.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 Media Bus functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-mediabus.h
diff --git a/Documentation/driver-api/media/v4l2-mem2mem.rst b/Documentation/driver-api/media/v4l2-mem2mem.rst
new file mode 100644
index 0000000000..a43b31cc82
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-mem2mem.rst
@@ -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
diff --git a/Documentation/driver-api/media/v4l2-rect.rst b/Documentation/driver-api/media/v4l2-rect.rst
new file mode 100644
index 0000000000..fc315cd841
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-rect.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 rect helper functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/v4l2-rect.h
diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
new file mode 100644
index 0000000000..e56b50b3f2
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -0,0 +1,637 @@
+.. 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``.
+
+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.
+
+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 andthe
+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 an array of
+struct v4l2_subdev_pad_config, 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
diff --git a/Documentation/driver-api/media/v4l2-tuner.rst b/Documentation/driver-api/media/v4l2-tuner.rst
new file mode 100644
index 0000000000..e6caa33215
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-tuner.rst
@@ -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
diff --git a/Documentation/driver-api/media/v4l2-tveeprom.rst b/Documentation/driver-api/media/v4l2-tveeprom.rst
new file mode 100644
index 0000000000..43fb391eda
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-tveeprom.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Hauppauge TV EEPROM functions and data structures
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/tveeprom.h
diff --git a/Documentation/driver-api/media/v4l2-videobuf.rst b/Documentation/driver-api/media/v4l2-videobuf.rst
new file mode 100644
index 0000000000..4b1d84eefe
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-videobuf.rst
@@ -0,0 +1,403 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _vb_framework:
+
+Videobuf Framework
+==================
+
+Author: Jonathan Corbet <corbet@lwn.net>
+
+Current as of 2.6.33
+
+.. note::
+
+ The videobuf framework was deprecated in favor of videobuf2. Shouldn't
+ be used on new drivers.
+
+Introduction
+------------
+
+The videobuf layer functions as a sort of glue layer between a V4L2 driver
+and user space. It handles the allocation and management of buffers for
+the storage of video frames. There is a set of functions which can be used
+to implement many of the standard POSIX I/O system calls, including read(),
+poll(), and, happily, mmap(). Another set of functions can be used to
+implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
+including buffer allocation, queueing and dequeueing, and streaming
+control. Using videobuf imposes a few design decisions on the driver
+author, but the payback comes in the form of reduced code in the driver and
+a consistent implementation of the V4L2 user-space API.
+
+Buffer types
+------------
+
+Not all video devices use the same kind of buffers. In fact, there are (at
+least) three common variations:
+
+ - Buffers which are scattered in both the physical and (kernel) virtual
+ address spaces. (Almost) all user-space buffers are like this, but it
+ makes great sense to allocate kernel-space buffers this way as well when
+ it is possible. Unfortunately, it is not always possible; working with
+ this kind of buffer normally requires hardware which can do
+ scatter/gather DMA operations.
+
+ - Buffers which are physically scattered, but which are virtually
+ contiguous; buffers allocated with vmalloc(), in other words. These
+ buffers are just as hard to use for DMA operations, but they can be
+ useful in situations where DMA is not available but virtually-contiguous
+ buffers are convenient.
+
+ - Buffers which are physically contiguous. Allocation of this kind of
+ buffer can be unreliable on fragmented systems, but simpler DMA
+ controllers cannot deal with anything else.
+
+Videobuf can work with all three types of buffers, but the driver author
+must pick one at the outset and design the driver around that decision.
+
+[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
+which are located within the system's video memory. The overlay
+functionality is considered to be deprecated for most use, but it still
+shows up occasionally in system-on-chip drivers where the performance
+benefits merit the use of this technique. Overlay buffers can be handled
+as a form of scattered buffer, but there are very few implementations in
+the kernel and a description of this technique is currently beyond the
+scope of this document.]
+
+Data structures, callbacks, and initialization
+----------------------------------------------
+
+Depending on which type of buffers are being used, the driver should
+include one of the following files:
+
+.. code-block:: none
+
+ <media/videobuf-dma-sg.h> /* Physically scattered */
+ <media/videobuf-vmalloc.h> /* vmalloc() buffers */
+ <media/videobuf-dma-contig.h> /* Physically contiguous */
+
+The driver's data structure describing a V4L2 device should include a
+struct videobuf_queue instance for the management of the buffer queue,
+along with a list_head for the queue of available buffers. There will also
+need to be an interrupt-safe spinlock which is used to protect (at least)
+the queue.
+
+The next step is to write four simple callbacks to help videobuf deal with
+the management of buffers:
+
+.. code-block:: none
+
+ struct videobuf_queue_ops {
+ int (*buf_setup)(struct videobuf_queue *q,
+ unsigned int *count, unsigned int *size);
+ int (*buf_prepare)(struct videobuf_queue *q,
+ struct videobuf_buffer *vb,
+ enum v4l2_field field);
+ void (*buf_queue)(struct videobuf_queue *q,
+ struct videobuf_buffer *vb);
+ void (*buf_release)(struct videobuf_queue *q,
+ struct videobuf_buffer *vb);
+ };
+
+buf_setup() is called early in the I/O process, when streaming is being
+initiated; its purpose is to tell videobuf about the I/O stream. The count
+parameter will be a suggested number of buffers to use; the driver should
+check it for rationality and adjust it if need be. As a practical rule, a
+minimum of two buffers are needed for proper streaming, and there is
+usually a maximum (which cannot exceed 32) which makes sense for each
+device. The size parameter should be set to the expected (maximum) size
+for each frame of data.
+
+Each buffer (in the form of a struct videobuf_buffer pointer) will be
+passed to buf_prepare(), which should set the buffer's size, width, height,
+and field fields properly. If the buffer's state field is
+VIDEOBUF_NEEDS_INIT, the driver should pass it to:
+
+.. code-block:: none
+
+ int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
+ struct v4l2_framebuffer *fbuf);
+
+Among other things, this call will usually allocate memory for the buffer.
+Finally, the buf_prepare() function should set the buffer's state to
+VIDEOBUF_PREPARED.
+
+When a buffer is queued for I/O, it is passed to buf_queue(), which should
+put it onto the driver's list of available buffers and set its state to
+VIDEOBUF_QUEUED. Note that this function is called with the queue spinlock
+held; if it tries to acquire it as well things will come to a screeching
+halt. Yes, this is the voice of experience. Note also that videobuf may
+wait on the first buffer in the queue; placing other buffers in front of it
+could again gum up the works. So use list_add_tail() to enqueue buffers.
+
+Finally, buf_release() is called when a buffer is no longer intended to be
+used. The driver should ensure that there is no I/O active on the buffer,
+then pass it to the appropriate free routine(s):
+
+.. code-block:: none
+
+ /* Scatter/gather drivers */
+ int videobuf_dma_unmap(struct videobuf_queue *q,
+ struct videobuf_dmabuf *dma);
+ int videobuf_dma_free(struct videobuf_dmabuf *dma);
+
+ /* vmalloc drivers */
+ void videobuf_vmalloc_free (struct videobuf_buffer *buf);
+
+ /* Contiguous drivers */
+ void videobuf_dma_contig_free(struct videobuf_queue *q,
+ struct videobuf_buffer *buf);
+
+One way to ensure that a buffer is no longer under I/O is to pass it to:
+
+.. code-block:: none
+
+ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
+
+Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
+should be used (it should be zero in the buf_release() case), and intr
+controls whether an interruptible wait is used.
+
+File operations
+---------------
+
+At this point, much of the work is done; much of the rest is slipping
+videobuf calls into the implementation of the other driver callbacks. The
+first step is in the open() function, which must initialize the
+videobuf queue. The function to use depends on the type of buffer used:
+
+.. code-block:: none
+
+ void videobuf_queue_sg_init(struct videobuf_queue *q,
+ struct videobuf_queue_ops *ops,
+ struct device *dev,
+ spinlock_t *irqlock,
+ enum v4l2_buf_type type,
+ enum v4l2_field field,
+ unsigned int msize,
+ void *priv);
+
+ void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
+ struct videobuf_queue_ops *ops,
+ struct device *dev,
+ spinlock_t *irqlock,
+ enum v4l2_buf_type type,
+ enum v4l2_field field,
+ unsigned int msize,
+ void *priv);
+
+ void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
+ struct videobuf_queue_ops *ops,
+ struct device *dev,
+ spinlock_t *irqlock,
+ enum v4l2_buf_type type,
+ enum v4l2_field field,
+ unsigned int msize,
+ void *priv);
+
+In each case, the parameters are the same: q is the queue structure for the
+device, ops is the set of callbacks as described above, dev is the device
+structure for this video device, irqlock is an interrupt-safe spinlock to
+protect access to the data structures, type is the buffer type used by the
+device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
+describes which field is being captured (often V4L2_FIELD_NONE for
+progressive devices), msize is the size of any containing structure used
+around struct videobuf_buffer, and priv is a private data pointer which
+shows up in the priv_data field of struct videobuf_queue. Note that these
+are void functions which, evidently, are immune to failure.
+
+V4L2 capture drivers can be written to support either of two APIs: the
+read() system call and the rather more complicated streaming mechanism. As
+a general rule, it is necessary to support both to ensure that all
+applications have a chance of working with the device. Videobuf makes it
+easy to do that with the same code. To implement read(), the driver need
+only make a call to one of:
+
+.. code-block:: none
+
+ ssize_t videobuf_read_one(struct videobuf_queue *q,
+ char __user *data, size_t count,
+ loff_t *ppos, int nonblocking);
+
+ ssize_t videobuf_read_stream(struct videobuf_queue *q,
+ char __user *data, size_t count,
+ loff_t *ppos, int vbihack, int nonblocking);
+
+Either one of these functions will read frame data into data, returning the
+amount actually read; the difference is that videobuf_read_one() will only
+read a single frame, while videobuf_read_stream() will read multiple frames
+if they are needed to satisfy the count requested by the application. A
+typical driver read() implementation will start the capture engine, call
+one of the above functions, then stop the engine before returning (though a
+smarter implementation might leave the engine running for a little while in
+anticipation of another read() call happening in the near future).
+
+The poll() function can usually be implemented with a direct call to:
+
+.. code-block:: none
+
+ unsigned int videobuf_poll_stream(struct file *file,
+ struct videobuf_queue *q,
+ poll_table *wait);
+
+Note that the actual wait queue eventually used will be the one associated
+with the first available buffer.
+
+When streaming I/O is done to kernel-space buffers, the driver must support
+the mmap() system call to enable user space to access the data. In many
+V4L2 drivers, the often-complex mmap() implementation simplifies to a
+single call to:
+
+.. code-block:: none
+
+ int videobuf_mmap_mapper(struct videobuf_queue *q,
+ struct vm_area_struct *vma);
+
+Everything else is handled by the videobuf code.
+
+The release() function requires two separate videobuf calls:
+
+.. code-block:: none
+
+ void videobuf_stop(struct videobuf_queue *q);
+ int videobuf_mmap_free(struct videobuf_queue *q);
+
+The call to videobuf_stop() terminates any I/O in progress - though it is
+still up to the driver to stop the capture engine. The call to
+videobuf_mmap_free() will ensure that all buffers have been unmapped; if
+so, they will all be passed to the buf_release() callback. If buffers
+remain mapped, videobuf_mmap_free() returns an error code instead. The
+purpose is clearly to cause the closing of the file descriptor to fail if
+buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
+ignores its return value.
+
+ioctl() operations
+------------------
+
+The V4L2 API includes a very long list of driver callbacks to respond to
+the many ioctl() commands made available to user space. A number of these
+- those associated with streaming I/O - turn almost directly into videobuf
+calls. The relevant helper functions are:
+
+.. code-block:: none
+
+ int videobuf_reqbufs(struct videobuf_queue *q,
+ struct v4l2_requestbuffers *req);
+ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+ int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+ int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b,
+ int nonblocking);
+ int videobuf_streamon(struct videobuf_queue *q);
+ int videobuf_streamoff(struct videobuf_queue *q);
+
+So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
+vidioc_reqbufs() callback which, in turn, usually only needs to locate the
+proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
+These support functions can replace a great deal of buffer management
+boilerplate in a lot of V4L2 drivers.
+
+The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
+complex, of course, since they will also need to deal with starting and
+stopping the capture engine.
+
+Buffer allocation
+-----------------
+
+Thus far, we have talked about buffers, but have not looked at how they are
+allocated. The scatter/gather case is the most complex on this front. For
+allocation, the driver can leave buffer allocation entirely up to the
+videobuf layer; in this case, buffers will be allocated as anonymous
+user-space pages and will be very scattered indeed. If the application is
+using user-space buffers, no allocation is needed; the videobuf layer will
+take care of calling get_user_pages() and filling in the scatterlist array.
+
+If the driver needs to do its own memory allocation, it should be done in
+the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The
+first step is a call to:
+
+.. code-block:: none
+
+ struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
+
+The returned videobuf_dmabuf structure (defined in
+<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
+
+.. code-block:: none
+
+ struct scatterlist *sglist;
+ int sglen;
+
+The driver must allocate an appropriately-sized scatterlist array and
+populate it with pointers to the pieces of the allocated buffer; sglen
+should be set to the length of the array.
+
+Drivers using the vmalloc() method need not (and cannot) concern themselves
+with buffer allocation at all; videobuf will handle those details. The
+same is normally true of contiguous-DMA drivers as well; videobuf will
+allocate the buffers (with dma_alloc_coherent()) when it sees fit. That
+means that these drivers may be trying to do high-order allocations at any
+time, an operation which is not always guaranteed to work. Some drivers
+play tricks by allocating DMA space at system boot time; videobuf does not
+currently play well with those drivers.
+
+As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
+as long as that buffer is physically contiguous. Normal user-space
+allocations will not meet that criterion, but buffers obtained from other
+kernel drivers, or those contained within huge pages, will work with these
+drivers.
+
+Filling the buffers
+-------------------
+
+The final part of a videobuf implementation has no direct callback - it's
+the portion of the code which actually puts frame data into the buffers,
+usually in response to interrupts from the device. For all types of
+drivers, this process works approximately as follows:
+
+ - Obtain the next available buffer and make sure that somebody is actually
+ waiting for it.
+
+ - Get a pointer to the memory and put video data there.
+
+ - Mark the buffer as done and wake up the process waiting for it.
+
+Step (1) above is done by looking at the driver-managed list_head structure
+- the one which is filled in the buf_queue() callback. Because starting
+the engine and enqueueing buffers are done in separate steps, it's possible
+for the engine to be running without any buffers available - in the
+vmalloc() case especially. So the driver should be prepared for the list
+to be empty. It is equally possible that nobody is yet interested in the
+buffer; the driver should not remove it from the list or fill it until a
+process is waiting on it. That test can be done by examining the buffer's
+done field (a wait_queue_head_t structure) with waitqueue_active().
+
+A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
+DMA; that ensures that the videobuf layer will not try to do anything with
+it while the device is transferring data.
+
+For scatter/gather drivers, the needed memory pointers will be found in the
+scatterlist structure described above. Drivers using the vmalloc() method
+can get a memory pointer with:
+
+.. code-block:: none
+
+ void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
+
+For contiguous DMA drivers, the function to use is:
+
+.. code-block:: none
+
+ dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
+
+The contiguous DMA API goes out of its way to hide the kernel-space address
+of the DMA buffer from drivers.
+
+The final step is to set the size field of the relevant videobuf_buffer
+structure to the actual size of the captured image, set state to
+VIDEOBUF_DONE, then call wake_up() on the done queue. At this point, the
+buffer is owned by the videobuf layer and the driver should not touch it
+again.
+
+Developers who are interested in more information can go into the relevant
+header files; there are a few low-level functions declared there which have
+not been talked about here. Note also that all of these calls are exported
+GPL-only, so they will not be available to non-GPL kernel modules.
diff --git a/Documentation/driver-api/media/v4l2-videobuf2.rst b/Documentation/driver-api/media/v4l2-videobuf2.rst
new file mode 100644
index 0000000000..1044f64ff1
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-videobuf2.rst
@@ -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