diff --git a/ddbridge/ddbridge-m4.c b/ddbridge/ddbridge-m4.c index 88f0be0..87a90da 100644 --- a/ddbridge/ddbridge-m4.c +++ b/ddbridge/ddbridge-m4.c @@ -388,6 +388,14 @@ static int get_algo(struct dvb_frontend *fe) return DVBFE_ALGO_HW; } +static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p) +{ + struct m4 *state = fe->demodulator_priv; + + ddb_mci_proc_info(&state->mci, p); + return 0; +} + static struct dvb_frontend_ops m4_ops = { .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2, SYS_DVBC2, SYS_ISDBT, SYS_DVBS, SYS_DVBS2, }, @@ -411,6 +419,7 @@ static struct dvb_frontend_ops m4_ops = { }, .release = release, .get_frontend_algo = get_algo, + .get_frontend = get_frontend, .read_status = read_status, .tune = tune, .sleep = sleep, diff --git a/ddbridge/ddbridge-mci.c b/ddbridge/ddbridge-mci.c index 107c776..dec7861 100644 --- a/ddbridge/ddbridge-mci.c +++ b/ddbridge/ddbridge-mci.c @@ -195,6 +195,113 @@ int ddb_mci_get_info(struct mci *mci) return stat; } +/****************************************************************************/ +/****************************************************************************/ + +void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p) +{ + const enum fe_modulation modcod2mod[0x20] = { + QPSK, QPSK, QPSK, QPSK, + QPSK, QPSK, QPSK, QPSK, + QPSK, QPSK, QPSK, QPSK, + PSK_8, PSK_8, PSK_8, PSK_8, + PSK_8, PSK_8, APSK_16, APSK_16, + APSK_16, APSK_16, APSK_16, APSK_16, + APSK_32, APSK_32, APSK_32, APSK_32, + APSK_32, + }; + const enum fe_code_rate modcod2fec[0x20] = { + FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5, + FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, + FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6, + FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, + FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, + FEC_9_10, FEC_NONE, FEC_NONE, FEC_NONE, + }; + const enum fe_code_rate dvbs_fec_lut[8] = { + FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, + FEC_NONE, FEC_7_8, FEC_NONE, FEC_NONE, + }; + const enum fe_rolloff ro_lut[8] = { + ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_10, + ROLLOFF_5, ROLLOFF_15, ROLLOFF_35, ROLLOFF_35 + }; + + p->frequency = + mci->signal_info.dvbs2_signal_info.frequency; + switch (p->delivery_system) { + default: + case SYS_DVBS: + case SYS_DVBS2: + { + u32 pls_code = + mci->signal_info.dvbs2_signal_info.pls_code; + + p->frequency = + mci->signal_info.dvbs2_signal_info.frequency / 1000; + p->delivery_system = + (mci->signal_info.dvbs2_signal_info.standard == 2) ? + SYS_DVBS2 : SYS_DVBS; + if (mci->signal_info.dvbs2_signal_info.standard == 2) { + u32 modcod = (0x7c & pls_code) >> 2; + + p->delivery_system = SYS_DVBS2; + p->rolloff = + ro_lut[mci->signal_info. + dvbs2_signal_info.roll_off & 7]; + p->pilot = (pls_code & 1) ? PILOT_ON : PILOT_OFF; + p->fec_inner = modcod2fec[modcod]; + p->modulation = modcod2mod[modcod]; + p->transmission_mode = pls_code; + } else { + p->delivery_system = SYS_DVBS; + p->rolloff = ROLLOFF_35; + p->pilot = PILOT_OFF; + p->fec_inner = dvbs_fec_lut[pls_code & 7]; + p->modulation = QPSK; + } + break; + } + case SYS_DVBC_ANNEX_A: + break; + case SYS_DVBT: + break; + case SYS_DVBT2: + break; + case SYS_DVBC2: + break; + case SYS_ISDBT: + break; + } + p->pre_bit_error.len = 1; + p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_error.stat[0].uvalue = + mci->signal_info.dvbs2_signal_info.ber_numerator; + + p->pre_bit_count.len = 1; + p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; + p->pre_bit_count.stat[0].uvalue = + mci->signal_info.dvbs2_signal_info.ber_denominator; + + p->block_error.len = 1; + p->block_error.stat[0].scale = FE_SCALE_COUNTER; + p->block_error.stat[0].uvalue = + mci->signal_info.dvbs2_signal_info.packet_errors; + p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + p->cnr.len = 1; + p->cnr.stat[0].scale = FE_SCALE_DECIBEL; + p->cnr.stat[0].svalue = (s64) mci-> + signal_info.dvbs2_signal_info.signal_to_noise * 10; + + p->strength.len = 1; + p->strength.stat[0].scale = FE_SCALE_DECIBEL; + p->strength.stat[0].svalue = + mci->signal_info.dvbs2_signal_info.channel_power * 10; +} + static void mci_handler(void *priv) { struct mci_base *base = (struct mci_base *)priv; diff --git a/ddbridge/ddbridge-mci.h b/ddbridge/ddbridge-mci.h index 7c9e3c6..6160ad6 100644 --- a/ddbridge/ddbridge-mci.h +++ b/ddbridge/ddbridge-mci.h @@ -245,19 +245,21 @@ struct mci_command { } sx8_start_iq; struct { - u8 flags; /* Bit 1:0 = STVVGLNA Gain. 0 = AGC, 1 = 0dB, 2 = Minimum, 3 = Maximum */ + /* Bit 1:0 = STVVGLNA Gain. 0 = AGC, 1 = 0dB, + 2 = Minimum, 3 = Maximum */ + u8 flags; } sx8_input_enable; - + struct { u8 Offset; // Offset into list, must be multiple of 64 u8 Select; // 0 = Slices, 1 = PLPs (C2 Only) u8 DataSlice; // DataSlice to get PLPList (C2 Only) - } Get_IDs; + } get_ids; struct { - u8 Select; // 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID - u8 ID; // DataSliceID, PLPId - } Get_L1Info; + u8 select; // 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID + u8 id; // DataSliceID, PLPId + } get_l1_info; }; }; @@ -343,7 +345,7 @@ struct mci_result { u32 packet_errors; // Counter for packet errors. (set to 0 on Start command) u32 ber_numerator; // Bit error rate: PreBCH u32 ber_denominator; - } DVBC2_SignalInfo; + } dvbc2_signal_info; struct { u32 rsvd0; @@ -365,6 +367,7 @@ struct mci_result { s16 i; s16 q; } iq_symbol; + struct { u8 t2_l1_pre[37]; u8 t2_l1_post[15]; @@ -539,5 +542,6 @@ int ddb_mci_get_status(struct mci *mci, struct mci_result *res); int ddb_mci_get_snr(struct dvb_frontend *fe); int ddb_mci_get_info(struct mci *mci); int ddb_mci_get_strength(struct dvb_frontend *fe); +void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p); #endif diff --git a/ddbridge/ddbridge-sx8.c b/ddbridge/ddbridge-sx8.c index 4bd24e6..b97704d 100644 --- a/ddbridge/ddbridge-sx8.c +++ b/ddbridge/ddbridge-sx8.c @@ -111,6 +111,9 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) { int stat; struct sx8 *state = fe->demodulator_priv; + struct mci_base *mci_base = state->mci.base; + struct sx8_base *sx8_base = (struct sx8_base *) mci_base; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct mci_result res; stat = ddb_mci_get_status(&state->mci, &res); @@ -118,12 +121,18 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) return stat; *status = 0x00; ddb_mci_get_info(&state->mci); - ddb_mci_get_strength(fe); if (res.status == SX8_DEMOD_WAIT_MATYPE) *status = 0x0f; if (res.status == SX8_DEMOD_LOCKED) { *status = 0x1f; - ddb_mci_get_snr(fe); + if (state->mci.signal_info.dvbs2_signal_info.standard == 2) { + sx8_base->used_ldpc_bitrate[state->mci.nr] = + p->symbol_rate * + dvbs2_bits_per_symbol[ + state->mci.signal_info. + dvbs2_signal_info.pls_code]; + } else + sx8_base->used_ldpc_bitrate[state->mci.nr] = 0; } return stat; } @@ -228,6 +237,7 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config) if (sx8_base->demod_in_use[i]) used_demods++; } + printk("used_ldpc_bitrate = %u\n", used_ldpc_bitrate); if ((used_ldpc_bitrate >= MAX_LDPC_BITRATE) || ((ts_config & SX8_TSCONFIG_MODE_MASK) > SX8_TSCONFIG_MODE_NORMAL && used_demods > 0)) { @@ -450,6 +460,14 @@ static int sleep(struct dvb_frontend *fe) return 0; } +static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p) +{ + struct sx8 *state = fe->demodulator_priv; + + ddb_mci_proc_info(&state->mci, p); + return 0; +} + static struct dvb_frontend_ops sx8_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ @@ -468,6 +486,7 @@ static struct dvb_frontend_ops sx8_ops = { FE_CAN_MULTISTREAM, }, .get_frontend_algo = get_algo, + .get_frontend = get_frontend, .tune = tune, .release = release, .read_status = read_status,