From 9a59d9361a68b0f664372312debd7396eda3ed55 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Sep 2017 06:26:03 -0400 Subject: media: cec-ioc-dqevent.rst: fix typo The documentation talked about INITIAL_VALUE when the actual define is INITIAL_STATE. Fix this. Signed-off-by: Hans Verkuil Reported-by: Jonas Karlman Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/cec.h.rst.exceptions | 2 -- Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/cec.h.rst.exceptions b/Documentation/media/cec.h.rst.exceptions index b1687532742f..d9fd092de6f8 100644 --- a/Documentation/media/cec.h.rst.exceptions +++ b/Documentation/media/cec.h.rst.exceptions @@ -24,8 +24,6 @@ ignore define CEC_VENDOR_ID_NONE ignore define CEC_MODE_INITIATOR_MSK ignore define CEC_MODE_FOLLOWER_MSK -ignore define CEC_EVENT_FL_INITIAL_STATE - # Part of CEC 2.0 spec - shouldn't be documented too? ignore define CEC_LOG_ADDR_TV ignore define CEC_LOG_ADDR_RECORD_1 diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index a5c821809cc6..4fe96e2adf4c 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -172,9 +172,9 @@ it is guaranteed that the state did change in between the two events. :stub-columns: 0 :widths: 3 1 8 - * .. _`CEC-EVENT-FL-INITIAL-VALUE`: + * .. _`CEC-EVENT-FL-INITIAL-STATE`: - - ``CEC_EVENT_FL_INITIAL_VALUE`` + - ``CEC_EVENT_FL_INITIAL_STATE`` - 1 - Set for the initial events that are generated when the device is opened. See the table above for which events do this. This allows -- cgit v1.2.1 From da634f623e4879d7716029a84791fc596ebac24d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Sep 2017 05:23:57 -0400 Subject: media: cec-core.rst/cec-ioc-receive.rst: clarify CEC_TX_STATUS_ERROR CEC_TX_STATUS_ERROR can be used if the HW cannot tell LOST_ARB and LOW_DRIVE apart, or when some other error occurs. It is not a replacement for NACK. So the hardware must be able to tell the difference between OK, NACK and 'something else'. Clarify the documentation (both public and kernel API) on this point. Also fix two small typos (this messages -> this message). Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/cec-core.rst | 7 +++++-- Documentation/media/uapi/cec/cec-ioc-receive.rst | 10 +++++----- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 28866259998c..d37e107f2fde 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -227,8 +227,8 @@ CEC_TX_STATUS_LOW_DRIVE: retransmission. CEC_TX_STATUS_ERROR: - some unspecified error occurred: this can be one of - the previous two if the hardware cannot differentiate or something + some unspecified error occurred: this can be one of ARB_LOST + or LOW_DRIVE if the hardware cannot differentiate or something else entirely. CEC_TX_STATUS_MAX_RETRIES: @@ -238,6 +238,9 @@ CEC_TX_STATUS_MAX_RETRIES: 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 diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index 0f397c535a4c..bdad4b197bcd 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -131,7 +131,7 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - ``tx_status`` - The status bits of the transmitted message. See :ref:`cec-tx-status` for the possible status values. It is 0 if - this messages was received, not transmitted. + this message was received, not transmitted. * - __u8 - ``msg[16]`` - The message payload. For :ref:`ioctl CEC_TRANSMIT ` this is filled in by the @@ -168,7 +168,7 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - ``tx_status`` - The status bits of the transmitted message. See :ref:`cec-tx-status` for the possible status values. It is 0 if - this messages was received, not transmitted. + this message was received, not transmitted. * - __u8 - ``tx_arb_lost_cnt`` - A counter of the number of transmit attempts that resulted in the @@ -256,9 +256,9 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). - ``CEC_TX_STATUS_ERROR`` - 0x10 - Some error occurred. This is used for any errors that do not fit - the previous two, either because the hardware could not tell which - error occurred, or because the hardware tested for other - conditions besides those two. + ``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because + the hardware could not tell which error occurred, or because the hardware + tested for other conditions besides those two. * .. _`CEC-TX-STATUS-MAX-RETRIES`: - ``CEC_TX_STATUS_MAX_RETRIES`` -- cgit v1.2.1 From 00f7adff0c3a1d793ffa213c28d82c47dfd8ab04 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 30 Aug 2017 12:05:55 -0400 Subject: media: cec-ioc-dqevent.rst: document new CEC_EVENT_PIN_HPD_LOW/HIGH events Document these new CEC events. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/cec/cec-ioc-dqevent.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'Documentation/media') diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 4fe96e2adf4c..b6fd86424fbb 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -161,6 +161,24 @@ it is guaranteed that the state did change in between the two events. - Generated if the CEC pin goes from a low voltage to a high voltage. Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` capability set. + * .. _`CEC-EVENT-PIN-HPD-LOW`: + + - ``CEC_EVENT_PIN_HPD_LOW`` + - 5 + - Generated if the HPD pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the HPD pin can be read and + if the HPD is low, then an initial event will be generated for that + filehandle. + * .. _`CEC-EVENT-PIN-HPD-HIGH`: + + - ``CEC_EVENT_PIN_HPD_HIGH`` + - 6 + - Generated if the HPD pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. When open() is called, the HPD pin can be read and + if the HPD is high, then an initial event will be generated for that + filehandle. .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| -- cgit v1.2.1 From 259a41d9ae8f3689742267f340ad2b159d00b302 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Sep 2017 08:21:37 -0400 Subject: media: dvb_frontend: fix return values for FE_SET_PROPERTY There are several problems with regards to the return of FE_SET_PROPERTY. The original idea were to return per-property return codes via tvp->result field, and to return an updated set of values. However, that never worked. What's actually implemented is: - the FE_SET_PROPERTY implementation doesn't call .get_frontend callback in order to get the actual parameters after return; - the tvp->result field is only filled if there's no error. So, it is always filled with zero; - FE_SET_PROPERTY doesn't call memdup_user() nor any other copy_to_user() function. So, any changes to the properties will be lost; - FE_SET_PROPERTY is declared as a write-only ioctl (IOW). While we could fix the above, it could cause regressions. So, let's just assume what the code really does, updating the documentation accordingly and removing the logic that would update the discarded tvp->result. Reviewed-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/dvb/fe-get-property.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/uapi/dvb/fe-get-property.rst b/Documentation/media/uapi/dvb/fe-get-property.rst index 948d2ba84f2c..b69741d9cedf 100644 --- a/Documentation/media/uapi/dvb/fe-get-property.rst +++ b/Documentation/media/uapi/dvb/fe-get-property.rst @@ -48,8 +48,11 @@ depends on the delivery system and on the device: - This call requires read/write access to the device. - - At return, the values are updated to reflect the actual parameters - used. +.. note:: + + At return, the values aren't updated to reflect the actual + parameters used. If the actual parameters are needed, an explicit + call to ``FE_GET_PROPERTY`` is needed. - ``FE_GET_PROPERTY:`` -- cgit v1.2.1 From 7af90c04cc8343fb8063d0b3d7ba135daf3aabde Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Sep 2017 16:46:10 -0400 Subject: media: dtv-core.rst: add chapters and introductory tests for common parts Better document the DVB common parts by adding two sections and an introductory text for each. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-core.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index de9a228aca8a..4cf9cf63bafd 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -29,8 +29,20 @@ I2C bus. Digital TV Common functions --------------------------- +Math functions +~~~~~~~~~~~~~~ + +Provide some commonly-used math functions, usually required in order to +estimate signal strength and signal to noise measurements in dB. + .. kernel-doc:: drivers/media/dvb-core/dvb_math.h + +DVB devices +~~~~~~~~~~~ + +Those functions are responsible for handling the DVB device nodes. + .. kernel-doc:: drivers/media/dvb-core/dvbdev.h Digital TV Ring buffer -- cgit v1.2.1 From 5b3b8c81b47aa3ca473d310b1aa3ab93f0ec9c6b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Sep 2017 16:54:15 -0400 Subject: media: dtv-core.rst: split into multiple files Instead of document all kAPI into a single file, split it on multiple ones. That makes easier to maintain each part. As a side effect, it will produce multiple html pages, with is a good idea. No changes at the text. Just some chapter levels changed. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-ca.rst | 4 + Documentation/media/kapi/dtv-common.rst | 55 +++ Documentation/media/kapi/dtv-core.rst | 585 +----------------------------- Documentation/media/kapi/dtv-demux.rst | 71 ++++ Documentation/media/kapi/dtv-frontend.rst | 443 ++++++++++++++++++++++ 5 files changed, 579 insertions(+), 579 deletions(-) create mode 100644 Documentation/media/kapi/dtv-ca.rst create mode 100644 Documentation/media/kapi/dtv-common.rst create mode 100644 Documentation/media/kapi/dtv-demux.rst create mode 100644 Documentation/media/kapi/dtv-frontend.rst (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-ca.rst b/Documentation/media/kapi/dtv-ca.rst new file mode 100644 index 000000000000..a4dd700189b0 --- /dev/null +++ b/Documentation/media/kapi/dtv-ca.rst @@ -0,0 +1,4 @@ +Digital TV Conditional Access kABI +---------------------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h diff --git a/Documentation/media/kapi/dtv-common.rst b/Documentation/media/kapi/dtv-common.rst new file mode 100644 index 000000000000..40cf1033b5e1 --- /dev/null +++ b/Documentation/media/kapi/dtv-common.rst @@ -0,0 +1,55 @@ +Digital TV Common functions +--------------------------- + +Math functions +~~~~~~~~~~~~~~ + +Provide some commonly-used math functions, usually required in order to +estimate signal strength and signal to noise measurements in dB. + +.. kernel-doc:: drivers/media/dvb-core/dvb_math.h + + +DVB devices +~~~~~~~~~~~ + +Those functions are responsible for handling the DVB device nodes. + +.. kernel-doc:: drivers/media/dvb-core/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:: drivers/media/dvb-core/dvb_ringbuffer.h diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index 4cf9cf63bafd..8ee384f61fa0 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -26,584 +26,11 @@ I2C bus. abandoned standard, not used anymore) and ATSC version 3.0 current proposals. Currently, the DVB subsystem doesn't implement those standards. -Digital TV Common functions ---------------------------- -Math functions -~~~~~~~~~~~~~~ +.. toctree:: + :maxdepth: 1 -Provide some commonly-used math functions, usually required in order to -estimate signal strength and signal to noise measurements in dB. - -.. kernel-doc:: drivers/media/dvb-core/dvb_math.h - - -DVB devices -~~~~~~~~~~~ - -Those functions are responsible for handling the DVB device nodes. - -.. kernel-doc:: drivers/media/dvb-core/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:: drivers/media/dvb-core/dvb_ringbuffer.h - - -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 -``drivers/media/dvb-core``. - -Demodulator driver -^^^^^^^^^^^^^^^^^^ - -The demodulator driver is responsible to talk with the decoding part of the -hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with -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 ``drivers/media/dvb-core/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 ` 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 ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is -responsible for tuning the device. It supports multiple algoritms to -detect a channel, as defined at enum :c:func:`dvbfe_algo`. - -The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver -doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to -``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning, -e. g. it will try first to use the specified center frequency ``f``, -then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|, -``f`` - 2 x |delta| and so on. - -If the hardware has internally a some sort of zigzag algorithm, you should -define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``. - -.. note:: - - The core frontend support also supports - a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to - define its own hardware-assisted algorithm. Very few hardware need to - use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other - function callbacks at struct :c:type:`dvb_frontend_ops`. - -Attaching frontend driver to the bridge driver -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Before using the Digital TV frontend core, the bridge driver should attach -the frontend demod, tuner and SEC devices and call -:c:func:`dvb_register_frontend()`, -in order to register the new frontend at the subsystem. At device -detach/removal, the bridge driver should call -:c:func:`dvb_unregister_frontend()` to -remove the frontend from the core and then :c:func:`dvb_frontend_detach()` -to free the memory allocated by the frontend drivers. - -The drivers should also call :c:func:`dvb_frontend_suspend()` as part of -their handler for the :c:type:`device_driver`.\ ``suspend()``, and -:c:func:`dvb_frontend_resume()` as -part of their handler for :c:type:`device_driver`.\ ``resume()``. - -A few other optional functions are provided to handle some special cases. - -.. _dvbv5_stats: - -Digital TV Frontend statistics -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Introduction -^^^^^^^^^^^^ - -Digital TV frontends provide a range of -:ref:`statistics ` 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 this 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 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, is - available when the main carrier is detected. On those hardware, CNR - measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``, - see :c:type:`fe_status`). - - On other devices, it requires inner FEC decoding, - as the frontend measures it indirectly from other parameters (e. g. after - ``FE_HAS_VITERBI``, see :c:type:`fe_status`). - - Having it available after inner FEC is more common. - -Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`) - - Those counters measure the number of bits and bit errors errors after - the forward error correction (FEC) on the inner coding block - (after Viterbi, LDPC or other inner code). - - - Due to its nature, those statistics depend on full coding lock - (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``, - see :c:type:`fe_status`). - -Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`) - - Those counters measure the number of bits and bit errors errors before - the forward error correction (FEC) on the inner coding block - (before Viterbi, LDPC or other inner code). - - - Not all frontends provide this kind of statistics. - - - Due to its nature, those statistics depend on inner coding lock (e. g. - after ``FE_HAS_VITERBI``, see :c:type:`fe_status`). - -Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`) - - Those counters measure the number of blocks and block errors errors after - the forward error correction (FEC) on the inner coding block - (before Viterbi, LDPC or other inner code). - - - Due to its nature, those statistics depend on full coding lock - (e. g. after ``FE_HAS_SYNC`` or after - ``FE_HAS_LOCK``, see :c:type:`fe_status`). - -.. note:: All counters should be monotonically increased as they're - collected from the hardware. - -A typical example of the logic that handle status and statistics is:: - - static int foo_get_status_and_stats(struct dvb_frontend *fe) - { - struct foo_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - int rc; - enum fe_status *status; - - /* Both status and strength are always available */ - rc = foo_read_status(fe, &status); - if (rc < 0) - return rc; - - rc = foo_read_strength(fe); - if (rc < 0) - return rc; - - /* Check if CNR is available */ - if (!(fe->status & FE_HAS_CARRIER)) - return 0; - - rc = foo_read_cnr(fe); - if (rc < 0) - return rc; - - /* Check if pre-BER stats are available */ - if (!(fe->status & FE_HAS_VITERBI)) - return 0; - - rc = foo_get_pre_ber(fe); - if (rc < 0) - return rc; - - /* Check if post-BER stats are available */ - if (!(fe->status & FE_HAS_SYNC)) - return 0; - - rc = foo_get_post_ber(fe); - if (rc < 0) - return rc; - } - - static const struct dvb_frontend_ops ops = { - /* ... */ - .read_status = foo_get_status_and_stats, - }; - -Statistics collect -^^^^^^^^^^^^^^^^^^ - -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 programable), 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:: drivers/media/dvb-core/dvb_frontend.h - - -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 -drivers/media/dvb-core. - -The demux kABI should be implemented for each demux in the system. It is -used to select the TS source of a demux and to manage the demux resources. -When the demux client allocates a resource via the demux kABI, it receives -a pointer to the kABI of that resource. - -Each demux receives its TS input from a DVB front-end or from memory, as -set via this demux kABI. In a system with more than one front-end, the kABI -can be used to select one of the DVB front-ends as a TS source for a demux, -unless this is fixed in the HW platform. - -The demux kABI only controls front-ends regarding to their connections with -demuxes; the kABI used to set the other front-end parameters, such as -tuning, are devined via the Digital TV Frontend kABI. - -The functions that implement the abstract interface demux should be defined -static or module private and registered to the Demux core for external -access. It is not necessary to implement every function in the struct -&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 ------------------- - -Demux Callback -~~~~~~~~~~~~~~ - -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. - -.. kernel-doc:: drivers/media/dvb-core/demux.h - -Digital TV Conditional Access kABI ----------------------------------- - -.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h + dtv-common + dtv-frontend + dtv-demux + dtv-ca diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst new file mode 100644 index 000000000000..8169c479156e --- /dev/null +++ b/Documentation/media/kapi/dtv-demux.rst @@ -0,0 +1,71 @@ +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 +drivers/media/dvb-core. + +The demux kABI should be implemented for each demux in the system. It is +used to select the TS source of a demux and to manage the demux resources. +When the demux client allocates a resource via the demux kABI, it receives +a pointer to the kABI of that resource. + +Each demux receives its TS input from a DVB front-end or from memory, as +set via this demux kABI. In a system with more than one front-end, the kABI +can be used to select one of the DVB front-ends as a TS source for a demux, +unless this is fixed in the HW platform. + +The demux kABI only controls front-ends regarding to their connections with +demuxes; the kABI used to set the other front-end parameters, such as +tuning, are devined via the Digital TV Frontend kABI. + +The functions that implement the abstract interface demux should be defined +static or module private and registered to the Demux core for external +access. It is not necessary to implement every function in the struct +&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. + +.. kernel-doc:: drivers/media/dvb-core/demux.h diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst new file mode 100644 index 000000000000..9f67b7a7387d --- /dev/null +++ b/Documentation/media/kapi/dtv-frontend.rst @@ -0,0 +1,443 @@ +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 +``drivers/media/dvb-core``. + +Demodulator driver +^^^^^^^^^^^^^^^^^^ + +The demodulator driver is responsible to talk with the decoding part of the +hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with +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 ``drivers/media/dvb-core/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 ` 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 ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is +responsible for tuning the device. It supports multiple algoritms to +detect a channel, as defined at enum :c:func:`dvbfe_algo`. + +The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver +doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to +``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning, +e. g. it will try first to use the specified center frequency ``f``, +then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|, +``f`` - 2 x |delta| and so on. + +If the hardware has internally a some sort of zigzag algorithm, you should +define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``. + +.. note:: + + The core frontend support also supports + a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to + define its own hardware-assisted algorithm. Very few hardware need to + use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other + function callbacks at struct :c:type:`dvb_frontend_ops`. + +Attaching frontend driver to the bridge driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before using the Digital TV frontend core, the bridge driver should attach +the frontend demod, tuner and SEC devices and call +:c:func:`dvb_register_frontend()`, +in order to register the new frontend at the subsystem. At device +detach/removal, the bridge driver should call +:c:func:`dvb_unregister_frontend()` to +remove the frontend from the core and then :c:func:`dvb_frontend_detach()` +to free the memory allocated by the frontend drivers. + +The drivers should also call :c:func:`dvb_frontend_suspend()` as part of +their handler for the :c:type:`device_driver`.\ ``suspend()``, and +:c:func:`dvb_frontend_resume()` as +part of their handler for :c:type:`device_driver`.\ ``resume()``. + +A few other optional functions are provided to handle some special cases. + +.. _dvbv5_stats: + +Digital TV Frontend statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Introduction +^^^^^^^^^^^^ + +Digital TV frontends provide a range of +:ref:`statistics ` 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 this 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 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, is + available when the main carrier is detected. On those hardware, CNR + measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``, + see :c:type:`fe_status`). + + On other devices, it requires inner FEC decoding, + as the frontend measures it indirectly from other parameters (e. g. after + ``FE_HAS_VITERBI``, see :c:type:`fe_status`). + + Having it available after inner FEC is more common. + +Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`) + - Those counters measure the number of bits and bit errors errors after + the forward error correction (FEC) on the inner coding block + (after Viterbi, LDPC or other inner code). + + - Due to its nature, those statistics depend on full coding lock + (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``, + see :c:type:`fe_status`). + +Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`) + - Those counters measure the number of bits and bit errors errors before + the forward error correction (FEC) on the inner coding block + (before Viterbi, LDPC or other inner code). + + - Not all frontends provide this kind of statistics. + + - Due to its nature, those statistics depend on inner coding lock (e. g. + after ``FE_HAS_VITERBI``, see :c:type:`fe_status`). + +Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`) + - Those counters measure the number of blocks and block errors errors after + the forward error correction (FEC) on the inner coding block + (before Viterbi, LDPC or other inner code). + + - Due to its nature, those statistics depend on full coding lock + (e. g. after ``FE_HAS_SYNC`` or after + ``FE_HAS_LOCK``, see :c:type:`fe_status`). + +.. note:: All counters should be monotonically increased as they're + collected from the hardware. + +A typical example of the logic that handle status and statistics is:: + + static int foo_get_status_and_stats(struct dvb_frontend *fe) + { + struct foo_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + int rc; + enum fe_status *status; + + /* Both status and strength are always available */ + rc = foo_read_status(fe, &status); + if (rc < 0) + return rc; + + rc = foo_read_strength(fe); + if (rc < 0) + return rc; + + /* Check if CNR is available */ + if (!(fe->status & FE_HAS_CARRIER)) + return 0; + + rc = foo_read_cnr(fe); + if (rc < 0) + return rc; + + /* Check if pre-BER stats are available */ + if (!(fe->status & FE_HAS_VITERBI)) + return 0; + + rc = foo_get_pre_ber(fe); + if (rc < 0) + return rc; + + /* Check if post-BER stats are available */ + if (!(fe->status & FE_HAS_SYNC)) + return 0; + + rc = foo_get_post_ber(fe); + if (rc < 0) + return rc; + } + + static const struct dvb_frontend_ops ops = { + /* ... */ + .read_status = foo_get_status_and_stats, + }; + +Statistics collect +^^^^^^^^^^^^^^^^^^ + +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 programable), 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:: drivers/media/dvb-core/dvb_frontend.h -- cgit v1.2.1 From b2fc98fc91647e4b7ec1ac90001729345ec3e790 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Oct 2017 13:06:30 -0400 Subject: media: dtv-frontend.rst fix a typo: algoritms -> algorithms WARNING: 'algoritms' may be misspelled - perhaps 'algorithms'? +responsible for tuning the device. It supports multiple algoritms to Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-frontend.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst index 9f67b7a7387d..f1a2fdaab5ba 100644 --- a/Documentation/media/kapi/dtv-frontend.rst +++ b/Documentation/media/kapi/dtv-frontend.rst @@ -119,7 +119,7 @@ Satellite TV reception is:: .. |delta| unicode:: U+00394 The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is -responsible for tuning the device. It supports multiple algoritms to +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 -- cgit v1.2.1 From 1607b8b574c9318ea58f3f08cf85514ceddf467a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Sep 2017 17:05:14 -0400 Subject: media: dtv-demux.rst: minor markup improvements Add a cross-reference to a mentioned structure and split the kernel-doc stuff on a separate chapter. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-demux.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst index 8169c479156e..3ee69266e206 100644 --- a/Documentation/media/kapi/dtv-demux.rst +++ b/Documentation/media/kapi/dtv-demux.rst @@ -7,8 +7,8 @@ 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 -drivers/media/dvb-core. +The header file for this kABI is named ``demux.h`` and located in +``drivers/media/dvb-core``. 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. @@ -27,7 +27,7 @@ tuning, are devined via the Digital TV Frontend kABI. The functions that implement the abstract interface demux should be defined static or module private and registered to the Demux core for external access. It is not necessary to implement every function in the struct -&dmx_demux. For example, a demux interface might support Section filtering, +: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. @@ -43,8 +43,6 @@ 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 ~~~~~~~~~~~~~~~~~~ @@ -68,4 +66,7 @@ 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 functions and types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + .. kernel-doc:: drivers/media/dvb-core/demux.h -- cgit v1.2.1 From 8c6b18631ff6a4823249becb51b428da5f0f9a40 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 19 Sep 2017 19:03:14 -0400 Subject: media: dtv-demux.rst: parse other demux headers with kernel-doc Now that we have kernel-doc markups at dvb_demux.h and dmxdev.h, parse them. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-demux.rst | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst index 3ee69266e206..7aa865a2b43f 100644 --- a/Documentation/media/kapi/dtv-demux.rst +++ b/Documentation/media/kapi/dtv-demux.rst @@ -66,7 +66,17 @@ 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 functions and types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Digital TV Demux device registration functions and data structures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/media/dvb-core/dmxdev.h + +High-level Digital TV demux interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/media/dvb-core/dvb_demux.h + +Driver-internal low-level hardware specific driver demux interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. kernel-doc:: drivers/media/dvb-core/demux.h -- cgit v1.2.1 From b5b03a200934cad3c77e85026a3549847234f74e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Sep 2017 13:51:06 -0400 Subject: media: dvb-net.rst: document DVB network kAPI interface That's the last DVB kAPI that misses documentation. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/dtv-core.rst | 1 + Documentation/media/kapi/dtv-net.rst | 4 ++++ Documentation/media/uapi/dvb/net-types.rst | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Documentation/media/kapi/dtv-net.rst (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index 8ee384f61fa0..bca743dc6b43 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -34,3 +34,4 @@ I2C bus. dtv-frontend dtv-demux dtv-ca + dtv-net diff --git a/Documentation/media/kapi/dtv-net.rst b/Documentation/media/kapi/dtv-net.rst new file mode 100644 index 000000000000..ced991b73d69 --- /dev/null +++ b/Documentation/media/kapi/dtv-net.rst @@ -0,0 +1,4 @@ +Digital TV Network kABI +----------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_net.h diff --git a/Documentation/media/uapi/dvb/net-types.rst b/Documentation/media/uapi/dvb/net-types.rst index e1177bdcd623..8fa3292eaa42 100644 --- a/Documentation/media/uapi/dvb/net-types.rst +++ b/Documentation/media/uapi/dvb/net-types.rst @@ -1,6 +1,6 @@ .. -*- coding: utf-8; mode: rst -*- -.. _dmx_types: +.. _net_types: ************** Net Data Types -- cgit v1.2.1 From b33494e950c6d492c65799252cb8bc2692468221 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Sep 2017 14:42:42 -0400 Subject: media: dvb uAPI docs: get rid of examples section That section is too outdated and got superseded by DVBv5 and by libdvbv5. Maybe some day we'll end adding updated examples there, but while nobody has time or interest of doing that, just mention that there and get rid of the current examples for good. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/dvb/examples.rst | 378 +----------------------------- 1 file changed, 6 insertions(+), 372 deletions(-) (limited to 'Documentation/media') diff --git a/Documentation/media/uapi/dvb/examples.rst b/Documentation/media/uapi/dvb/examples.rst index e0f627ca2e4d..16dd90fa9e94 100644 --- a/Documentation/media/uapi/dvb/examples.rst +++ b/Documentation/media/uapi/dvb/examples.rst @@ -6,377 +6,11 @@ Examples ******** -In this section we would like to present some examples for using the Digital -TV API. +In the past, we used to have a set of examples here. However, those +examples got out of date and doesn't even compile nowadays. -.. note:: +Also, nowadays, the best is to use the libdvbv5 DVB API nowadays, +with is fully documented. - This section is out of date, and the code below won't even - compile. Please refer to the - `libdvbv5 `__ for - updated/recommended examples. - - -.. _tuning: - -Example: Tuning -=============== - -We will start with a generic tuning subroutine that uses the frontend -and SEC, as well as the demux devices. The example is given for QPSK -tuners, but can easily be adjusted for QAM. - - -.. code-block:: c - - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #include - - #define DMX "/dev/dvb/adapter0/demux1" - #define FRONT "/dev/dvb/adapter0/frontend1" - #define SEC "/dev/dvb/adapter0/sec1" - - /* routine for checking if we have a signal and other status information*/ - int FEReadStatus(int fd, fe_status_t *stat) - { - int ans; - - if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ - perror("FE READ STATUS: "); - return -1; - } - - if (*stat & FE_HAS_POWER) - printf("FE HAS POWER\\n"); - - if (*stat & FE_HAS_SIGNAL) - printf("FE HAS SIGNAL\\n"); - - if (*stat & FE_SPECTRUM_INV) - printf("SPEKTRUM INV\\n"); - - return 0; - } - - - /* tune qpsk */ - /* freq: frequency of transponder */ - /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ - /* diseqc: DiSEqC address of the used LNB */ - /* pol: Polarisation */ - /* srate: Symbol Rate */ - /* fec. FEC */ - /* lnb_lof1: local frequency of lower LNB band */ - /* lnb_lof2: local frequency of upper LNB band */ - /* lnb_slof: switch frequency of LNB */ - - int set_qpsk_channel(int freq, int vpid, int apid, int tpid, - int diseqc, int pol, int srate, int fec, int lnb_lof1, - int lnb_lof2, int lnb_slof) - { - struct secCommand scmd; - struct secCmdSequence scmds; - struct dmx_pes_filter_params pesFilterParams; - FrontendParameters frp; - struct pollfd pfd[1]; - FrontendEvent event; - int demux1, demux2, demux3, front; - - frequency = (uint32_t) freq; - symbolrate = (uint32_t) srate; - - if((front = open(FRONT,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - - if((sec = open(SEC,O_RDWR)) < 0){ - perror("SEC DEVICE: "); - return -1; - } - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux3 < 0){ - if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (freq < lnb_slof) { - frp.Frequency = (freq - lnb_lof1); - scmds.continuousTone = SEC_TONE_OFF; - } else { - frp.Frequency = (freq - lnb_lof2); - scmds.continuousTone = SEC_TONE_ON; - } - frp.Inversion = INVERSION_AUTO; - if (pol) scmds.voltage = SEC_VOLTAGE_18; - else scmds.voltage = SEC_VOLTAGE_13; - - scmd.type=0; - scmd.u.diseqc.addr=0x10; - scmd.u.diseqc.cmd=0x38; - scmd.u.diseqc.numParams=1; - scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | - (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | - (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); - - scmds.miniCommand=SEC_MINI_NONE; - scmds.numCommands=1; - scmds.commands=&scmd; - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - frp.u.qpsk.SymbolRate = srate; - frp.u.qpsk.FEC_inner = fec; - - if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ - perror("QPSK TUNE: "); - return -1; - } - - pfd[0].fd = front; - pfd[0].events = POLLIN; - - if (poll(pfd,1,3000)){ - if (pfd[0].revents & POLLIN){ - printf("Getting QPSK event\\n"); - if ( ioctl(front, FE_GET_EVENT, &event) - - == -EOVERFLOW){ - perror("qpsk get event"); - return -1; - } - printf("Received "); - switch(event.type){ - case FE_UNEXPECTED_EV: - printf("unexpected event\\n"); - return -1; - case FE_FAILURE_EV: - printf("failure event\\n"); - return -1; - - case FE_COMPLETION_EV: - printf("completion event\\n"); - } - } - } - - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_vpid"); - return -1; - } - - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_apid"); - return -1; - } - - pesFilterParams.pid = tpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pes_type = DMX_PES_TELETEXT; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_tpid"); - return -1; - } - - return has_signal(fds); - } - -The program assumes that you are using a universal LNB and a standard -DiSEqC switch with up to 4 addresses. Of course, you could build in some -more checking if tuning was successful and maybe try to repeat the -tuning process. Depending on the external hardware, i.e. LNB and DiSEqC -switch, and weather conditions this may be necessary. - - -.. _the_dvr_device: - -Example: The DVR device -======================== - -The following program code shows how to use the DVR device for -recording. - - -.. code-block:: c - - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - #define DVR "/dev/dvb/adapter0/dvr1" - #define AUDIO "/dev/dvb/adapter0/audio1" - #define VIDEO "/dev/dvb/adapter0/video1" - - #define BUFFY (188*20) - #define MAX_LENGTH (1024*1024*5) /* record 5MB */ - - - /* switch the demuxes to recording, assuming the transponder is tuned */ - - /* demux1, demux2: file descriptor of video and audio filters */ - /* vpid, apid: PIDs of video and audio channels */ - - int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) - { - struct dmx_pes_filter_params pesFilterParams; - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - return 0; - } - - /* start recording MAX_LENGTH , assuming the transponder is tuned */ - - /* demux1, demux2: file descriptor of video and audio filters */ - /* vpid, apid: PIDs of video and audio channels */ - int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) - { - int i; - int len; - int written; - uint8_t buf[BUFFY]; - uint64_t length; - struct pollfd pfd[1]; - int dvr, dvr_out; - - /* open dvr device */ - if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ - perror("DVR DEVICE"); - return -1; - } - - /* switch video and audio demuxes to dvr */ - printf ("Switching dvr on\\n"); - i = switch_to_record(demux1, demux2, vpid, apid); - printf("finished: "); - - printf("Recording %2.0f MB of test file in TS format\\n", - MAX_LENGTH/(1024.0*1024.0)); - length = 0; - - /* open output file */ - if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT - |O_TRUNC, S_IRUSR|S_IWUSR - |S_IRGRP|S_IWGRP|S_IROTH| - S_IWOTH)) < 0){ - perror("Can't open file for dvr test"); - return -1; - } - - pfd[0].fd = dvr; - pfd[0].events = POLLIN; - - /* poll for dvr data and write to file */ - while (length < MAX_LENGTH ) { - if (poll(pfd,1,1)){ - if (pfd[0].revents & POLLIN){ - len = read(dvr, buf, BUFFY); - if (len < 0){ - perror("recording"); - return -1; - } - if (len > 0){ - written = 0; - while (written < len) - written += - write (dvr_out, - buf, len); - length += len; - printf("written %2.0f MB\\r", - length/1024./1024.); - } - } - } - } - return 0; - } +Please refer to the `libdvbv5 `__ +for updated/recommended examples. -- cgit v1.2.1 From d65b34135ff86e8e04144ccdfcc2824127e0a7e8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 29 Aug 2017 06:17:06 -0400 Subject: media: v4l: async: Add V4L2 async documentation to the documentation build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The V4L2 async wasn't part of the documentation build. Fix this. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Acked-by: Hans Verkuil Reviewed-by: Laurent Pinchart Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/v4l2-async.rst | 3 +++ Documentation/media/kapi/v4l2-core.rst | 1 + 2 files changed, 4 insertions(+) create mode 100644 Documentation/media/kapi/v4l2-async.rst (limited to 'Documentation/media') diff --git a/Documentation/media/kapi/v4l2-async.rst b/Documentation/media/kapi/v4l2-async.rst new file mode 100644 index 000000000000..523ff9eb09a0 --- /dev/null +++ b/Documentation/media/kapi/v4l2-async.rst @@ -0,0 +1,3 @@ +V4L2 async kAPI +^^^^^^^^^^^^^^^ +.. kernel-doc:: include/media/v4l2-async.h diff --git a/Documentation/media/kapi/v4l2-core.rst b/Documentation/media/kapi/v4l2-core.rst index c7434f38fd9c..5cf292037a48 100644 --- a/Documentation/media/kapi/v4l2-core.rst +++ b/Documentation/media/kapi/v4l2-core.rst @@ -19,6 +19,7 @@ Video4Linux devices v4l2-mc v4l2-mediabus v4l2-mem2mem + v4l2-async v4l2-fwnode v4l2-rect v4l2-tuner -- cgit v1.2.1