2. Digital TV (DVB) devices

3. Digital TV Common functions

unsigned int intlog2(u32 value)

computes log2 of a value; the result is shifted left by 24 bits

Parameters

u32 value
The value (must be != 0)

Description

to use rational values you can use the following method:

intlog2(value) = intlog2(value * 2^x) - x * 2^24

Some usecase examples:

intlog2(8) will give 3 << 24 = 3 * 2^24

intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24

intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24

Return

log2(value) * 2^24

unsigned int intlog10(u32 value)

computes log10 of a value; the result is shifted left by 24 bits

Parameters

u32 value
The value (must be != 0)

Description

to use rational values you can use the following method:

intlog10(value) = intlog10(value * 10^x) - x * 2^24

An usecase example:

intlog10(1000) will give 3 << 24 = 3 * 2^24

due to the implementation intlog10(1000) might be not exactly 3 * 2^24

look at intlog2 for similar examples

Return

log10(value) * 2^24

struct dvb_adapter

represents a Digital TV adapter using Linux DVB API

Definition

struct dvb_adapter {
  int num;
  struct list_head list_head;
  struct list_head device_list;
  const char * name;
  u8 proposed_mac;
  void * priv;
  struct device * device;
  struct module * module;
  int mfe_shared;
  struct dvb_device * mfe_dvbdev;
  struct mutex mfe_lock;
#if defined(CONFIG_MEDIA_CONTROLLER_DVB
  struct media_device * mdev;
  struct media_entity * conn;
  struct media_pad * conn_pads;
#endif
};

Members

num
Number of the adapter
list_head
List with the DVB adapters
device_list
List with the DVB devices
name
Name of the adapter
proposed_mac
proposed MAC address for the adapter
priv
private data
device
pointer to struct device
module
pointer to struct module
mfe_shared
mfe shared: indicates mutually exclusive frontends Thie usage of this flag is currently deprecated
mfe_dvbdev
Frontend device in use, in the case of MFE
mfe_lock
Lock to prevent using the other frontends when MFE is used.
mdev
pointer to struct media_device, used when the media controller is used.
conn
RF connector. Used only if the device has no separate tuner.
conn_pads
pointer to struct media_pad associated with conn;
struct dvb_device

represents a DVB device node

Definition

struct dvb_device {
  struct list_head list_head;
  const struct file_operations * fops;
  struct dvb_adapter * adapter;
  int type;
  int minor;
  u32 id;
  int readers;
  int writers;
  int users;
  wait_queue_head_t wait_queue;
  int (* kernel_ioctl) (struct file *file, unsigned int cmd, void *arg);
#if defined(CONFIG_MEDIA_CONTROLLER_DVB
  const char * name;
  struct media_intf_devnode * intf_devnode;
  unsigned tsout_num_entities;
  struct media_entity * entity;
  struct media_entity * tsout_entity;
  struct media_pad * pads;
  struct media_pad * tsout_pads;
#endif
  void * priv;
};

Members

list_head
List head with all DVB devices
fops
pointer to struct file_operations
adapter
pointer to the adapter that holds this device node
type
type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
minor
devnode minor number. Major number is always DVB_MAJOR.
id
device ID number, inside the adapter
readers
Initialized by the caller. Each call to open() in Read Only mode decreases this counter by one.
writers
Initialized by the caller. Each call to open() in Read/Write mode decreases this counter by one.
users
Initialized by the caller. Each call to open() in any mode decreases this counter by one.
wait_queue
wait queue, used to wait for certain events inside one of the DVB API callers
kernel_ioctl
callback function used to handle ioctl calls from userspace.
name
Name to be used for the device at the Media Controller
intf_devnode
Pointer to media_intf_devnode. Used by the dvbdev core to store the MC device node interface
tsout_num_entities
Number of Transport Stream output entities
entity
pointer to struct media_entity associated with the device node
tsout_entity
array with MC entities associated to each TS output node
pads
pointer to struct media_pad associated with entity;
tsout_pads
array with the source pads for each tsout_entity
priv
private data

Description

This structure is used by the DVB core (frontend, CA, net, demux) in order to create the device nodes. Usually, driver should not initialize this struct diretly.

int dvb_register_adapter(struct dvb_adapter * adap, const char * name, struct module * module, struct device * device, short * adapter_nums)

Registers a new DVB adapter

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
const char * name
Adapter’s name
struct module * module
initialized with THIS_MODULE at the caller
struct device * device
pointer to struct device that corresponds to the device driver
short * adapter_nums
Array with a list of the numbers for dvb_register_adapter; to select among them. Typically, initialized with: DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
int dvb_unregister_adapter(struct dvb_adapter * adap)

Unregisters a DVB adapter

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
int dvb_register_device(struct dvb_adapter * adap, struct dvb_device ** pdvbdev, const struct dvb_device * template, void * priv, int type, int demux_sink_pads)

Registers a new DVB device

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
struct dvb_device ** pdvbdev
pointer to the place where the new struct dvb_device will be stored
const struct dvb_device * template
Template used to create pdvbdev;
void * priv
private data
int type
type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
int demux_sink_pads
Number of demux outputs, to be used to create the TS outputs via the Media Controller.
void dvb_remove_device(struct dvb_device * dvbdev)

Remove a registered DVB device

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

This does not free memory. To do that, call dvb_free_device().

void dvb_free_device(struct dvb_device * dvbdev)

Free memory occupied by a DVB device.

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

Call dvb_unregister_device() before calling this function.

void dvb_unregister_device(struct dvb_device * dvbdev)

Unregisters a DVB device

Parameters

struct dvb_device * dvbdev
pointer to struct dvb_device

Description

This is a combination of dvb_remove_device() and dvb_free_device(). Using this function is usually a mistake, and is often an indicator for a use-after-free bug (when a userspace process keeps a file handle to a detached device).

int dvb_create_media_graph(struct dvb_adapter * adap, bool create_rf_connector)

Creates media graph for the Digital TV part of the device.

Parameters

struct dvb_adapter * adap
pointer to struct dvb_adapter
bool create_rf_connector
if true, it creates the RF connector too

Description

This function checks all DVB-related functions at the media controller entities and creates the needed links for the media graph. It is capable of working with multiple tuners or multiple frontends, but it won’t create links if the device has multiple tuners and multiple frontends or if the device has multiple muxes. In such case, the caller driver should manually create the remaining links.

4. Digital TV Ring buffer

Those routines implement ring buffers used to handle digital TV data and copy it from/to userspace.

Note

  1. For performance reasons read and write routines don’t check buffer sizes and/or number of bytes free/available. This has to be done before these routines are called. For example:
/* write @buflen: bytes */
free = dvb_ringbuffer_free(rbuf);
if (free >= buflen)
        count = dvb_ringbuffer_write(rbuf, buffer, buflen);
else
        /* do something */

/* read min. 1000, max. @bufsize: bytes */
avail = dvb_ringbuffer_avail(rbuf);
if (avail >= 1000)
        count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
else
        /* do something */
  1. If there is exactly one reader and one writer, there is no need to lock read or write operations. Two or more readers must be locked against each other. Flushing the buffer counts as a read operation. Resetting the buffer counts as a read and write operation. Two or more writers must be locked against each other.
struct dvb_ringbuffer

Describes a ring buffer used at DVB framework

Definition

struct dvb_ringbuffer {
  u8 * data;
  ssize_t size;
  ssize_t pread;
  ssize_t pwrite;
  int error;
  wait_queue_head_t queue;
  spinlock_t lock;
};

Members

data
Area were the ringbuffer data is written
size
size of the ringbuffer
pread
next position to read
pwrite
next position to write
error
used by ringbuffer clients to indicate that an error happened.
queue
Wait queue used by ringbuffer clients to indicate when buffer was filled
lock
Spinlock used to protect the ringbuffer
void dvb_ringbuffer_init(struct dvb_ringbuffer * rbuf, void * data, size_t len)

initialize ring buffer, lock and queue

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
void * data
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf
int dvb_ringbuffer_empty(struct dvb_ringbuffer * rbuf)

test whether buffer is empty

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer * rbuf)

returns the number of free bytes in the buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Return

number of free bytes in the buffer

ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer * rbuf)

returns the number of bytes waiting in the buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Return

number of bytes waiting in the buffer

void dvb_ringbuffer_reset(struct dvb_ringbuffer * rbuf)

resets the ringbuffer to initial state

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer

Description

Resets the read and write pointers to zero and flush the buffer.

This counts as a read and write operation

void dvb_ringbuffer_flush(struct dvb_ringbuffer * rbuf)

flush buffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer * rbuf)

flush buffer protected by spinlock and wake-up waiting task(s)

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
DVB_RINGBUFFER_PEEK(rbuf, offs)

peek at byte offs in the buffer

Parameters

rbuf
pointer to struct dvb_ringbuffer
offs
offset inside the ringbuffer
DVB_RINGBUFFER_SKIP(rbuf, num)

advance read ptr by num bytes

Parameters

rbuf
pointer to struct dvb_ringbuffer
num
number of bytes to advance
ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer * rbuf, u8 __user * buf, size_t len)

Reads a buffer into a user pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
u8 __user * buf
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the userspace. So, it will internally call copy_to_user().

Return

number of bytes transferred or -EFAULT

void dvb_ringbuffer_read(struct dvb_ringbuffer * rbuf, u8 * buf, size_t len)

Reads a buffer into a pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
u8 * buf
pointer to the buffer where the data will be stored
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the Kernel space

Return

number of bytes transferred or -EFAULT

DVB_RINGBUFFER_WRITE_BYTE(rbuf, byte)

write single byte to ring buffer

Parameters

rbuf
pointer to struct dvb_ringbuffer
byte
byte to write
ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer * rbuf, const u8 * buf, size_t len)

Writes a buffer into the ringbuffer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
const u8 * buf
pointer to the buffer where the data will be read
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the Kernel space

Return

number of bytes transferred or -EFAULT

ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer * rbuf, const u8 __user * buf, size_t len)

Writes a buffer received via a user pointer

Parameters

struct dvb_ringbuffer * rbuf
pointer to struct dvb_ringbuffer
const u8 __user * buf
pointer to the buffer where the data will be read
size_t len
bytes from ring buffer into buf

Description

This variant assumes that the buffer is a memory at the userspace. So, it will internally call copy_from_user().

Return

number of bytes transferred or -EFAULT

ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer * rbuf, u8 * buf, size_t len)

Write a packet into the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer to write to.
u8 * buf
Buffer to write.
size_t len
Length of buffer (currently limited to 65535 bytes max).

Return

Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.

ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 __user * buf, size_t len)

Read from a packet in the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
int offset
Offset into packet to read from.
u8 __user * buf
Destination buffer for data.
size_t len
Size of destination buffer.

Return

Number of bytes read, or -EFAULT.

Note

unlike dvb_ringbuffer_read(), this does NOT update the read pointer in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.

ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer * rbuf, size_t idx, int offset, u8 * buf, size_t len)

Read from a packet in the ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
int offset
Offset into packet to read from.
u8 * buf
Destination buffer for data.
size_t len
Size of destination buffer.

Note

unlike dvb_ringbuffer_read_user(), this DOES update the read pointer in the ringbuffer.

Return

Number of bytes read, or -EFAULT.

void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer * rbuf, size_t idx)

Dispose of a packet in the ring buffer.

Parameters

struct dvb_ringbuffer * rbuf
Ring buffer concerned.
size_t idx
Packet index as returned by dvb_ringbuffer_pkt_next().
ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer * rbuf, size_t idx, size_t * pktlen)

Get the index of the next packet in a ringbuffer.

Parameters

struct dvb_ringbuffer * rbuf
Ringbuffer concerned.
size_t idx
Previous packet index, or -1 to return the first packet index.
size_t * pktlen
On success, will be updated to contain the length of the packet in bytes. returns Packet index (if >=0), or -1 if no packets available.

5. Digital TV Frontend kABI

5.1. Digital TV Frontend

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

Before using the Digital TV frontend core, the bridge driver should attach the frontend demod, tuner and SEC devices and call dvb_register_frontend(), in order to register the new frontend at the subsystem. At device detach/removal, the bridge driver should call dvb_unregister_frontend() to remove the frontend from the core and then dvb_frontend_detach() to free the memory allocated by the frontend drivers.

The drivers should also call dvb_frontend_suspend() as part of their handler for the device_driver.suspend(), and dvb_frontend_resume() as part of their handler for device_driver.resume().

A few other optional functions are provided to handle some special cases.

struct dvb_frontend_tune_settings

parameters to adjust frontend tuning

Definition

struct dvb_frontend_tune_settings {
  int min_delay_ms;
  int step_size;
  int max_drift;
};

Members

min_delay_ms
minimum delay for tuning, in ms
step_size
step size between two consecutive frequencies
max_drift
maximum drift

NOTE

step_size is in Hz, for terrestrial/cable or kHz for satellite

struct dvb_tuner_info

Frontend name and min/max ranges/bandwidths

Definition

struct dvb_tuner_info {
  char name;
  u32 frequency_min;
  u32 frequency_max;
  u32 frequency_step;
  u32 bandwidth_min;
  u32 bandwidth_max;
  u32 bandwidth_step;
};

Members

name
name of the Frontend
frequency_min
minimal frequency supported
frequency_max
maximum frequency supported
frequency_step
frequency step
bandwidth_min
minimal frontend bandwidth supported
bandwidth_max
maximum frontend bandwidth supported
bandwidth_step
frontend bandwidth step

NOTE

frequency parameters are in Hz, for terrestrial/cable or kHz for satellite.

struct analog_parameters

Parameters to tune into an analog/radio channel

Definition

struct analog_parameters {
  unsigned int frequency;
  unsigned int mode;
  unsigned int audmode;
  u64 std;
};

Members

frequency
Frequency used by analog TV tuner (either in 62.5 kHz step, for TV, or 62.5 Hz for radio)
mode
Tuner mode, as defined on enum v4l2_tuner_type
audmode
Audio mode as defined for the rxsubchans field at videodev2.h, e. g. V4L2_TUNER_MODE_*
std
TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*

Description

Hybrid tuners should be supported by both V4L2 and DVB APIs. This struct contains the data that are used by the V4L2 side. To avoid dependencies from V4L2 headers, all enums here are declared as integers.

enum dvbfe_algo

defines the algorithm used to tune into a channel

Constants

DVBFE_ALGO_HW
Hardware Algorithm - Devices that support this algorithm do everything in hardware and no software support is needed to handle them. Requesting these devices to LOCK is the only thing required, device is supposed to do everything in the hardware.
DVBFE_ALGO_SW
Software Algorithm - These are dumb devices, that require software to do everything
DVBFE_ALGO_CUSTOM
Customizable Agorithm - Devices having this algorithm can be customized to have specific algorithms in the frontend driver, rather than simply doing a software zig-zag. In this case the zigzag maybe hardware assisted or it maybe completely done in hardware. In all cases, usage of this algorithm, in conjunction with the search and track callbacks, utilizes the driver specific algorithm.
DVBFE_ALGO_RECOVERY
Recovery Algorithm - These devices have AUTO recovery capabilities from LOCK failure

search callback possible return status

Constants

DVBFE_ALGO_SEARCH_SUCCESS
The frontend search algorithm completed and returned successfully
DVBFE_ALGO_SEARCH_ASLEEP
The frontend search algorithm is sleeping
DVBFE_ALGO_SEARCH_FAILED
The frontend search for a signal failed
DVBFE_ALGO_SEARCH_INVALID
The frontend search algorith was probably supplied with invalid parameters and the search is an invalid one
DVBFE_ALGO_SEARCH_AGAIN
The frontend search algorithm was requested to search again
DVBFE_ALGO_SEARCH_ERROR
The frontend search algorithm failed due to some error
struct dvb_tuner_ops

Tuner information and callbacks

Definition

struct dvb_tuner_ops {
  struct dvb_tuner_info info;
  void (* release) (struct dvb_frontend *fe);
  int (* init) (struct dvb_frontend *fe);
  int (* sleep) (struct dvb_frontend *fe);
  int (* suspend) (struct dvb_frontend *fe);
  int (* resume) (struct dvb_frontend *fe);
  int (* set_params) (struct dvb_frontend *fe);
  int (* set_analog_params) (struct dvb_frontend *fe, struct analog_parameters *p);
  int (* set_config) (struct dvb_frontend *fe, void *priv_cfg);
  int (* get_frequency) (struct dvb_frontend *fe, u32 *frequency);
  int (* get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
  int (* get_if_frequency) (struct dvb_frontend *fe, u32 *frequency);
#define TUNER_STATUS_LOCKED 1
#define TUNER_STATUS_STEREO 2
  int (* get_status) (struct dvb_frontend *fe, u32 *status);
  int (* get_rf_strength) (struct dvb_frontend *fe, u16 *strength);
  int (* get_afc) (struct dvb_frontend *fe, s32 *afc);
  int (* calc_regs) (struct dvb_frontend *fe, u8 *buf, int buf_len);
  int (* set_frequency) (struct dvb_frontend *fe, u32 frequency);
  int (* set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
};

Members

info
embedded struct dvb_tuner_info with tuner properties
release
callback function called when frontend is dettached. drivers should free any allocated memory.
init
callback function used to initialize the tuner device.
sleep
callback function used to put the tuner to sleep.
suspend
callback function used to inform that the Kernel will suspend.
resume
callback function used to inform that the Kernel is resuming from suspend.
set_params
callback function used to inform the tuner to tune into a digital TV channel. The properties to be used are stored at dvb_frontend.dtv_property_cache;. The tuner demod can change the parameters to reflect the changes needed for the channel to be tuned, and update statistics. This is the recommended way to set the tuner parameters and should be used on newer drivers.
set_analog_params
callback function used to tune into an analog TV channel on hybrid tuners. It passes analog_parameters; to the driver.
set_config
callback function used to send some tuner-specific parameters.
get_frequency
get the actual tuned frequency
get_bandwidth
get the bandwitdh used by the low pass filters
get_if_frequency
get the Intermediate Frequency, in Hz. For baseband, should return 0.
get_status
returns the frontend lock status
get_rf_strength
returns the RF signal strengh. Used mostly to support analog TV and radio. Digital TV should report, instead, via DVBv5 API (dvb_frontend.dtv_property_cache;).
get_afc
Used only by analog TV core. Reports the frequency drift due to AFC.
calc_regs
callback function used to pass register data settings for simple tuners. Shouldn’t be used on newer drivers.
set_frequency
Set a new frequency. Shouldn’t be used on newer drivers.
set_bandwidth
Set a new frequency. Shouldn’t be used on newer drivers.

NOTE

frequencies used on get_frequency and set_frequency are in Hz for terrestrial/cable or kHz for satellite.

struct analog_demod_info

Information struct for analog TV part of the demod

Definition

struct analog_demod_info {
  char * name;
};

Members

name
Name of the analog TV demodulator
struct analog_demod_ops

Demodulation information and callbacks for analog TV and radio

Definition

struct analog_demod_ops {
  struct analog_demod_info info;
  void (* set_params) (struct dvb_frontend *fe,struct analog_parameters *params);
  int (* has_signal) (struct dvb_frontend *fe, u16 *signal);
  int (* get_afc) (struct dvb_frontend *fe, s32 *afc);
  void (* tuner_status) (struct dvb_frontend *fe);
  void (* standby) (struct dvb_frontend *fe);
  void (* release) (struct dvb_frontend *fe);
  int (* i2c_gate_ctrl) (struct dvb_frontend *fe, int enable);
  int (* set_config) (struct dvb_frontend *fe, void *priv_cfg);
};

Members

info
pointer to struct analog_demod_info
set_params
callback function used to inform the demod to set the demodulator parameters needed to decode an analog or radio channel. The properties are passed via struct analog_params;.
has_signal
returns 0xffff if has signal, or 0 if it doesn’t.
get_afc
Used only by analog TV core. Reports the frequency drift due to AFC.
tuner_status
callback function that returns tuner status bits, e. g. TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO.
standby
set the tuner to standby mode.
release
callback function called when frontend is dettached. drivers should free any allocated memory.
i2c_gate_ctrl
controls the I2C gate. Newer drivers should use I2C mux support instead.
set_config
callback function used to send some tuner-specific parameters.
struct dvb_frontend_ops

Demodulation information and callbacks for ditialt TV

Definition

struct dvb_frontend_ops {
  struct dvb_frontend_info info;
  u8 delsys;
  void (* detach) (struct dvb_frontend *fe);
  void (* release) (struct dvb_frontend* fe);
  void (* release_sec) (struct dvb_frontend* fe);
  int (* init) (struct dvb_frontend* fe);
  int (* sleep) (struct dvb_frontend* fe);
  int (* write) (struct dvb_frontend* fe, const u8 buf[], int len);
  int (* tune) (struct dvb_frontend* fe,bool re_tune,unsigned int mode_flags,unsigned int *delay,enum fe_status *status);
  enum dvbfe_algo (* get_frontend_algo) (struct dvb_frontend *fe);
  int (* set_frontend) (struct dvb_frontend *fe);
  int (* get_tune_settings) (struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
  int (* get_frontend) (struct dvb_frontend *fe,struct dtv_frontend_properties *props);
  int (* read_status) (struct dvb_frontend *fe, enum fe_status *status);
  int (* read_ber) (struct dvb_frontend* fe, u32* ber);
  int (* read_signal_strength) (struct dvb_frontend* fe, u16* strength);
  int (* read_snr) (struct dvb_frontend* fe, u16* snr);
  int (* read_ucblocks) (struct dvb_frontend* fe, u32* ucblocks);
  int (* diseqc_reset_overload) (struct dvb_frontend* fe);
  int (* diseqc_send_master_cmd) (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
  int (* diseqc_recv_slave_reply) (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
  int (* diseqc_send_burst) (struct dvb_frontend *fe,enum fe_sec_mini_cmd minicmd);
  int (* set_tone) (struct dvb_frontend *fe, enum fe_sec_tone_mode tone);
  int (* set_voltage) (struct dvb_frontend *fe,enum fe_sec_voltage voltage);
  int (* enable_high_lnb_voltage) (struct dvb_frontend* fe, long arg);
  int (* dishnetwork_send_legacy_command) (struct dvb_frontend* fe, unsigned long cmd);
  int (* i2c_gate_ctrl) (struct dvb_frontend* fe, int enable);
  int (* ts_bus_ctrl) (struct dvb_frontend* fe, int acquire);
  int (* set_lna) (struct dvb_frontend *);
  enum dvbfe_search (* search) (struct dvb_frontend *fe);
  struct dvb_tuner_ops tuner_ops;
  struct analog_demod_ops analog_ops;
  int (* set_property) (struct dvb_frontend* fe, struct dtv_property* tvp);
  int (* get_property) (struct dvb_frontend* fe, struct dtv_property* tvp);
};

Members

info
embedded struct dvb_tuner_info with tuner properties
delsys
Delivery systems supported by the frontend
detach
callback function called when frontend is detached. drivers should clean up, but not yet free the struct dvb_frontend allocation.
release
callback function called when frontend is ready to be freed. drivers should free any allocated memory.
release_sec
callback function requesting that the Satelite Equipment Control (SEC) driver to release and free any memory allocated by the driver.
init
callback function used to initialize the tuner device.
sleep
callback function used to put the tuner to sleep.
write
callback function used by some demod legacy drivers to allow other drivers to write data into their registers. Should not be used on new drivers.
tune
callback function used by demod drivers that use DVBFE_ALGO_HW; to tune into a frequency.
get_frontend_algo
returns the desired hardware algorithm.
set_frontend
callback function used to inform the demod to set the parameters for demodulating a digital TV channel. The properties to be used are stored at dvb_frontend.dtv_property_cache;. The demod can change the parameters to reflect the changes needed for the channel to be decoded, and update statistics.
get_tune_settings
callback function
get_frontend
callback function used to inform the parameters actuall in use. The properties to be used are stored at dvb_frontend.dtv_property_cache; and update statistics. Please notice that it should not return an error code if the statistics are not available because the demog is not locked.
read_status
returns the locking status of the frontend.
read_ber
legacy callback function to return the bit error rate. Newer drivers should provide such info via DVBv5 API, e. g. set_frontend;/get_frontend;, implementing this callback only if DVBv3 API compatibility is wanted.
read_signal_strength
legacy callback function to return the signal strength. Newer drivers should provide such info via DVBv5 API, e. g. set_frontend;/get_frontend;, implementing this callback only if DVBv3 API compatibility is wanted.
read_snr
legacy callback function to return the Signal/Noise rate. Newer drivers should provide such info via DVBv5 API, e. g. set_frontend;/get_frontend;, implementing this callback only if DVBv3 API compatibility is wanted.
read_ucblocks
legacy callback function to return the Uncorrected Error Blocks. Newer drivers should provide such info via DVBv5 API, e. g. set_frontend;/get_frontend;, implementing this callback only if DVBv3 API compatibility is wanted.
diseqc_reset_overload
callback function to implement the FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite)
diseqc_send_master_cmd
callback function to implement the FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite).
diseqc_recv_slave_reply
callback function to implement the FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite)
diseqc_send_burst
callback function to implement the FE_DISEQC_SEND_BURST ioctl (only Satellite).
set_tone
callback function to implement the FE_SET_TONE ioctl (only Satellite).
set_voltage
callback function to implement the FE_SET_VOLTAGE ioctl (only Satellite).
enable_high_lnb_voltage
callback function to implement the FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite).
dishnetwork_send_legacy_command
callback function to implement the FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite). Drivers should not use this, except when the DVB core emulation fails to provide proper support (e.g. if set_voltage takes more than 8ms to work), and when backward compatibility with this legacy API is required.
i2c_gate_ctrl
controls the I2C gate. Newer drivers should use I2C mux support instead.
ts_bus_ctrl
callback function used to take control of the TS bus.
set_lna
callback function to power on/off/auto the LNA.
search
callback function used on some custom algo search algos.
tuner_ops
pointer to struct dvb_tuner_ops
analog_ops
pointer to struct analog_demod_ops
set_property
callback function to allow the frontend to validade incoming properties. Should not be used on new drivers.
get_property
callback function to allow the frontend to override outcoming properties. Should not be used on new drivers.
struct dtv_frontend_properties

contains a list of properties that are specific to a digital TV standard.

Definition

struct dtv_frontend_properties {
  u32 frequency;
  enum fe_modulation modulation;
  enum fe_sec_voltage voltage;
  enum fe_sec_tone_mode sectone;
  enum fe_spectral_inversion inversion;
  enum fe_code_rate fec_inner;
  enum fe_transmit_mode transmission_mode;
  u32 bandwidth_hz;
  enum fe_guard_interval guard_interval;
  enum fe_hierarchy hierarchy;
  u32 symbol_rate;
  enum fe_code_rate code_rate_HP;
  enum fe_code_rate code_rate_LP;
  enum fe_pilot pilot;
  enum fe_rolloff rolloff;
  enum fe_delivery_system delivery_system;
  enum fe_interleaving interleaving;
  u8 isdbt_partial_reception;
  u8 isdbt_sb_mode;
  u8 isdbt_sb_subchannel;
  u32 isdbt_sb_segment_idx;
  u32 isdbt_sb_segment_count;
  u8 isdbt_layer_enabled;
  struct layer;
  u32 stream_id;
  u8 atscmh_fic_ver;
  u8 atscmh_parade_id;
  u8 atscmh_nog;
  u8 atscmh_tnog;
  u8 atscmh_sgn;
  u8 atscmh_prc;
  u8 atscmh_rs_frame_mode;
  u8 atscmh_rs_frame_ensemble;
  u8 atscmh_rs_code_mode_pri;
  u8 atscmh_rs_code_mode_sec;
  u8 atscmh_sccc_block_mode;
  u8 atscmh_sccc_code_mode_a;
  u8 atscmh_sccc_code_mode_b;
  u8 atscmh_sccc_code_mode_c;
  u8 atscmh_sccc_code_mode_d;
  u32 lna;
  struct dtv_fe_stats strength;
  struct dtv_fe_stats cnr;
  struct dtv_fe_stats pre_bit_error;
  struct dtv_fe_stats pre_bit_count;
  struct dtv_fe_stats post_bit_error;
  struct dtv_fe_stats post_bit_count;
  struct dtv_fe_stats block_error;
  struct dtv_fe_stats block_count;
};

Members

frequency
frequency in Hz for terrestrial/cable or in kHz for Satellite
modulation
Frontend modulation type
voltage
SEC voltage (only Satellite)
sectone
SEC tone mode (only Satellite)
inversion
Spectral inversion
fec_inner
Forward error correction inner Code Rate
transmission_mode
Transmission Mode
bandwidth_hz
Bandwidth, in Hz. A zero value means that userspace wants to autodetect.
guard_interval
Guard Interval
hierarchy
Hierarchy
symbol_rate
Symbol Rate
code_rate_HP
high priority stream code rate
code_rate_LP
low priority stream code rate
pilot
Enable/disable/autodetect pilot tones
rolloff
Rolloff factor (alpha)
delivery_system
FE delivery system (e. g. digital TV standard)
interleaving
interleaving
isdbt_partial_reception
ISDB-T partial reception (only ISDB standard)
isdbt_sb_mode
ISDB-T Sound Broadcast (SB) mode (only ISDB standard)
isdbt_sb_subchannel
ISDB-T SB subchannel (only ISDB standard)
isdbt_sb_segment_idx
ISDB-T SB segment index (only ISDB standard)
isdbt_sb_segment_count
ISDB-T SB segment count (only ISDB standard)
isdbt_layer_enabled
ISDB Layer enabled (only ISDB standard)
layer
per layer interleaving.
stream_id
If different than zero, enable substream filtering, if hardware supports (DVB-S2 and DVB-T2).
atscmh_fic_ver
Version number of the FIC (Fast Information Channel) signaling data (only ATSC-M/H)
atscmh_parade_id
Parade identification number (only ATSC-M/H)
atscmh_nog
Number of MH groups per MH subframe for a designated parade (only ATSC-M/H)
atscmh_tnog
Total number of MH groups including all MH groups belonging to all MH parades in one MH subframe (only ATSC-M/H)
atscmh_sgn
Start group number (only ATSC-M/H)
atscmh_prc
Parade repetition cycle (only ATSC-M/H)
atscmh_rs_frame_mode
Reed Solomon (RS) frame mode (only ATSC-M/H)
atscmh_rs_frame_ensemble
RS frame ensemble (only ATSC-M/H)
atscmh_rs_code_mode_pri
RS code mode pri (only ATSC-M/H)
atscmh_rs_code_mode_sec
RS code mode sec (only ATSC-M/H)
atscmh_sccc_block_mode
Series Concatenated Convolutional Code (SCCC) Block Mode (only ATSC-M/H)
atscmh_sccc_code_mode_a
SCCC code mode A (only ATSC-M/H)
atscmh_sccc_code_mode_b
SCCC code mode B (only ATSC-M/H)
atscmh_sccc_code_mode_c
SCCC code mode C (only ATSC-M/H)
atscmh_sccc_code_mode_d
SCCC code mode D (only ATSC-M/H)
lna
Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
strength
DVBv5 API statistics: Signal Strength
cnr
DVBv5 API statistics: Signal to Noise ratio of the (main) carrier
pre_bit_error
DVBv5 API statistics: pre-Viterbi bit error count
pre_bit_count
DVBv5 API statistics: pre-Viterbi bit count
post_bit_error
DVBv5 API statistics: post-Viterbi bit error count
post_bit_count
DVBv5 API statistics: post-Viterbi bit count
block_error
DVBv5 API statistics: block error count
block_count
DVBv5 API statistics: block count

NOTE

derivated statistics like Uncorrected Error blocks (UCE) are calculated on userspace.

Only a subset of the properties are needed for a given delivery system. For more info, consult the media_api.html with the documentation of the Userspace API.

struct dvb_frontend

Frontend structure to be used on drivers.

Definition

struct dvb_frontend {
  struct kref refcount;
  struct dvb_frontend_ops ops;
  struct dvb_adapter * dvb;
  void * demodulator_priv;
  void * tuner_priv;
  void * frontend_priv;
  void * sec_priv;
  void * analog_demod_priv;
  struct dtv_frontend_properties dtv_property_cache;
#define DVB_FRONTEND_COMPONENT_TUNER 0
#define DVB_FRONTEND_COMPONENT_DEMOD 1
  int (* callback) (void *adapter_priv, int component, int cmd, int arg);
  int id;
  unsigned int exit;
};

Members

refcount
refcount to keep track of struct dvb_frontend references
ops
embedded struct dvb_frontend_ops
dvb
pointer to struct dvb_adapter
demodulator_priv
demod private data
tuner_priv
tuner private data
frontend_priv
frontend private data
sec_priv
SEC private data
analog_demod_priv
Analog demod private data
dtv_property_cache
embedded struct dtv_frontend_properties
callback
callback function used on some drivers to call either the tuner or the demodulator.
id
Frontend ID
exit
Used to inform the DVB core that the frontend thread should exit (usually, means that the hardware got disconnected.
int dvb_register_frontend(struct dvb_adapter * dvb, struct dvb_frontend * fe)

Registers a DVB frontend at the adapter

Parameters

struct dvb_adapter * dvb
pointer to the dvb adapter
struct dvb_frontend * fe
pointer to the frontend struct

Description

Allocate and initialize the private data needed by the frontend core to manage the frontend and calls dvb_register_device() to register a new frontend. It also cleans the property cache that stores the frontend parameters and selects the first available delivery system.

int dvb_unregister_frontend(struct dvb_frontend * fe)

Unregisters a DVB frontend

Parameters

struct dvb_frontend * fe
pointer to the frontend struct

Description

Stops the frontend kthread, calls dvb_unregister_device() and frees the private frontend data allocated by dvb_register_frontend().

NOTE

This function doesn’t frees the memory allocated by the demod, by the SEC driver and by the tuner. In order to free it, an explicit call to dvb_frontend_detach() is needed, after calling this function.

void dvb_frontend_detach(struct dvb_frontend * fe)

Detaches and frees frontend specific data

Parameters

struct dvb_frontend * fe
pointer to the frontend struct

Description

This function should be called after dvb_unregister_frontend(). It calls the SEC, tuner and demod release functions: dvb_frontend_ops.release_sec, dvb_frontend_ops.tuner_ops.release, dvb_frontend_ops.analog_ops.release and dvb_frontend_ops.release.

If the driver is compiled with CONFIG_MEDIA_ATTACH, it also decreases the module reference count, needed to allow userspace to remove the previously used DVB frontend modules.

int dvb_frontend_suspend(struct dvb_frontend * fe)

Suspends a Digital TV frontend

Parameters

struct dvb_frontend * fe
pointer to the frontend struct

Description

This function prepares a Digital TV frontend to suspend.

In order to prepare the tuner to suspend, if dvb_frontend_ops.tuner_ops.suspend() is available, it calls it. Otherwise, it will call dvb_frontend_ops.tuner_ops.sleep(), if available.

It will also call dvb_frontend_ops.sleep() to put the demod to suspend.

The drivers should also call dvb_frontend_suspend() as part of their handler for the device_driver.suspend().

int dvb_frontend_resume(struct dvb_frontend * fe)

Resumes a Digital TV frontend

Parameters

struct dvb_frontend * fe
pointer to the frontend struct

Description

This function resumes the usual operation of the tuner after resume.

In order to resume the frontend, it calls the demod dvb_frontend_ops.init().

If dvb_frontend_ops.tuner_ops.resume() is available, It, it calls it. Otherwise,t will call dvb_frontend_ops.tuner_ops.init(), if available.

Once tuner and demods are resumed, it will enforce that the SEC voltage and tone are restored to their previous values and wake up the frontend’s kthread in order to retune the frontend.

The drivers should also call dvb_frontend_resume() as part of their handler for the device_driver.resume().

void dvb_frontend_reinitialise(struct dvb_frontend * fe)

forces a reinitialisation at the frontend

Parameters

struct dvb_frontend * fe
pointer to the frontend struct

Description

Calls dvb_frontend_ops.init() and dvb_frontend_ops.tuner_ops.init(), and resets SEC tone and voltage (for Satellite systems).

NOTE

Currently, this function is used only by one driver (budget-av). It seems to be due to address some special issue with that specific frontend.

void dvb_frontend_sleep_until(ktime_t * waketime, u32 add_usec)

Sleep for the amount of time given by add_usec parameter

Parameters

ktime_t * waketime
pointer to a struct ktime_t
u32 add_usec
time to sleep, in microseconds

Description

This function is used to measure the time required for the FE_DISHNETWORK_SEND_LEGACY_CMD ioctl to work. It needs to be as precise as possible, as it affects the detection of the dish tone command at the satellite subsystem.

Its used internally by the DVB frontend core, in order to emulate FE_DISHNETWORK_SEND_LEGACY_CMD using the dvb_frontend_ops.set_voltage() callback.

NOTE

it should not be used at the drivers, as the emulation for the legacy callback is provided by the Kernel. The only situation where this should be at the drivers is when there are some bugs at the hardware that would prevent the core emulation to work. On such cases, the driver would be writing a dvb_frontend_ops.dishnetwork_send_legacy_command() and calling this function directly.

6. Digital TV Demux kABI

6.1. Digital TV Demux

The Kernel Digital TV Demux kABI defines a driver-internal interface for registering low-level, hardware specific driver to a hardware independent demux layer. It is only of interest for Digital TV device driver writers. The header file for this kABI is named demux.h and located in drivers/media/dvb-core.

The demux kABI should be implemented for each demux in the system. It is used to select the TS source of a demux and to manage the demux resources. When the demux client allocates a resource via the demux kABI, it receives a pointer to the kABI of that resource.

Each demux receives its TS input from a DVB front-end or from memory, as set via this demux kABI. In a system with more than one front-end, the kABI can be used to select one of the DVB front-ends as a TS source for a demux, unless this is fixed in the HW platform.

The demux kABI only controls front-ends regarding to their connections with demuxes; the kABI used to set the other front-end parameters, such as tuning, are devined via the Digital TV Frontend kABI.

The functions that implement the abstract interface demux should be defined static or module private and registered to the Demux core for external access. It is not necessary to implement every function in the struct &dmx_demux. For example, a demux interface might support Section filtering, but not PES filtering. The kABI client is expected to check the value of any function pointer before calling the function: the value of NULL means that the function is not available.

Whenever the functions of the demux API modify shared data, the possibilities of lost update and race condition problems should be addressed, e.g. by protecting parts of code with mutexes.

Note that functions called from a bottom half context must not sleep. Even a simple memory allocation without using GFP_ATOMIC can result in a kernel thread being put to sleep if swapping is needed. For example, the Linux Kernel calls the functions of a network device interface from a bottom half context. Thus, if a demux kABI function is called from network device code, the function must not sleep.

7. Demux Callback API

7.1. Demux Callback

This kernel-space API comprises the callback functions that deliver filtered data to the demux client. Unlike the other DVB kABIs, these functions are provided by the client and called from the demux code.

The function pointers of this abstract interface are not packed into a structure as in the other demux APIs, because the callback functions are registered and used independent of each other. As an example, it is possible for the API client to provide several callback functions for receiving TS packets and no callbacks for PES packets or sections.

The functions that implement the callback API need not be re-entrant: when a demux driver calls one of these functions, the driver is not allowed to call the function again before the original call returns. If a callback is triggered by a hardware interrupt, it is recommended to use the Linux bottom half mechanism or start a tasklet instead of making the callback function call directly from a hardware interrupt.

This mechanism is implemented by dmx_ts_cb() and dmx_section_cb() callbacks.

Error

kernel-doc missing

8. Digital TV Conditional Access kABI

struct dvb_ca_en50221

Structure describing a CA interface

Definition

struct dvb_ca_en50221 {
  struct module * owner;
  int (* read_attribute_mem) (struct dvb_ca_en50221 *ca,int slot, int address);
  int (* write_attribute_mem) (struct dvb_ca_en50221 *ca,int slot, int address, u8 value);
  int (* read_cam_control) (struct dvb_ca_en50221 *ca,int slot, u8 address);
  int (* write_cam_control) (struct dvb_ca_en50221 *ca,int slot, u8 address, u8 value);
  int (* slot_reset) (struct dvb_ca_en50221 *ca, int slot);
  int (* slot_shutdown) (struct dvb_ca_en50221 *ca, int slot);
  int (* slot_ts_enable) (struct dvb_ca_en50221 *ca, int slot);
  int (* poll_slot_status) (struct dvb_ca_en50221 *ca, int slot, int open);
  void * data;
  void * private;
};

Members

owner
the module owning this structure
read_attribute_mem
function for reading attribute memory on the CAM
write_attribute_mem
function for writing attribute memory on the CAM
read_cam_control
function for reading the control interface on the CAM
write_cam_control
function for reading the control interface on the CAM
slot_reset
function to reset the CAM slot
slot_shutdown
function to shutdown a CAM slot
slot_ts_enable
function to enable the Transport Stream on a CAM slot
poll_slot_status
function to poll slot status. Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set.
data
private data, used by caller.
private
Opaque data used by the dvb_ca core. Do not modify!

NOTE

the read_*, write_* and poll_slot_status functions will be called for different slots concurrently and need to use locks where and if appropriate. There will be no concurrent access to one slot.

void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 * pubca, int slot, int change_type)

A CAMCHANGE IRQ has occurred.

Parameters

struct dvb_ca_en50221 * pubca
CA instance.
int slot
Slot concerned.
int change_type
One of the DVB_CA_CAMCHANGE_* values
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 * pubca, int slot)

A CAMREADY IRQ has occurred.

Parameters

struct dvb_ca_en50221 * pubca
CA instance.
int slot
Slot concerned.
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 * ca, int slot)

An FR or a DA IRQ has occurred.

Parameters

struct dvb_ca_en50221 * ca
CA instance.
int slot
Slot concerned.
int dvb_ca_en50221_init(struct dvb_adapter * dvb_adapter, struct dvb_ca_en50221 * ca, int flags, int slot_count)

Initialise a new DVB CA device.

Parameters

struct dvb_adapter * dvb_adapter
DVB adapter to attach the new CA device to.
struct dvb_ca_en50221 * ca
The dvb_ca instance.
int flags
Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
int slot_count
Number of slots supported.

Description

return 0 on success, nonzero on failure

void dvb_ca_en50221_release(struct dvb_ca_en50221 * ca)

Release a DVB CA device.

Parameters

struct dvb_ca_en50221 * ca
The associated dvb_ca instance.