From ec656237d412f779865cb315e65cd33e7f40db10 Mon Sep 17 00:00:00 2001 From: betacentauri Date: Mon, 16 May 2016 18:02:28 +0200 --- drivers/media/dvb-frontends/stv090x.c | 182 ++++++++++++++++++++++++++++-- drivers/media/dvb-frontends/stv090x_reg.h | 2 + 2 files changed, 172 insertions(+), 12 deletions(-) diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 2d735a82..f2cc8ed7 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -1700,6 +1700,7 @@ static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) ((int_1 * tmp_2) >> 16) + ((int_2 * tmp_1) >> 16); + state->srate = srate; return srate; } @@ -2614,6 +2615,94 @@ static int stv090x_get_viterbi(struct stv090x_state *state) static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state) { struct dvb_frontend *fe = &state->frontend; + struct dtv_frontend_properties *props = &fe->dtv_property_cache; + + int fe_stv0900_tracking_standard_return[] = { + SYS_UNDEFINED, + SYS_DVBS, + SYS_DVBS2, + SYS_DSS + }; + + int fe_stv0900_rolloff_return[] = { + ROLLOFF_35, + ROLLOFF_25, + ROLLOFF_20, + ROLLOFF_AUTO + }; + + int fe_stv0900_modulation_return[] = { + QPSK, + PSK_8, + APSK_16, + APSK_32 + }; + + int fe_stv0900_modcod_return_dvbs[] = { + FEC_NONE, + FEC_AUTO, + FEC_AUTO, + FEC_AUTO, + FEC_1_2, + FEC_3_5, + FEC_2_3, + FEC_3_4, + FEC_4_5, + FEC_5_6, + FEC_6_7, + FEC_7_8, + 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_AUTO + }; + + int fe_stv0900_modcod_return_dvbs2[] = { + FEC_NONE, + FEC_AUTO, + FEC_AUTO, + FEC_AUTO, + 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_AUTO + }; u8 tmg; u32 reg; @@ -2653,10 +2742,71 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1; - reg = STV090x_READ_DEMOD(state, TMGOBS); - state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); - reg = STV090x_READ_DEMOD(state, FECM); - state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); + reg = STV090x_READ_DEMOD(state, MATSTR1); + state->rolloff = STV090x_GETFIELD_Px(reg, MATYPE_ROLLOFF_FIELD); + + switch (state->delsys) { + case STV090x_DVBS2: + if (state->modcod <= STV090x_QPSK_910) + state->modulation = STV090x_QPSK; + else if (state->modcod <= STV090x_8PSK_910) + state->modulation = STV090x_8PSK; + else if (state->modcod <= STV090x_16APSK_910) + state->modulation = STV090x_16APSK; + else if (state->modcod <= STV090x_32APSK_910) + state->modulation = STV090x_32APSK; + else + state->modulation = STV090x_UNKNOWN; + reg = STV090x_READ_DEMOD(state, PLHMODCOD); + state->inversion = STV090x_GETFIELD_Px(reg, SPECINV_DEMOD_FIELD); + break; + case STV090x_DVBS1: + case STV090x_DSS: + switch(state->fec) { + case STV090x_PR12: + state->modcod = STV090x_QPSK_12; + break; + case STV090x_PR23: + state->modcod = STV090x_QPSK_23; + break; + case STV090x_PR34: + state->modcod = STV090x_QPSK_34; + break; + case STV090x_PR45: + state->modcod = STV090x_QPSK_45; + break; + case STV090x_PR56: + state->modcod = STV090x_QPSK_56; + break; + case STV090x_PR67: + state->modcod = STV090x_QPSK_89; + break; + case STV090x_PR78: + state->modcod = STV090x_QPSK_910; + break; + default: + state->modcod = STV090x_DUMMY_PLF; + break; + } + state->modulation = STV090x_QPSK; + reg = STV090x_READ_DEMOD(state, FECM); + state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); + break; + default: + break; + } + + props->frequency = state->frequency; + props->symbol_rate = state->srate; + if (state->delsys == 2) + props->fec_inner = fe_stv0900_modcod_return_dvbs2[state->modcod]; + else + props->fec_inner = fe_stv0900_modcod_return_dvbs[state->modcod]; + props->pilot = state->pilots; + props->rolloff = fe_stv0900_rolloff_return[state->rolloff]; + props->modulation = fe_stv0900_modulation_return[state->modulation]; + props->inversion = state->inversion; + props->delivery_system = fe_stv0900_tracking_standard_return[state->delsys]; if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { @@ -2864,6 +3014,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) { struct dvb_frontend *fe = &state->frontend; + enum stv090x_rolloff rolloff; enum stv090x_modcod modcod; s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; @@ -3009,6 +3160,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) f_1 = STV090x_READ_DEMOD(state, CFR2); f_0 = STV090x_READ_DEMOD(state, CFR1); reg = STV090x_READ_DEMOD(state, TMGOBS); + rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); if (state->algo == STV090x_BLIND_SEARCH) { STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); @@ -3530,20 +3682,24 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) state->frequency = props->frequency; state->srate = props->symbol_rate; state->search_mode = STV090x_SEARCH_AUTO; - state->algo = STV090x_COLD_SEARCH; + state->algo = STV090x_BLIND_SEARCH; state->fec = STV090x_PRERR; - if (state->srate > 10000000) { - dprintk(FE_DEBUG, 1, "Search range: 10 MHz"); - state->search_range = 10000000; - } else { - dprintk(FE_DEBUG, 1, "Search range: 5 MHz"); - state->search_range = 5000000; - } + state->search_range = 0; stv090x_set_mis(state, props->stream_id); + dprintk(FE_DEBUG, 1, "Search started..."); if (stv090x_algo(state) == STV090x_RANGEOK) { + stv090x_get_sig_params(state); dprintk(FE_DEBUG, 1, "Search success!"); + dprintk(FE_DEBUG, 1, "frequency = %d", props->frequency); + dprintk(FE_DEBUG, 1, "symbol_rate = %d", props->symbol_rate); + dprintk(FE_DEBUG, 1, "fec_inner = %d, %d", props->fec_inner, state->modcod); + dprintk(FE_DEBUG, 1, "pilot = %d", props->pilot); + dprintk(FE_DEBUG, 1, "rolloff = %d", props->rolloff); + dprintk(FE_DEBUG, 1, "modulation = %d, %d", props->modulation, state->modulation); + dprintk(FE_DEBUG, 1, "inversion = %d", props->inversion); + dprintk(FE_DEBUG, 1, "delivery_system = %d, %d", props->delivery_system, state->delsys); return DVBFE_ALGO_SEARCH_SUCCESS; } else { dprintk(FE_DEBUG, 1, "Search failed!"); @@ -3586,6 +3742,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) *status |= FE_HAS_SYNC | FE_HAS_LOCK; } } + stv090x_get_sig_params(state); break; case 3: /* DVB-S1/legacy mode */ @@ -3599,6 +3756,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) *status |= FE_HAS_SYNC | FE_HAS_LOCK; } } + stv090x_get_sig_params(state); break; } diff --git a/drivers/media/dvb-frontends/stv090x_reg.h b/drivers/media/dvb-frontends/stv090x_reg.h index c1dac9c0..82b976fc 100644 --- a/drivers/media/dvb-frontends/stv090x_reg.h +++ b/drivers/media/dvb-frontends/stv090x_reg.h @@ -1927,6 +1927,8 @@ #define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1) #define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0) #define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1) +#define STV090x_OFFST_Px_MATYPE_ROLLOFF_FIELD 0 +#define STV090x_WIDTH_Px_MATYPE_ROLLOFF_FIELD 2 #define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0 #define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8