.. SPDX-License-Identifier: GPL-2.0

Digital TV Frontend kABI
------------------------

Digital TV Frontend
~~~~~~~~~~~~~~~~~~~

The Digital TV Frontend kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
frontend layer. It is only of interest for Digital TV device driver writers.
The header file for this API is named ``dvb_frontend.h`` and located in
``include/media/``.

Demodulator driver
^^^^^^^^^^^^^^^^^^

The demodulator driver is responsible for talking with the decoding part of the
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
tells what type of digital TV standards are supported, and points to a
series of functions that allow the DVB core to command the hardware via
the code under ``include/media/dvb_frontend.c``.

A typical example of such struct in a driver ``foo`` is::

	static struct dvb_frontend_ops foo_ops = {
		.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
		.info = {
			.name	= "foo DVB-T/T2/C driver",
			.caps = FE_CAN_FEC_1_2 |
				FE_CAN_FEC_2_3 |
				FE_CAN_FEC_3_4 |
				FE_CAN_FEC_5_6 |
				FE_CAN_FEC_7_8 |
				FE_CAN_FEC_AUTO |
				FE_CAN_QPSK |
				FE_CAN_QAM_16 |
				FE_CAN_QAM_32 |
				FE_CAN_QAM_64 |
				FE_CAN_QAM_128 |
				FE_CAN_QAM_256 |
				FE_CAN_QAM_AUTO |
				FE_CAN_TRANSMISSION_MODE_AUTO |
				FE_CAN_GUARD_INTERVAL_AUTO |
				FE_CAN_HIERARCHY_AUTO |
				FE_CAN_MUTE_TS |
				FE_CAN_2G_MODULATION,
			.frequency_min = 42000000, /* Hz */
			.frequency_max = 1002000000, /* Hz */
			.symbol_rate_min = 870000,
			.symbol_rate_max = 11700000
		},
		.init = foo_init,
		.sleep = foo_sleep,
		.release = foo_release,
		.set_frontend = foo_set_frontend,
		.get_frontend = foo_get_frontend,
		.read_status = foo_get_status_and_stats,
		.tune = foo_tune,
		.i2c_gate_ctrl = foo_i2c_gate_ctrl,
		.get_frontend_algo = foo_get_algo,
	};

A typical example of such struct in a driver ``bar`` meant to be used on
Satellite TV reception is::

	static const struct dvb_frontend_ops bar_ops = {
		.delsys = { SYS_DVBS, SYS_DVBS2 },
		.info = {
			.name		= "Bar DVB-S/S2 demodulator",
			.frequency_min	= 500000, /* KHz */
			.frequency_max	= 2500000, /* KHz */
			.frequency_stepsize	= 0,
			.symbol_rate_min = 1000000,
			.symbol_rate_max = 45000000,
			.symbol_rate_tolerance = 500,
			.caps = FE_CAN_INVERSION_AUTO |
				FE_CAN_FEC_AUTO |
				FE_CAN_QPSK,
		},
		.init = bar_init,
		.sleep = bar_sleep,
		.release = bar_release,
		.set_frontend = bar_set_frontend,
		.get_frontend = bar_get_frontend,
		.read_status = bar_get_status_and_stats,
		.i2c_gate_ctrl = bar_i2c_gate_ctrl,
		.get_frontend_algo = bar_get_algo,
		.tune = bar_tune,

		/* Satellite-specific */
		.diseqc_send_master_cmd = bar_send_diseqc_msg,
		.diseqc_send_burst = bar_send_burst,
		.set_tone = bar_set_tone,
		.set_voltage = bar_set_voltage,
	};

.. note::

   #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
      frequencies are specified in kHz, while, for terrestrial and cable
      standards, they're specified in Hz. Due to that, if the same frontend
      supports both types, you'll need to have two separate
      :c:type:`dvb_frontend_ops` structures, one for each standard.
   #) The ``.i2c_gate_ctrl`` field is present only when the hardware has
      allows controlling an I2C gate (either directly of via some GPIO pin),
      in order to remove the tuner from the I2C bus after a channel is
      tuned.
   #) All new drivers should implement the
      :ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
      Yet, there are a number of callbacks meant to get statistics for
      signal strength, S/N and UCB. Those are there to provide backward
      compatibility with legacy applications that don't support the DVBv5
      API. Implementing those callbacks are optional. Those callbacks may be
      removed in the future, after we have all existing drivers supporting
      DVBv5 stats.
   #) Other callbacks are required for satellite TV standards, in order to
      control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
      ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.

.. |delta|   unicode:: U+00394

The ``include/media/dvb_frontend.c`` has a kernel thread which is
responsible for tuning the device. It supports multiple algorithms to
detect a channel, as defined at enum :c:func:`dvbfe_algo`.

The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
doesn't fill its field at struct :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 <frontend-stat-properties>` meant to help tuning the device
and measuring the quality of service.

For each statistics measurement, the driver should set the type of scale used,
or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
time. Drivers should also provide the number of statistics for each type.
that's usually 1 for most video standards [#f2]_.

Drivers should initialize each statistic counters with length and
scale at its init code. For example, if the frontend provides signal
strength, it should have, on its init code::

	struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;

	c->strength.len = 1;
	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;

And, when the statistics got updated, set the scale::

	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
	c->strength.stat[0].uvalue = strength;

.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
   set of statistics. On such cases, len should be equal to 4. The first
   value corresponds to the global stat; the other ones to each layer, e. g.:

   - c->cnr.stat[0] for global S/N carrier ratio,
   - c->cnr.stat[1] for Layer A S/N carrier ratio,
   - c->cnr.stat[2] for layer B S/N carrier ratio,
   - c->cnr.stat[3] for layer C S/N carrier ratio.

.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
   ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.

Groups of statistics
^^^^^^^^^^^^^^^^^^^^

There are several groups of statistics currently supported:

Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
  - Measures the signal strength level at the analog part of the tuner or
    demod.

  - Typically obtained from the gain applied to the tuner and/or frontend
    in order to detect the carrier. When no carrier is detected, the gain is
    at the maximum value (so, strength is on its minimal).

  - As the gain is visible through the set of registers that adjust the gain,
    typically, this statistics is always available [#f3]_.

  - Drivers should try to make it available all the times, as these statistics
    can be used when adjusting an antenna position and to check for troubles
    at the cabling.

  .. [#f3] On a few devices, the gain keeps floating if there is no carrier.
     On such devices, strength report should check first if carrier is
     detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
     and otherwise return the lowest possible value.

Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
  - Signal to Noise ratio for the main carrier.

  - Signal to Noise measurement depends on the device. On some hardware, it is
    available when the main carrier is detected. On those hardware, CNR
    measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
    see :c:type:`fe_status`).

    On other devices, it requires inner FEC decoding,
    as the frontend measures it indirectly from other parameters (e. g. after
    ``FE_HAS_VITERBI``, see :c:type:`fe_status`).

    Having it available after inner FEC is more common.

Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
  - Those counters measure the number of bits and bit errors 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 collection
^^^^^^^^^^^^^^^^^^^^^

On almost all frontend hardware, the bit and byte counts are stored by
the hardware after a certain amount of time or after the total bit/block
counter reaches a certain value (usually programmable), for example, on
every 1000 ms or after receiving 1,000,000 bits.

So, if you read the registers too soon, you'll end by reading the same
value as in the previous reading, causing the monotonic value to be
incremented too often.

Drivers should take the responsibility to avoid too often reads. That
can be done using two approaches:

if the driver have a bit that indicates when a collected data is ready
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Driver should check such bit before making the statistics available.

An example of such behavior can be found at this code snippet (adapted
from mb86a20s driver's logic)::

	static int foo_get_pre_ber(struct dvb_frontend *fe)
	{
		struct foo_state *state = fe->demodulator_priv;
		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
		int rc, bit_error;

		/* Check if the BER measures are already available */
		rc = foo_read_u8(state, 0x54);
		if (rc < 0)
			return rc;

		if (!rc)
			return 0;

		/* Read Bit Error Count */
		bit_error = foo_read_u32(state, 0x55);
		if (bit_error < 0)
			return bit_error;

		/* Read Total Bit Count */
		rc = foo_read_u32(state, 0x51);
		if (rc < 0)
			return rc;

		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
		c->pre_bit_error.stat[0].uvalue += bit_error;
		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
		c->pre_bit_count.stat[0].uvalue += rc;

		return 0;
	}

If the driver doesn't provide a statistics available check bit
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

A few devices, however, may not provide a way to check if the stats are
available (or the way to check it is unknown). They may not even provide
a way to directly read the total number of bits or blocks.

On those devices, the driver need to ensure that it won't be reading from
the register too often and/or estimate the total number of bits/blocks.

On such drivers, a typical routine to get statistics would be like
(adapted from dib8000 driver's logic)::

	struct foo_state {
		/* ... */

		unsigned long per_jiffies_stats;
	}

	static int foo_get_pre_ber(struct dvb_frontend *fe)
	{
		struct foo_state *state = fe->demodulator_priv;
		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
		int rc, bit_error;
		u64 bits;

		/* Check if time for stats was elapsed */
		if (!time_after(jiffies, state->per_jiffies_stats))
			return 0;

		/* Next stat should be collected in 1000 ms */
		state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);

		/* Read Bit Error Count */
		bit_error = foo_read_u32(state, 0x55);
		if (bit_error < 0)
			return bit_error;

		/*
		 * On this particular frontend, there's no register that
		 * would provide the number of bits per 1000ms sample. So,
		 * some function would calculate it based on DTV properties
		 */
		bits = get_number_of_bits_per_1000ms(fe);

		c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
		c->pre_bit_error.stat[0].uvalue += bit_error;
		c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
		c->pre_bit_count.stat[0].uvalue += bits;

		return 0;
	}

Please notice that, on both cases, we're getting the statistics using the
:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
the frontend core will automatically call this function periodically
(usually, 3 times per second, when the frontend is locked).

That warrants that we won't miss to collect a counter and increment the
monotonic stats at the right time.

Digital TV Frontend functions and types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. kernel-doc:: include/media/dvb_frontend.h
