# 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;
const char * name;
u8 proposed_mac[6];
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;
#endif
};
```

Members

`num`
`list_head`
`device_list`
List with the DVB devices
`name`
`proposed_mac[6]`
`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 {
const struct file_operations * fops;
int type;
int minor;
u32 id;
int writers;
int users;
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;
#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)

Parameters

`struct dvb_adapter * adap`
`const char * 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)

Parameters

`struct dvb_adapter * adap`
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`
`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_unregister_device`(struct dvb_device * dvbdev)

Unregisters a DVB device

Parameters

`struct dvb_device * dvbdev`
pointer to struct dvb_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`
`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.

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

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

Parameters

`struct dvb_adapter * adap`
`const char * 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)

Parameters

`struct dvb_adapter * adap`
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`
`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_unregister_device`(struct dvb_device * dvbdev)

Unregisters a DVB device

Parameters

`struct dvb_device * dvbdev`
pointer to struct dvb_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`
`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 pwrite;
int error;
spinlock_t lock;
};
```

Members

`data`
Area were the ringbuffer data is written
`size`
size of the ringbuffer
`pread`
`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)

Parameters

`rbuf`
pointer to struct dvb_ringbuffer
`num`
ssize_t `dvb_ringbuffer_read_user`(struct dvb_ringbuffer * rbuf, u8 __user * buf, size_t len)

Reads a buffer into an 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 an 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`

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[128];
u32 frequency_min;
u32 frequency_max;
u32 frequency_step;
u32 bandwidth_min;
u32 bandwidth_max;
u32 bandwidth_step;
};
```

Members

`name[128]`
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;
int (* 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[MAX_DELSYS];
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_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[MAX_DELSYS]`
Delivery systems supported by the frontend
`release`
callback function called when frontend is dettached. 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[3];
u32 stream_id;
u8 atscmh_fic_ver;
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[3]`
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`
`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`
`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 dvb_frontend_ops ops;
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

`ops`
embedded struct dvb_frontend_ops
`dvb`
`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`
`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.

enum `ts_filter_type`

filter type bitmap for dmx_ts_feed.set()

Constants

`TS_PACKET`
Send TS packets (188 bytes) to callback (default).
`TS_PAYLOAD_ONLY`
In case TS_PACKET is set, only send the TS payload (<=184 bytes per packet) to callback
`TS_DECODER`
Send stream to built-in decoder (if present).
`TS_DEMUX`
In case TS_PACKET is set, send the TS to the demux device, not to the dvr device
struct `dmx_ts_feed`

Structure that contains a TS feed filter

Definition

```struct dmx_ts_feed {
int is_filtering;
struct dmx_demux * parent;
void * priv;
int (* set) (struct dmx_ts_feed *feed,u16 pid,int type,enum dmx_ts_pes pes_type,size_t circular_buffer_size,ktime_t timeout);
int (* start_filtering) (struct dmx_ts_feed *feed);
int (* stop_filtering) (struct dmx_ts_feed *feed);
};
```

Members

`is_filtering`
Set to non-zero when filtering in progress
`parent`
pointer to struct dmx_demux
`priv`
pointer to private data of the API client
`set`
sets the TS filter
`start_filtering`
starts TS filtering
`stop_filtering`
stops TS filtering

Description

A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this API, the client can set the filtering properties to start/stop filtering TS packets on a particular TS feed.

struct `dmx_section_filter`

Structure that describes a section filter

Definition

```struct dmx_section_filter {
u8 filter_value[DMX_MAX_FILTER_SIZE];
u8 filter_mode[DMX_MAX_FILTER_SIZE];
struct dmx_section_feed * parent;
void * priv;
};
```

Members

`filter_value[DMX_MAX_FILTER_SIZE]`
Contains up to 16 bytes (128 bits) of the TS section header that will be matched by the section filter
`filter_mask[DMX_MAX_FILTER_SIZE]`
Contains a 16 bytes (128 bits) filter mask with the bits specified by filter_value that will be used on the filter match logic.
`filter_mode[DMX_MAX_FILTER_SIZE]`
Contains a 16 bytes (128 bits) filter mode.
`parent`
Pointer to struct dmx_section_feed.
`priv`
Pointer to private data of the API client.

Description

The filter_mask controls which bits of filter_value are compared with the section headers/payload. On a binary value of 1 in filter_mask, the corresponding bits are compared. The filter only accepts sections that are equal to filter_value in all the tested bit positions.

struct `dmx_section_feed`

Structure that contains a section feed filter

Definition

```struct dmx_section_feed {
int is_filtering;
struct dmx_demux * parent;
void * priv;
int check_crc;
int (* set) (struct dmx_section_feed *feed,u16 pid,size_t circular_buffer_size,int check_crc);
int (* allocate_filter) (struct dmx_section_feed *feed,struct dmx_section_filter **filter);
int (* release_filter) (struct dmx_section_feed *feed,struct dmx_section_filter *filter);
int (* start_filtering) (struct dmx_section_feed *feed);
int (* stop_filtering) (struct dmx_section_feed *feed);
};
```

Members

`is_filtering`
Set to non-zero when filtering in progress
`parent`
pointer to struct dmx_demux
`priv`
pointer to private data of the API client
`check_crc`
If non-zero, check the CRC values of filtered sections.
`set`
sets the section filter
`allocate_filter`
This function is used to allocate a section filter on the demux. It should only be called when no filtering is in progress on this section feed. If a filter cannot be allocated, the function fails with -ENOSPC.
`release_filter`
This function releases all the resources of a previously allocated section filter. The function should not be called while filtering is in progress on this section feed. After calling this function, the caller should not try to dereference the filter pointer.
`start_filtering`
starts section filtering
`stop_filtering`
stops section filtering

Description

A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this API, the client can set the filtering properties to start/stop filtering TS packets on a particular TS feed.

`dmx_ts_cb`

Typedef: DVB demux TS filter callback function prototype

Syntax

`int dmx_ts_cb (const u8 * buffer1, size_t buffer1_length, const u8 * buffer2, size_t buffer2_length, struct dmx_ts_feed * source);`

Parameters

`const u8 * buffer1`
Pointer to the start of the filtered TS packets.
`size_t buffer1_length`
Length of the TS data in buffer1.
`const u8 * buffer2`
Pointer to the tail of the filtered TS packets, or NULL.
`size_t buffer2_length`
Length of the TS data in buffer2.
`struct dmx_ts_feed * source`
Indicates which TS feed is the source of the callback.

Description

This function callback prototype, provided by the client of the demux API, is called from the demux code. The function is only called when filtering on a TS feed has been enabled using the start_filtering() function at the `dmx_demux`. Any TS packets that match the filter settings are copied to a circular buffer. The filtered TS packets are delivered to the client using this callback function. The size of the circular buffer is controlled by the circular_buffer_size parameter of the `dmx_ts_feed`.**set** function. It is expected that the buffer1 and buffer2 callback parameters point to addresses within the circular buffer, but other implementations are also possible. Note that the called party should not try to free the memory the buffer1 and buffer2 parameters point to.

When this function is called, the buffer1 parameter typically points to the start of the first undelivered TS packet within a circular buffer. The buffer2 buffer parameter is normally NULL, except when the received TS packets have crossed the last address of the circular buffer and ”wrapped” to the beginning of the buffer. In the latter case the buffer1 parameter would contain an address within the circular buffer, while the buffer2 parameter would contain the first address of the circular buffer. The number of bytes delivered with this function (i.e. buffer1_length + buffer2_length) is usually equal to the value of callback_length parameter given in the `set()` function, with one exception: if a timeout occurs before receiving callback_length bytes of TS data, any undelivered packets are immediately delivered to the client by calling this function. The timeout duration is controlled by the `set()` function in the TS Feed API.

If a TS packet is received with errors that could not be fixed by the TS-level forward error correction (FEC), the Transport_error_indicator flag of the TS packet header should be set. The TS packet should not be discarded, as the error can possibly be corrected by a higher layer protocol. If the called party is slow in processing the callback, it is possible that the circular buffer eventually fills up. If this happens, the demux driver should discard any TS packets received while the buffer is full and return -EOVERFLOW.

The type of data returned to the callback can be selected by the `dmx_ts_feed`.**set** function. The type parameter decides if the raw TS packet (TS_PACKET) or just the payload (TS_PACKET|TS_PAYLOAD_ONLY) should be returned. If additionally the TS_DECODER bit is set the stream will also be sent to the hardware MPEG decoder.

Return

• 0, on success;
• -EOVERFLOW, on buffer overflow.
`dmx_section_cb`

Typedef: DVB demux TS filter callback function prototype

Syntax

`int dmx_section_cb (const u8 * buffer1, size_t buffer1_len, const u8 * buffer2, size_t buffer2_len, struct dmx_section_filter * source);`

Parameters

`const u8 * buffer1`
Pointer to the start of the filtered section, e.g. within the circular buffer of the demux driver.
`size_t buffer1_len`
Length of the filtered section data in buffer1, including headers and CRC.
`const u8 * buffer2`
Pointer to the tail of the filtered section data, or NULL. Useful to handle the wrapping of a circular buffer.
`size_t buffer2_len`
Length of the filtered section data in buffer2, including headers and CRC.
`struct dmx_section_filter * source`
Indicates which section feed is the source of the callback.

Description

This function callback prototype, provided by the client of the demux API, is called from the demux code. The function is only called when filtering of sections has been enabled using the function `dmx_ts_feed`.**start_filtering**. When the demux driver has received a complete section that matches at least one section filter, the client is notified via this callback function. Normally this function is called for each received section; however, it is also possible to deliver multiple sections with one callback, for example when the system load is high. If an error occurs while receiving a section, this function should be called with the corresponding error type set in the success field, whether or not there is data to deliver. The Section Feed implementation should maintain a circular buffer for received sections. However, this is not necessary if the Section Feed API is implemented as a client of the TS Feed API, because the TS Feed implementation then buffers the received data. The size of the circular buffer can be configured using the `dmx_ts_feed`.**set** function in the Section Feed API. If there is no room in the circular buffer when a new section is received, the section must be discarded. If this happens, the value of the success parameter should be DMX_OVERRUN_ERROR on the next callback.

enum `dmx_frontend_source`

Used to identify the type of frontend

Constants

`DMX_MEMORY_FE`
The source of the demux is memory. It means that the MPEG-TS to be filtered comes from userspace, via `write()` syscall.
`DMX_FRONTEND_0`
The source of the demux is a frontend connected to the demux.
struct `dmx_frontend`

Structure that lists the frontends associated with a demux

Definition

```struct dmx_frontend {
enum dmx_frontend_source source;
};
```

Members

`connectivity_list`
List of front-ends that can be connected to a particular demux;
`source`
Type of the frontend.

Description

FIXME: this structure should likely be replaced soon by some
media-controller based logic.
enum `dmx_demux_caps`

MPEG-2 TS Demux capabilities bitmap

Constants

`DMX_TS_FILTERING`
set if TS filtering is supported;
`DMX_SECTION_FILTERING`
set if section filtering is supported;
`DMX_MEMORY_BASED_FILTERING`
set if `write()` available.

Description

Those flags are OR’ed in the `dmx_demux.capabilities` field

`DMX_FE_ENTRY`(list)

Casts elements in the list of registered front-ends from the generic type struct list_head to the type * struct dmx_frontend

Parameters

`list`
list of struct dmx_frontend
struct `dmx_demux`

Structure that contains the demux capabilities and callbacks.

Definition

```struct dmx_demux {
enum dmx_demux_caps capabilities;
struct dmx_frontend * frontend;
void * priv;
int (* open) (struct dmx_demux *demux);
int (* close) (struct dmx_demux *demux);
int (* write) (struct dmx_demux *demux, const char __user *buf,size_t count);
int (* allocate_ts_feed) (struct dmx_demux *demux,struct dmx_ts_feed **feed,dmx_ts_cb callback);
int (* release_ts_feed) (struct dmx_demux *demux,struct dmx_ts_feed *feed);
int (* allocate_section_feed) (struct dmx_demux *demux,struct dmx_section_feed **feed,dmx_section_cb callback);
int (* release_section_feed) (struct dmx_demux *demux,struct dmx_section_feed *feed);
int (* add_frontend) (struct dmx_demux *demux,struct dmx_frontend *frontend);
int (* remove_frontend) (struct dmx_demux *demux,struct dmx_frontend *frontend);
struct list_head *(* get_frontends) (struct dmx_demux *demux);
int (* connect_frontend) (struct dmx_demux *demux,struct dmx_frontend *frontend);
int (* disconnect_frontend) (struct dmx_demux *demux);
int (* get_pes_pids) (struct dmx_demux *demux, u16 *pids);
};
```

Members

`capabilities`
Bitfield of capability flags.
`frontend`
Front-end connected to the demux
`priv`
Pointer to private data of the API client
`open`
This function reserves the demux for use by the caller and, if necessary, initializes the demux. When the demux is no longer needed, the function close should be called. It should be possible for multiple clients to access the demux at the same time. Thus, the function implementation should increment the demux usage count when open is called and decrement it when close is called. The demux function parameter contains a pointer to the demux API and instance data. It returns: 0 on success; -EUSERS, if maximum usage count was reached; -EINVAL, on bad parameter.
`close`
This function reserves the demux for use by the caller and, if necessary, initializes the demux. When the demux is no longer needed, the function close should be called. It should be possible for multiple clients to access the demux at the same time. Thus, the function implementation should increment the demux usage count when open is called and decrement it when close is called. The demux function parameter contains a pointer to the demux API and instance data. It returns: 0 on success; -ENODEV, if demux was not in use (e. g. no users); -EINVAL, on bad parameter.
`write`
This function provides the demux driver with a memory buffer containing TS packets. Instead of receiving TS packets from the DVB front-end, the demux driver software will read packets from memory. Any clients of this demux with active TS, PES or Section filters will receive filtered data via the Demux callback API (see 0). The function returns when all the data in the buffer has been consumed by the demux. Demux hardware typically cannot read TS from memory. If this is the case, memory-based filtering has to be implemented entirely in software. The demux function parameter contains a pointer to the demux API and instance data. The buf function parameter contains a pointer to the TS data in kernel-space memory. The count function parameter contains the length of the TS data. It returns: 0 on success; -ERESTARTSYS, if mutex lock was interrupted; -EINTR, if a signal handling is pending; -ENODEV, if demux was removed; -EINVAL, on bad parameter.
`allocate_ts_feed`
Allocates a new TS feed, which is used to filter the TS packets carrying a certain PID. The TS feed normally corresponds to a hardware PID filter on the demux chip. The demux function parameter contains a pointer to the demux API and instance data. The feed function parameter contains a pointer to the TS feed API and instance data. The callback function parameter contains a pointer to the callback function for passing received TS packet. It returns: 0 on success; -ERESTARTSYS, if mutex lock was interrupted; -EBUSY, if no more TS feeds is available; -EINVAL, on bad parameter.
`release_ts_feed`
Releases the resources allocated with allocate_ts_feed. Any filtering in progress on the TS feed should be stopped before calling this function. The demux function parameter contains a pointer to the demux API and instance data. The feed function parameter contains a pointer to the TS feed API and instance data. It returns: 0 on success; -EINVAL on bad parameter.
`allocate_section_feed`
Allocates a new section feed, i.e. a demux resource for filtering and receiving sections. On platforms with hardware support for section filtering, a section feed is directly mapped to the demux HW. On other platforms, TS packets are first PID filtered in hardware and a hardware section filter then emulated in software. The caller obtains an API pointer of type dmx_section_feed_t as an out parameter. Using this API the caller can set filtering parameters and start receiving sections. The demux function parameter contains a pointer to the demux API and instance data. The feed function parameter contains a pointer to the TS feed API and instance data. The callback function parameter contains a pointer to the callback function for passing received TS packet. It returns: 0 on success; -EBUSY, if no more TS feeds is available; -EINVAL, on bad parameter.
`release_section_feed`
Releases the resources allocated with allocate_section_feed, including allocated filters. Any filtering in progress on the section feed should be stopped before calling this function. The demux function parameter contains a pointer to the demux API and instance data. The feed function parameter contains a pointer to the TS feed API and instance data. It returns: 0 on success; -EINVAL, on bad parameter.
`add_frontend`
Registers a connectivity between a demux and a front-end, i.e., indicates that the demux can be connected via a call to connect_frontend to use the given front-end as a TS source. The client of this function has to allocate dynamic or static memory for the frontend structure and initialize its fields before calling this function. This function is normally called during the driver initialization. The caller must not free the memory of the frontend struct before successfully calling remove_frontend. The demux function parameter contains a pointer to the demux API and instance data. The frontend function parameter contains a pointer to the front-end instance data. It returns: 0 on success; -EINVAL, on bad parameter.
`remove_frontend`
Indicates that the given front-end, registered by a call to add_frontend, can no longer be connected as a TS source by this demux. The function should be called when a front-end driver or a demux driver is removed from the system. If the front-end is in use, the function fails with the return value of -EBUSY. After successfully calling this function, the caller can free the memory of the frontend struct if it was dynamically allocated before the add_frontend operation. The demux function parameter contains a pointer to the demux API and instance data. The frontend function parameter contains a pointer to the front-end instance data. It returns: 0 on success; -ENODEV, if the front-end was not found, -EINVAL, on bad parameter.
`get_frontends`
Provides the APIs of the front-ends that have been registered for this demux. Any of the front-ends obtained with this call can be used as a parameter for connect_frontend. The include file demux.h contains the macro `DMX_FE_ENTRY()` for converting an element of the generic type struct `list_head` * to the type struct `dmx_frontend` . The caller must not free the memory of any of the elements obtained via this function call. The **demux* function parameter contains a pointer to the demux API and instance data. It returns a struct list_head pointer to the list of front-end interfaces, or NULL in the case of an empty list.
`connect_frontend`
Connects the TS output of the front-end to the input of the demux. A demux can only be connected to a front-end registered to the demux with the function add_frontend. It may or may not be possible to connect multiple demuxes to the same front-end, depending on the capabilities of the HW platform. When not used, the front-end should be released by calling disconnect_frontend. The demux function parameter contains a pointer to the demux API and instance data. The frontend function parameter contains a pointer to the front-end instance data. It returns: 0 on success; -EINVAL, on bad parameter.
`disconnect_frontend`
Disconnects the demux and a front-end previously connected by a connect_frontend call. The demux function parameter contains a pointer to the demux API and instance data. It returns: 0 on success; -EINVAL on bad parameter.
`get_pes_pids`
Get the PIDs for DMX_PES_AUDIO0, DMX_PES_VIDEO0, DMX_PES_TELETEXT0, DMX_PES_SUBTITLE0 and DMX_PES_PCR0. The demux function parameter contains a pointer to the demux API and instance data. The pids function parameter contains an array with five u16 elements where the PIDs will be stored. It returns: 0 on success; -EINVAL on bad parameter.

# 8. Digital TV Conditional Access kABI¶

struct `dvb_ca_en50221`

Structure describing a CA interface

Definition

```struct dvb_ca_en50221 {
struct module * owner;
int (* write_attribute_mem) (struct dvb_ca_en50221 *ca,int slot, int address, u8 value);
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)

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.