You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

270 lines
7.8 KiB

From ec656237d412f779865cb315e65cd33e7f40db10 Mon Sep 17 00:00:00 2001
From: betacentauri <betacentauri@arcor.de>
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