^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Digital TV Frontend kABI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) ------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) Digital TV Frontend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) The Digital TV Frontend kABI defines a driver-internal interface for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) registering low-level, hardware specific driver to a hardware independent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) frontend layer. It is only of interest for Digital TV device driver writers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) The header file for this API is named ``dvb_frontend.h`` and located in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) ``include/media/``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) Demodulator driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) The demodulator driver is responsible for talking with the decoding part of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) tells what type of digital TV standards are supported, and points to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) series of functions that allow the DVB core to command the hardware via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) the code under ``include/media/dvb_frontend.c``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) A typical example of such struct in a driver ``foo`` is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static struct dvb_frontend_ops foo_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .name = "foo DVB-T/T2/C driver",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .caps = FE_CAN_FEC_1_2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) FE_CAN_FEC_2_3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) FE_CAN_FEC_5_6 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) FE_CAN_FEC_7_8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) FE_CAN_QAM_16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) FE_CAN_QAM_32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) FE_CAN_QAM_64 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) FE_CAN_QAM_128 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) FE_CAN_QAM_256 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) FE_CAN_HIERARCHY_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) FE_CAN_MUTE_TS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) FE_CAN_2G_MODULATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .frequency_min = 42000000, /* Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .frequency_max = 1002000000, /* Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .symbol_rate_min = 870000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .symbol_rate_max = 11700000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .init = foo_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .sleep = foo_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .release = foo_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .set_frontend = foo_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .get_frontend = foo_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .read_status = foo_get_status_and_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .tune = foo_tune,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .i2c_gate_ctrl = foo_i2c_gate_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .get_frontend_algo = foo_get_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) A typical example of such struct in a driver ``bar`` meant to be used on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Satellite TV reception is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static const struct dvb_frontend_ops bar_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .delsys = { SYS_DVBS, SYS_DVBS2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .name = "Bar DVB-S/S2 demodulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .frequency_min = 500000, /* KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .frequency_max = 2500000, /* KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .frequency_stepsize = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .symbol_rate_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .symbol_rate_max = 45000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .symbol_rate_tolerance = 500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) FE_CAN_QPSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .init = bar_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .sleep = bar_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .release = bar_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .set_frontend = bar_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .get_frontend = bar_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .read_status = bar_get_status_and_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .i2c_gate_ctrl = bar_i2c_gate_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .get_frontend_algo = bar_get_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .tune = bar_tune,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Satellite-specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .diseqc_send_master_cmd = bar_send_diseqc_msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .diseqc_send_burst = bar_send_burst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .set_tone = bar_set_tone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .set_voltage = bar_set_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .. note::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) frequencies are specified in kHz, while, for terrestrial and cable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) standards, they're specified in Hz. Due to that, if the same frontend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) supports both types, you'll need to have two separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) :c:type:`dvb_frontend_ops` structures, one for each standard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #) The ``.i2c_gate_ctrl`` field is present only when the hardware has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) allows controlling an I2C gate (either directly of via some GPIO pin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) in order to remove the tuner from the I2C bus after a channel is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) tuned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #) All new drivers should implement the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) :ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) Yet, there are a number of callbacks meant to get statistics for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) signal strength, S/N and UCB. Those are there to provide backward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) compatibility with legacy applications that don't support the DVBv5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) API. Implementing those callbacks are optional. Those callbacks may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) removed in the future, after we have all existing drivers supporting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) DVBv5 stats.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #) Other callbacks are required for satellite TV standards, in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .. |delta| unicode:: U+00394
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) The ``include/media/dvb_frontend.c`` has a kernel thread which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) responsible for tuning the device. It supports multiple algorithms to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) detect a channel, as defined at enum :c:func:`dvbfe_algo`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) doesn't fill its field at struct dvb_frontend_ops, it will default to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) e. g. it will try first to use the specified center frequency ``f``,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ``f`` - 2 x |delta| and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) If the hardware has internally a some sort of zigzag algorithm, you should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .. note::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) The core frontend support also supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) define its own hardware-assisted algorithm. Very few hardware need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) function callbacks at struct dvb_frontend_ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) Attaching frontend driver to the bridge driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) Before using the Digital TV frontend core, the bridge driver should attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) the frontend demod, tuner and SEC devices and call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) :c:func:`dvb_register_frontend()`,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) in order to register the new frontend at the subsystem. At device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) detach/removal, the bridge driver should call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) :c:func:`dvb_unregister_frontend()` to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) remove the frontend from the core and then :c:func:`dvb_frontend_detach()`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) to free the memory allocated by the frontend drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) The drivers should also call :c:func:`dvb_frontend_suspend()` as part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) their handler for the :c:type:`device_driver`.\ ``suspend()``, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) :c:func:`dvb_frontend_resume()` as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) part of their handler for :c:type:`device_driver`.\ ``resume()``.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) A few other optional functions are provided to handle some special cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .. _dvbv5_stats:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) Digital TV Frontend statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) Introduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) ^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) Digital TV frontends provide a range of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) :ref:`statistics <frontend-stat-properties>` meant to help tuning the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) and measuring the quality of service.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) For each statistics measurement, the driver should set the type of scale used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) time. Drivers should also provide the number of statistics for each type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) that's usually 1 for most video standards [#f2]_.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) Drivers should initialize each statistic counters with length and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) scale at its init code. For example, if the frontend provides signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) strength, it should have, on its init code::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) c->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) And, when the statistics got updated, set the scale::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) c->strength.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) c->strength.stat[0].uvalue = strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) set of statistics. On such cases, len should be equal to 4. The first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) value corresponds to the global stat; the other ones to each layer, e. g.:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) - c->cnr.stat[0] for global S/N carrier ratio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) - c->cnr.stat[1] for Layer A S/N carrier ratio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) - c->cnr.stat[2] for layer B S/N carrier ratio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) - c->cnr.stat[3] for layer C S/N carrier ratio.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) Groups of statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ^^^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) There are several groups of statistics currently supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) - Measures the signal strength level at the analog part of the tuner or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) demod.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) - Typically obtained from the gain applied to the tuner and/or frontend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) in order to detect the carrier. When no carrier is detected, the gain is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) at the maximum value (so, strength is on its minimal).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) - As the gain is visible through the set of registers that adjust the gain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) typically, this statistics is always available [#f3]_.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) - Drivers should try to make it available all the times, as these statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) can be used when adjusting an antenna position and to check for troubles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) at the cabling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .. [#f3] On a few devices, the gain keeps floating if there is no carrier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) On such devices, strength report should check first if carrier is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) and otherwise return the lowest possible value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) - Signal to Noise ratio for the main carrier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) - Signal to Noise measurement depends on the device. On some hardware, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) available when the main carrier is detected. On those hardware, CNR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) see :c:type:`fe_status`).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) On other devices, it requires inner FEC decoding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) as the frontend measures it indirectly from other parameters (e. g. after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) Having it available after inner FEC is more common.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) - Those counters measure the number of bits and bit errors errors after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) the forward error correction (FEC) on the inner coding block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) (after Viterbi, LDPC or other inner code).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) - Due to its nature, those statistics depend on full coding lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) see :c:type:`fe_status`).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) - Those counters measure the number of bits and bit errors errors before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) the forward error correction (FEC) on the inner coding block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) (before Viterbi, LDPC or other inner code).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) - Not all frontends provide this kind of statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) - Due to its nature, those statistics depend on inner coding lock (e. g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) - Those counters measure the number of blocks and block errors errors after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) the forward error correction (FEC) on the inner coding block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) (before Viterbi, LDPC or other inner code).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) - Due to its nature, those statistics depend on full coding lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) (e. g. after ``FE_HAS_SYNC`` or after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ``FE_HAS_LOCK``, see :c:type:`fe_status`).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .. note:: All counters should be monotonically increased as they're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) collected from the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) A typical example of the logic that handle status and statistics is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int foo_get_status_and_stats(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct foo_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) enum fe_status *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Both status and strength are always available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) rc = foo_read_status(fe, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) rc = foo_read_strength(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Check if CNR is available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!(fe->status & FE_HAS_CARRIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) rc = foo_read_cnr(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Check if pre-BER stats are available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!(fe->status & FE_HAS_VITERBI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) rc = foo_get_pre_ber(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Check if post-BER stats are available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!(fe->status & FE_HAS_SYNC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) rc = foo_get_post_ber(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static const struct dvb_frontend_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .read_status = foo_get_status_and_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) Statistics collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ^^^^^^^^^^^^^^^^^^^^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) On almost all frontend hardware, the bit and byte counts are stored by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) the hardware after a certain amount of time or after the total bit/block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) counter reaches a certain value (usually programmable), for example, on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) every 1000 ms or after receiving 1,000,000 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) So, if you read the registers too soon, you'll end by reading the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) value as in the previous reading, causing the monotonic value to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) incremented too often.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) Drivers should take the responsibility to avoid too often reads. That
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) can be done using two approaches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if the driver have a bit that indicates when a collected data is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) Driver should check such bit before making the statistics available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) An example of such behavior can be found at this code snippet (adapted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) from mb86a20s driver's logic)::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int foo_get_pre_ber(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct foo_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int rc, bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Check if the BER measures are already available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) rc = foo_read_u8(state, 0x54);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Read Bit Error Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bit_error = foo_read_u32(state, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (bit_error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Read Total Bit Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) rc = foo_read_u32(state, 0x51);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) c->pre_bit_error.stat[0].uvalue += bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) c->pre_bit_count.stat[0].uvalue += rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) If the driver doesn't provide a statistics available check bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) A few devices, however, may not provide a way to check if the stats are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) available (or the way to check it is unknown). They may not even provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) a way to directly read the total number of bits or blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) On those devices, the driver need to ensure that it won't be reading from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) the register too often and/or estimate the total number of bits/blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) On such drivers, a typical routine to get statistics would be like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) (adapted from dib8000 driver's logic)::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct foo_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) unsigned long per_jiffies_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int foo_get_pre_ber(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct foo_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int rc, bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u64 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* Check if time for stats was elapsed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (!time_after(jiffies, state->per_jiffies_stats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Next stat should be collected in 1000 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* Read Bit Error Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) bit_error = foo_read_u32(state, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (bit_error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * On this particular frontend, there's no register that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * would provide the number of bits per 1000ms sample. So,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * some function would calculate it based on DTV properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) bits = get_number_of_bits_per_1000ms(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) c->pre_bit_error.stat[0].uvalue += bit_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) c->pre_bit_count.stat[0].uvalue += bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) Please notice that, on both cases, we're getting the statistics using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) :c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) the frontend core will automatically call this function periodically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) (usually, 3 times per second, when the frontend is locked).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) That warrants that we won't miss to collect a counter and increment the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) monotonic stats at the right time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) Digital TV Frontend functions and types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .. kernel-doc:: include/media/dvb_frontend.h