~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/driver-api/media/dtv-frontend.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/driver-api/media/dtv-frontend.rst (Version linux-6.12-rc7) and /Documentation/driver-api/media/dtv-frontend.rst (Version linux-5.8.18)


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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php