3.2. 數字電視前端kABI

3.2.1. 數字電視前端

數字電視前端kABI定義了一個驅動程式內部介面,用於將底層、硬體特定的驅動程式註冊到與硬體無關的前端層。它僅對數字電視裝置驅動程式編寫者感興趣。此API的標頭檔案名為dvb_frontend.h,位於include/media/中。

3.2.1.1. 解調器驅動程式

解調器驅動程式負責與硬體的解碼部分通訊。此類驅動程式應實現dvb_frontend_ops,該結構告訴支援哪種型別的數字電視標準,並指向一系列函式,這些函式允許DVB核心透過include/media/dvb_frontend.c下的程式碼來控制硬體。

驅動程式foo中此類結構的典型示例是

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

驅動程式bar中此類結構的典型示例,旨在用於衛星電視接收是

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

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

注意

  1. 對於衛星數字電視標準(DVB-S、DVB-S2、ISDB-S),頻率以kHz為單位指定,而對於地面和有線標準,頻率以Hz為單位指定。因此,如果同一前端支援這兩種型別,則需要有兩個單獨的dvb_frontend_ops結構,每種標準一個。

  2. 僅當硬體允許控制I2C門(直接或透過某些GPIO引腳)時,才存在.i2c_gate_ctrl欄位,以便在調整頻道後從I2C總線上移除調諧器。

  3. 所有新驅動程式都應透過.read_status實現DVBv5統計資訊。然而,有許多回調旨在獲取訊號強度、S/N和UCB的統計資訊。它們的存在是為了提供與不支援DVBv5 API的舊版應用程式的向後相容性。實現這些回撥是可選的。在我們讓所有現有驅動程式都支援DVBv5統計資訊之後,這些回撥可能會在將來被刪除。

  4. 為了控制LNBf和DiSEqC,衛星電視標準需要其他回撥:.diseqc_send_master_cmd.diseqc_send_burst.set_tone.set_voltage

include/media/dvb_frontend.c有一個核心執行緒,負責調諧裝置。它支援多種演算法來檢測頻道,如enum dvbfe_algo()中定義的那樣。

要使用的演算法透過.get_frontend_algo獲得。如果驅動程式沒有在struct dvb_frontend_ops中填寫其欄位,它將預設為DVBFE_ALGO_SW,這意味著dvb-core在調諧時會做一個鋸齒形,例如,它將首先嚐試使用指定的中心頻率f,然後,它將執行f + Δ、f - Δ、f + 2 x Δ、f - 2 x Δ等等。

如果硬體內部有一些鋸齒形演算法,則應定義一個.get_frontend_algo函式,該函式將返回DVBFE_ALGO_HW

注意

核心前端支援還支援第三種類型(DVBFE_ALGO_CUSTOM),以便允許驅動程式定義自己的硬體輔助演算法。現在很少有硬體需要使用它。使用DVBFE_ALGO_CUSTOM需要在struct dvb_frontend_ops中提供其他函式回撥。

3.2.1.2. 將前端驅動程式附加到橋驅動程式

在使用數字電視前端核心之前,橋驅動程式應附加前端解調器、調諧器和SEC裝置,並呼叫dvb_register_frontend(),以便在子系統註冊新的前端。在裝置分離/移除時,橋驅動程式應呼叫dvb_unregister_frontend()以從核心移除前端,然後呼叫dvb_frontend_detach()以釋放前端驅動程式分配的記憶體。

驅動程式還應呼叫dvb_frontend_suspend()作為其處理程式device_driver.suspend()的一部分,並呼叫dvb_frontend_resume()作為其處理程式device_driver.resume()的一部分。

提供了一些其他可選函式來處理一些特殊情況。

3.2.2. 數字電視前端統計資訊

3.2.2.1. 簡介

數字電視前端提供了一系列統計資訊,旨在幫助調諧裝置和測量服務質量。

對於每個統計資訊測量,驅動程式應設定使用的比例型別,或者如果給定的時間沒有統計資訊,則設定為FE_SCALE_NOT_AVAILABLE。驅動程式還應提供每種型別的統計資訊數量。對於大多數影片標準,這通常為1[1]

驅動程式應在其初始化程式碼中使用長度和比例初始化每個統計資訊計數器。例如,如果前端提供訊號強度,則應在其初始化程式碼中具有

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

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

並且,當統計資訊更新時,設定比例

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

注意

對於訊號強度和CNR測量,請首選使用FE_SCALE_DECIBEL而不是FE_SCALE_RELATIVE

3.2.2.2. 統計資訊組

目前支援幾個統計資訊組

訊號強度(DTV_STAT_SIGNAL_STRENGTH
  • 測量調諧器或解調器模擬部分的訊號強度級別。

  • 通常從應用於調諧器和/或前端以檢測載波的增益獲得。當未檢測到載波時,增益處於最大值(因此,強度處於最小值)。

  • 由於增益透過調整增益的暫存器集可見,因此通常此統計資訊始終可用[2]

  • 驅動程式應嘗試始終使其可用,因為這些統計資訊可用於調整天線位置並檢查佈線問題。

載波訊號噪聲比(DTV_STAT_CNR
  • 主載波的訊號噪聲比。

  • 訊號噪聲測量取決於裝置。在某些硬體上,當檢測到主載波時,它可以可用。在這些硬體上,CNR測量通常來自調諧器(例如,在FE_HAS_CARRIER之後,請參閱fe_status)。

    在其他裝置上,它需要內部FEC解碼,因為前端從其他引數間接測量它(例如,在FE_HAS_VITERBI之後,請參閱fe_status)。

    在內部FEC之後可用更為常見。

FEC後的位元計數(DTV_STAT_POST_ERROR_BIT_COUNTDTV_STAT_POST_TOTAL_BIT_COUNT
  • 這些計數器測量內部編碼塊(在Viterbi、LDPC或其他內部程式碼之後)上的前向糾錯(FEC)之後的位元數和位元錯誤數。

  • 由於其性質,這些統計資訊取決於完全編碼鎖定(例如,在FE_HAS_SYNC之後或在FE_HAS_LOCK之後,請參閱fe_status)。

FEC前的位元計數(DTV_STAT_PRE_ERROR_BIT_COUNTDTV_STAT_PRE_TOTAL_BIT_COUNT
  • 這些計數器測量內部編碼塊(在Viterbi、LDPC或其他內部程式碼之前)上的前向糾錯(FEC)之前的位元數和位元錯誤數。

  • 並非所有前端都提供此類統計資訊。

  • 由於其性質,這些統計資訊取決於內部編碼鎖定(例如,在FE_HAS_VITERBI之後,請參閱fe_status)。

塊計數(DTV_STAT_ERROR_BLOCK_COUNTDTV-STAT_TOTAL_BLOCK_COUNT
  • 這些計數器測量內部編碼塊(在Viterbi、LDPC或其他內部程式碼之前)上的前向糾錯(FEC)之後的塊數和塊錯誤數。

  • 由於其性質,這些統計資訊取決於完全編碼鎖定(例如,在FE_HAS_SYNC之後或在FE_HAS_LOCK之後,請參閱fe_status)。

注意

所有計數器都應隨著從硬體收集而單調遞增。

處理狀態和統計資訊的典型邏輯示例是

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

        int rc;
        enum fe_status *status;

        /* Both status and strength are always available */
        rc = foo_read_status(fe, &status);
        if (rc < 0)
                return rc;

        rc = foo_read_strength(fe);
        if (rc < 0)
                return rc;

        /* Check if CNR is available */
        if (!(fe->status & FE_HAS_CARRIER))
                return 0;

        rc = foo_read_cnr(fe);
        if (rc < 0)
                return rc;

        /* Check if pre-BER stats are available */
        if (!(fe->status & FE_HAS_VITERBI))
                return 0;

        rc = foo_get_pre_ber(fe);
        if (rc < 0)
                return rc;

        /* Check if post-BER stats are available */
        if (!(fe->status & FE_HAS_SYNC))
                return 0;

        rc = foo_get_post_ber(fe);
        if (rc < 0)
                return rc;
}

static const struct dvb_frontend_ops ops = {
        /* ... */
        .read_status = foo_get_status_and_stats,
};

3.2.2.3. 統計資訊收集

在幾乎所有前端硬體上,位元和位元組計數都由硬體在一段時間後或在總位元/塊計數器達到某個值(通常可程式設計)後儲存,例如,每1000毫秒或在接收到1,000,000位元後。

因此,如果過早讀取暫存器,最終會讀取與前一次讀取相同的值,導致單調值過於頻繁地遞增。

驅動程式應負責避免過於頻繁的讀取。這可以使用兩種方法完成

3.2.2.3.1. 如果驅動程式有一個指示何時準備好收集資料的位元

驅動程式應在提供統計資訊之前檢查該位元。

在此程式碼片段(改編自mb86a20s驅動程式的邏輯)中可以找到這種行為的一個示例

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

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

        if (!rc)
                return 0;

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

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

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

        return 0;
}

3.2.2.3.2. 如果驅動程式不提供統計資訊可用性檢查位元

然而,少數裝置可能不提供檢查統計資訊是否可用的方法(或者檢查它的方法未知)。它們甚至可能不提供直接讀取總位元數或塊數的方法。

在這些裝置上,驅動程式需要確保它不會過於頻繁地從暫存器讀取,並且/或者估計總位元/塊數。

在此類驅動程式上,獲取統計資訊的典型例程將類似於(改編自dib8000驅動程式的邏輯)

struct foo_state {
        /* ... */

        unsigned long per_jiffies_stats;
}

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

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

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

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

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

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

        return 0;
}

請注意,在這兩種情況下,我們都使用dvb_frontend_ops .read_status回撥獲取統計資訊。原因是前端核心會自動定期呼叫此函式(通常,當前端鎖定時,每秒3次)。

這保證了我們不會錯過收集計數器並在正確的時間遞增單調統計資訊。

3.2.3. 數字電視前端函式和型別

struct dvb_frontend_tune_settings

調整前端調諧的引數

定義:

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

成員

min_delay_ms

調諧的最小延遲,以毫秒為單位

step_size

兩個連續頻率之間的步長

max_drift

最大漂移

注意

step_size以Hz為單位(對於地面/有線)或以kHz為單位(對於衛星)

struct dvb_tuner_info

前端名稱和最小/最大範圍/頻寬

定義:

struct dvb_tuner_info {
    char name[128];
    u32 frequency_min_hz;
    u32 frequency_max_hz;
    u32 frequency_step_hz;
    u32 bandwidth_min;
    u32 bandwidth_max;
    u32 bandwidth_step;
};

成員

name

前端的名稱

frequency_min_hz

支援的最小頻率,以Hz為單位

frequency_max_hz

支援的最大頻率,以Hz為單位

frequency_step_hz

頻率步長,以Hz為單位

bandwidth_min

支援的最小前端頻寬

bandwidth_max

支援的最大前端頻寬

bandwidth_step

前端頻寬步長

struct analog_parameters

調諧到模擬/無線電頻道的引數

定義:

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

成員

frequency

模擬電視調諧器使用的頻率(對於電視,步長為62.5 kHz,對於無線電,步長為62.5 Hz)

mode

調諧器模式,如enum v4l2_tuner_type中定義

audmode

音訊模式,如videodev2.h中rxsubchans欄位所定義,例如V4L2_TUNER_MODE_ *

std

電視標準點陣圖,如videodev2.h中定義,例如V4L2_STD_ *

描述

混合調諧器應同時支援 V4L2 和 DVB API。此結構包含 V4L2 端使用的資料。為了避免依賴 V4L2 頭部檔案,此處的所有列舉都宣告為整數。

enum dvbfe_algo

定義用於調諧到頻道的演算法

常量

DVBFE_ALGO_HW

硬體演算法 - 支援此演算法的裝置在硬體中完成所有操作,不需要軟體支援來處理它們。請求這些裝置鎖定是唯一需要的事情,裝置應該在硬體中完成所有事情。

DVBFE_ALGO_SW

軟體演算法 - 這些是“啞”裝置,需要軟體來完成所有操作

DVBFE_ALGO_CUSTOM

可定製演算法 - 具有此演算法的裝置可以進行定製,以便在前端驅動程式中具有特定的演算法,而不是簡單地進行軟體 Z 字形搜尋。在這種情況下,Z 字形搜尋可能是硬體輔助的,或者完全在硬體中完成。在所有情況下,使用此演算法,結合搜尋和跟蹤回撥,將利用驅動程式特定的演算法。

DVBFE_ALGO_RECOVERY

恢復演算法 - 這些裝置具有從鎖定失敗中自動恢復的能力

搜尋回撥可能返回的狀態

常量

DVBFE_ALGO_SEARCH_SUCCESS

前端搜尋演算法已完成併成功返回

DVBFE_ALGO_SEARCH_ASLEEP

前端搜尋演算法正在休眠

DVBFE_ALGO_SEARCH_FAILED

前端搜尋訊號失敗

DVBFE_ALGO_SEARCH_INVALID

前端搜尋演算法可能提供了無效的引數,並且搜尋是無效的

DVBFE_ALGO_SEARCH_AGAIN

前端搜尋演算法被要求再次搜尋

DVBFE_ALGO_SEARCH_ERROR

由於某些錯誤,前端搜尋演算法失敗

struct dvb_tuner_ops

調諧器資訊和回撥

定義:

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);
};

成員

info

嵌入的 struct dvb_tuner_info 結構,包含調諧器屬性

release

前端分離時呼叫的回撥函式。驅動程式應釋放任何已分配的記憶體。

init

用於初始化調諧器裝置的回撥函式。

sleep

用於使調諧器進入睡眠狀態的回撥函式。

suspend

用於通知核心即將掛起的回撥函式。

resume

用於通知核心從掛起狀態恢復的回撥函式。

set_params

用於通知調諧器調諧到數字電影片道的回撥函式。要使用的屬性儲存在 struct dvb_frontend.dtv_property_cache 中。調諧器解調器可以更改引數以反映調諧頻道所需的更改,並更新統計資訊。這是設定調諧器引數的推薦方式,應在新驅動程式中使用。

set_analog_params

用於在混合調諧器上調諧到模擬電影片道的回撥函式。它將 analog_parameters 傳遞給驅動程式。

set_config

用於傳送一些調諧器特定的引數的回撥函式。

get_frequency

獲取實際調諧的頻率

get_bandwidth

獲取低通濾波器使用的頻寬

get_if_frequency

獲取中頻,單位為 Hz。對於基帶,應返回 0。

get_status

返回前端鎖定狀態

get_rf_strength

返回 RF 訊號強度。主要用於支援模擬電視和廣播。數字電視應透過 DVBv5 API (struct dvb_frontend.dtv_property_cache) 報告。

get_afc

僅由模擬電視核心使用。報告由於 AFC 導致的頻率漂移。

calc_regs

用於為簡單調諧器傳遞暫存器資料設定的回撥函式。不應在新驅動程式中使用。

set_frequency

設定新的頻率。不應在新驅動程式中使用。

set_bandwidth

設定新的頻率。不應在新驅動程式中使用。

注意

get_frequencyset_frequency 上使用的頻率對於地面/有線電視以 Hz 為單位,對於衛星電視以 kHz 為單位。

struct analog_demod_info

解調器模擬電視部分的結構體資訊

定義:

struct analog_demod_info {
    char *name;
};

成員

name

模擬電視解調器的名稱

struct analog_demod_ops

模擬電視和廣播的解調資訊和回撥

定義:

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);
};

成員

info

指向 struct analog_demod_info 的指標

set_params

用於通知解調器設定解碼模擬或廣播頻道所需的解調器引數的回撥函式。屬性透過 struct analog_params 傳遞。

has_signal

如果有訊號,則返回 0xffff,否則返回 0。

get_afc

僅由模擬電視核心使用。報告由於 AFC 導致的頻率漂移。

tuner_status

返回調諧器狀態位的回撥函式,例如 TUNER_STATUS_LOCKEDTUNER_STATUS_STEREO

standby

將調諧器設定為待機模式。

release

前端分離時呼叫的回撥函式。驅動程式應釋放任何已分配的記憶體。

i2c_gate_ctrl

控制 I2C 門。較新的驅動程式應改用 I2C 多路複用支援。

set_config

用於傳送一些調諧器特定的引數的回撥函式。

struct dvb_frontend_internal_info

前端屬性和功能

定義:

struct dvb_frontend_internal_info {
    char name[128];
    u32 frequency_min_hz;
    u32 frequency_max_hz;
    u32 frequency_stepsize_hz;
    u32 frequency_tolerance_hz;
    u32 symbol_rate_min;
    u32 symbol_rate_max;
    u32 symbol_rate_tolerance;
    enum fe_caps caps;
};

成員

name

前端名稱

frequency_min_hz

前端支援的最小頻率。

frequency_max_hz

前端支援的最小頻率。

frequency_stepsize_hz

所有頻率都是此值的倍數。

frequency_tolerance_hz

頻率容差。

symbol_rate_min

最小符號率,單位為波特(用於有線/衛星系統)。

symbol_rate_max

最大符號率,單位為波特(用於有線/衛星系統)。

symbol_rate_tolerance

最大符號率容差,單位為 ppm(用於有線/衛星系統)。

caps

前端支援的功能,如 enum fe_caps 中指定。

struct dvb_frontend_ops

數字電視的解調資訊和回撥

定義:

struct dvb_frontend_ops {
    struct dvb_frontend_internal_info info;
    u8 delsys[MAX_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 (*suspend)(struct dvb_frontend *fe);
    int (*resume)(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;
};

成員

info

嵌入的 struct dvb_tuner_info 結構,包含調諧器屬性

delsys

前端支援的傳輸系統

detach

前端分離時呼叫的回撥函式。驅動程式應進行清理,但不要釋放 struct dvb_frontend 分配。

release

前端準備好被釋放時呼叫的回撥函式。驅動程式應釋放任何已分配的記憶體。

release_sec

請求衛星裝置控制 (SEC) 驅動程式釋放並釋放驅動程式分配的任何記憶體的回撥函式。

init

用於初始化調諧器裝置的回撥函式。

sleep

用於使調諧器進入睡眠狀態的回撥函式。

suspend

用於通知核心即將掛起的回撥函式。

resume

用於通知核心從掛起狀態恢復的回撥函式。

write

一些解調器傳統驅動程式使用的回撥函式,允許其他驅動程式將資料寫入其暫存器。不應在新驅動程式中使用。

tune

使用 DVBFE_ALGO_HW 調諧到頻率的解調器驅動程式使用的回撥函式。

get_frontend_algo

返回所需的硬體演算法。

set_frontend

用於通知解調器設定解調數字電影片道的引數的回撥函式。要使用的屬性儲存在 struct dvb_frontend.dtv_property_cache 中。解調器可以更改引數以反映解碼頻道所需的更改,並更新統計資訊。

get_tune_settings

回撥函式

get_frontend

用於通知實際使用的引數的回撥函式。要使用的屬性儲存在 struct dvb_frontend.dtv_property_cache 中,並更新統計資訊。請注意,如果由於 demog 未鎖定而導致統計資訊不可用,則不應返回錯誤程式碼。

read_status

返回前端的鎖定狀態。

read_ber

返回誤位元速率的傳統回撥函式。較新的驅動程式應透過 DVBv5 API 提供此類資訊,例如 set_frontend/get_frontend,僅當需要 DVBv3 API 相容性時才實現此回撥。

read_signal_strength

返回訊號強度的傳統回撥函式。較新的驅動程式應透過 DVBv5 API 提供此類資訊,例如 set_frontend/get_frontend,僅當需要 DVBv3 API 相容性時才實現此回撥。

read_snr

返回信噪比的傳統回撥函式。較新的驅動程式應透過 DVBv5 API 提供此類資訊,例如 set_frontend/get_frontend,僅當需要 DVBv3 API 相容性時才實現此回撥。

read_ucblocks

返回未校正錯誤塊的傳統回撥函式。較新的驅動程式應透過 DVBv5 API 提供此類資訊,例如 set_frontend/get_frontend,僅當需要 DVBv3 API 相容性時才實現此回撥。

diseqc_reset_overload

實現 FE_DISEQC_RESET_OVERLOAD() ioctl 的回撥函式(僅限衛星)。

diseqc_send_master_cmd

實現 FE_DISEQC_SEND_MASTER_CMD() ioctl 的回撥函式(僅限衛星)。

diseqc_recv_slave_reply

實現 FE_DISEQC_RECV_SLAVE_REPLY() ioctl 的回撥函式(僅限衛星)。

diseqc_send_burst

實現 FE_DISEQC_SEND_BURST() ioctl 的回撥函式(僅限衛星)。

set_tone

實現 FE_SET_TONE() ioctl 的回撥函式(僅限衛星)。

set_voltage

實現 FE_SET_VOLTAGE() ioctl 的回撥函式(僅限衛星)。

enable_high_lnb_voltage

實現 FE_ENABLE_HIGH_LNB_VOLTAGE() ioctl 的回撥函式(僅限衛星)。

dishnetwork_send_legacy_command

實現 FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl 的回撥函式(僅限衛星)。驅動程式不應使用此功能,除非 DVB 核心模擬無法提供適當的支援(例如,如果 set_voltage 需要超過 8 毫秒才能工作),並且需要與此傳統 API 向後相容。

i2c_gate_ctrl

控制 I2C 門。較新的驅動程式應改用 I2C 多路複用支援。

ts_bus_ctrl

用於控制 TS 匯流排的回撥函式。

set_lna

用於開啟/關閉/自動 LNA 的回撥函式。

search

在某些自定義演算法搜尋演算法上使用的回撥函式。

tuner_ops

指向 struct dvb_tuner_ops 的指標

analog_ops

指向 struct analog_demod_ops 的指標

struct dtv_frontend_properties

包含特定於數字電視標準的屬性列表。

定義:

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 {
        u8 segment_count;
        enum fe_code_rate   fec;
        enum fe_modulation  modulation;
        u8 interleaving;
    } layer[3];
    u32 stream_id;
    u32 scrambling_sequence_index;
    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;
};

成員

frequency

地面/有線電視以 Hz 為單位的頻率,衛星電視以 kHz 為單位的頻率

modulation

前端調製型別

voltage

SEC 電壓(僅限衛星)

sectone

SEC 音調模式(僅限衛星)

inversion

頻譜反轉

fec_inner

前向糾錯內部位元速率

transmission_mode

傳輸模式

bandwidth_hz

頻寬,單位為 Hz。值為零表示使用者空間想要自動檢測。

guard_interval

保護間隔

hierarchy

層級

symbol_rate

符號率

code_rate_HP

高優先順序流位元速率

code_rate_LP

低優先順序流位元速率

pilot

啟用/停用/自動檢測導頻音

rolloff

滾降因子 (alpha)

delivery_system

FE 傳輸系統(例如,數字電視標準)

interleaving

interleaving

isdbt_partial_reception

ISDB-T 部分接收(僅限 ISDB 標準)

isdbt_sb_mode

ISDB-T 聲音廣播 (SB) 模式(僅限 ISDB 標準)

isdbt_sb_subchannel

ISDB-T SB 子頻道(僅限 ISDB 標準)

isdbt_sb_segment_idx

ISDB-T SB 段索引(僅限 ISDB 標準)

isdbt_sb_segment_count

ISDB-T SB 段計數(僅限 ISDB 標準)

isdbt_layer_enabled

已啟用的 ISDB 層(僅限 ISDB 標準)

layer

ISDB 每層資料(僅限 ISDB 標準)

layer.segment_count

段計數;

layer.fec

每層位元速率;

layer.modulation

每層調製;

layer.interleaving

每層交織。

stream_id

如果不同於零,則啟用子流過濾(如果硬體支援)(DVB-S2 和 DVB-T2)。

scrambling_sequence_index

攜帶 DVB-S2 物理層加擾序列的索引。

atscmh_fic_ver

FIC(快速資訊頻道)信令資料的版本號(僅限 ATSC-M/H)

atscmh_parade_id

佇列標識號(僅限 ATSC-M/H)

atscmh_nog

指定佇列的每個 MH 子幀的 MH 組數(僅限 ATSC-M/H)

atscmh_tnog

MH 組的總數,包括一個 MH 子幀中屬於所有 MH 佇列的所有 MH 組(僅限 ATSC-M/H)

atscmh_sgn

起始組號(僅限 ATSC-M/H)

atscmh_prc

佇列重複週期(僅限 ATSC-M/H)

atscmh_rs_frame_mode

裡德-所羅門 (RS) 幀模式(僅限 ATSC-M/H)

atscmh_rs_frame_ensemble

RS 幀集合(僅限 ATSC-M/H)

atscmh_rs_code_mode_pri

RS 碼模式 pri(僅限 ATSC-M/H)

atscmh_rs_code_mode_sec

RS 碼模式 sec(僅限 ATSC-M/H)

atscmh_sccc_block_mode

串聯卷積碼 (SCCC) 塊模式(僅限 ATSC-M/H)

atscmh_sccc_code_mode_a

SCCC 碼模式 A(僅限 ATSC-M/H)

atscmh_sccc_code_mode_b

SCCC 碼模式 B(僅限 ATSC-M/H)

atscmh_sccc_code_mode_c

SCCC 碼模式 C(僅限 ATSC-M/H)

atscmh_sccc_code_mode_d

SCCC 碼模式 D(僅限 ATSC-M/H)

lna

開啟/關閉/自動線性低噪聲放大器 (LNA)

strength

DVBv5 API 統計資訊:訊號強度

cnr

DVBv5 API 統計資訊:(主) 載波的信噪比

pre_bit_error

DVBv5 API 統計資訊:Viterbi 之前的誤碼計數

pre_bit_count

DVBv5 API 統計資訊:Viterbi 之前的位元計數

post_bit_error

DVBv5 API 統計資訊:Viterbi 之後的誤碼計數

post_bit_count

DVBv5 API 統計資訊:Viterbi 之後的位元計數

block_error

DVBv5 API 統計資訊:塊錯誤計數

block_count

DVBv5 API 統計資訊:塊計數

注意

使用者空間計算諸如未校正錯誤塊 (UCE) 之類的衍生統計資訊。

描述

對於給定的傳輸系統,只需要屬性的子集。有關更多資訊,請查閱 media_api.html 以及 Userspace API 的文件。

struct dvb_frontend

驅動程式要使用的前端結構。

定義:

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;
};

成員

refcount

用於跟蹤 struct dvb_frontend 引用的引用計數

ops

嵌入的 struct dvb_frontend_ops

dvb

指向 struct dvb_adapter 的指標

demodulator_priv

解調器私有資料

tuner_priv

調諧器私有資料

frontend_priv

前端私有資料

sec_priv

SEC 私有資料

analog_demod_priv

模擬解調私有資料

dtv_property_cache

嵌入的 struct dtv_frontend_properties

callback

在某些驅動程式上使用的回撥函式,用於呼叫調諧器或解調器。

id

前端 ID

exit

用於通知 DVB 核心前端執行緒應退出(通常意味著硬體已斷開連線)。

int dvb_register_frontend(struct dvb_adapter *dvb, struct dvb_frontend *fe)

在介面卡上註冊 DVB 前端

引數

struct dvb_adapter *dvb

指向 struct dvb_adapter 的指標

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

分配並初始化前端核心所需的私有資料,以管理前端,並呼叫 dvb_register_device() 來註冊一個新的前端。它還會清除儲存前端引數的屬性快取,並選擇第一個可用的傳輸系統。

int dvb_unregister_frontend(struct dvb_frontend *fe)

登出 DVB 前端

引數

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

停止前端 kthread,呼叫 dvb_unregister_device() 並釋放由 dvb_register_frontend() 分配的私有前端資料。

注意

此函式不會釋放解調器、SEC 驅動程式和調諧器分配的記憶體。 為了釋放它,在呼叫此函式後,需要顯式呼叫 dvb_frontend_detach()

void dvb_frontend_detach(struct dvb_frontend *fe)

分離並釋放前端特定資料

引數

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

此函式應在 dvb_unregister_frontend() 之後呼叫。 它呼叫 SEC、調諧器和解調器的釋放函式:dvb_frontend_ops.release_sec, dvb_frontend_ops.tuner_ops.release, dvb_frontend_ops.analog_ops.release 和 dvb_frontend_ops.release

如果驅動程式使用 CONFIG_MEDIA_ATTACH 編譯,它還會減少模組引用計數,這對於允許使用者空間刪除先前使用的 DVB 前端模組是必需的。

int dvb_frontend_suspend(struct dvb_frontend *fe)

掛起數字電視前端

引數

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

此函式準備掛起數字電視前端。

為了準備掛起調諧器,如果 dvb_frontend_ops.tuner_ops.suspend() 可用,它會呼叫它。 否則,如果 dvb_frontend_ops.tuner_ops.sleep() 可用,它將呼叫它。

它還會呼叫 dvb_frontend_ops.suspend() 來將解調器置於掛起狀態(如果可用)。 否則,它將呼叫 dvb_frontend_ops.sleep()。

驅動程式還應該呼叫 dvb_frontend_suspend() 作為他們對 device_driver.suspend() 的處理程式的一部分。

int dvb_frontend_resume(struct dvb_frontend *fe)

恢復數字電視前端

引數

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

此函式在恢復後恢復調諧器的正常操作。

為了恢復前端,它會呼叫解調器 dvb_frontend_ops.resume()(如果可用)。 否則,它會呼叫解調器 dvb_frontend_ops.init()。

如果 dvb_frontend_ops.tuner_ops.resume() 可用,則呼叫它。 否則,如果 dvb_frontend_ops.tuner_ops.init() 可用,則將呼叫它。

一旦恢復了調諧器和解調器,它將強制 SEC 電壓和音調恢復到先前的值,並喚醒前端的 kthread 以重新調諧前端。

驅動程式還應該呼叫 dvb_frontend_resume() 作為他們對 device_driver.resume() 的處理程式的一部分。

void dvb_frontend_reinitialise(struct dvb_frontend *fe)

強制前端重新初始化

引數

struct dvb_frontend *fe

指向 struct dvb_frontend 的指標

描述

呼叫 dvb_frontend_ops.init() 和 dvb_frontend_ops.tuner_ops.init(),並重置 SEC 音調和電壓(對於衛星系統)。

注意

目前,此函式僅由一個驅動程式 (budget-av) 使用。 似乎是為了解決該特定前端的一些特殊問題。

void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec)

睡眠由 add_usec 引數給定的時間量

引數

ktime_t *waketime

指向 struct ktime_t 的指標

u32 add_usec

睡眠時間,以微秒為單位

描述

此函式用於測量 FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl 工作所需的時間。 它需要儘可能精確,因為它會影響衛星子系統中 dish 音調命令的檢測。

它在 DVB 前端核心內部使用,以便使用 dvb_frontend_ops.set_voltage() 回撥來模擬 FE_DISHNETWORK_SEND_LEGACY_CMD()。

注意

它不應在驅動程式中使用,因為傳統回撥的模擬由核心提供。 這種情況應該只在驅動程式中出現,即當硬體存在一些錯誤,會阻止核心模擬工作時。 在這種情況下,驅動程式將編寫一個 dvb_frontend_ops.dishnetwork_send_legacy_command() 並直接呼叫此函式。