support new API signal strength and SNR

support get_frontend()
start support for BER
This commit is contained in:
Ralph Metzler 2016-07-04 18:59:33 +02:00
parent c929aea04d
commit 86d9ce8f11
2 changed files with 128 additions and 23 deletions

View File

@ -38,7 +38,6 @@
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE 64
#define ERRCTRL1_DVBS1 0x76
#define ERRCTRL1_DVBS2 0x67
@ -3554,6 +3553,43 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
return DVBFE_ALGO_SEARCH_ERROR;
}
static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr);
static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength);
static int stv090x_ber_prop(struct dvb_frontend *fe, enum fe_status *status)
{
struct stv090x_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u32 reg, h, m, l;
u32 n = 0, d = 1;
if (!(*status & FE_HAS_LOCK)) {
n = 1;
d = 1;
} else {
/* Counter 1 */
reg = STV090x_READ_DEMOD(state, ERRCNT12);
h = STV090x_GETFIELD_Px(reg, ERR_CNT12_FIELD);
reg = STV090x_READ_DEMOD(state, ERRCNT11);
m = STV090x_GETFIELD_Px(reg, ERR_CNT11_FIELD);
reg = STV090x_READ_DEMOD(state, ERRCNT10);
l = STV090x_GETFIELD_Px(reg, ERR_CNT10_FIELD);
n = ((h << 16) | (m << 8) | l);
}
p->pre_bit_error.len = 1;
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
p->pre_bit_error.stat[0].uvalue =n;
p->pre_bit_count.len = 1;
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
p->pre_bit_count.stat[0].uvalue = d;
return 0;
}
static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
{
struct stv090x_state *state = fe->demodulator_priv;
@ -3568,15 +3604,17 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
reg = STV090x_READ_DEMOD(state, DMDSTATE);
search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
switch (search_state) {
case 0: /* searching */
case 1: /* first PLH detected */
default:
dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
state->rec_mode = 0;
break;
case 2: /* DVB-S2 mode */
state->rec_mode = 2;
dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
@ -3590,6 +3628,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
break;
case 3: /* DVB-S1/legacy mode */
state->rec_mode = 1;
dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
@ -3603,6 +3642,15 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
break;
}
{
u16 val;
u32 ber;
stv090x_read_cnr(fe, &val);
stv090x_read_signal_strength(fe, &val);
stv090x_ber_prop(fe, status);
}
return 0;
}
@ -3749,6 +3797,10 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
str = 0;
else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
str = -100;
p->strength.len = 1;
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
p->strength.stat[0].uvalue = 1000 * (s64) (s32) str;
#ifdef DBVALS
*strength = str;
p->strength.len = 1;
@ -3784,10 +3836,9 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
u32 reg_0, reg_1, reg, i;
s32 val_0, val_1, val = 0;
u8 lock_f;
#ifndef DBVALS
s32 cnr_db;
s32 div;
u32 last;
#endif
switch (state->delsys) {
case STV090x_DVBS2:
@ -3804,21 +3855,16 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
msleep(1);
}
val /= 16;
#ifdef DBVALS
*cnr = stv090x_table_lookup(stv090x_s2cn_tab,
ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
#else
cnr_db = stv090x_table_lookup(stv090x_s2cn_tab,
ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
div = stv090x_s2cn_tab[0].read -
stv090x_s2cn_tab[last].read;
*cnr = 0xFFFF - ((val * 0xFFFF) / div);
#endif
} else
#ifdef DBVALS
*cnr = -30;
#else
} else {
cnr_db = -30;
*cnr = 0;
#endif
}
break;
case STV090x_DVBS1:
@ -3836,26 +3882,26 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
msleep(1);
}
val /= 16;
#ifdef DBVALS
*cnr = stv090x_table_lookup(stv090x_s1cn_tab,
ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
#else
cnr_db = stv090x_table_lookup(stv090x_s1cn_tab,
ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
div = stv090x_s1cn_tab[0].read -
stv090x_s1cn_tab[last].read;
*cnr = 0xFFFF - ((val * 0xFFFF) / div);
#endif
} else
} else {
cnr_db = -30;
*cnr = 0;
}
break;
default:
break;
}
#ifdef DBVALS
*cnr = cnr_db;
#endif
p->cnr.len = 1;
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
p->cnr.stat[0].uvalue = 100 * (s64) *cnr;
p->cnr.stat[0].uvalue = 100 * (s64) cnr_db;
return 0;
}
@ -5038,6 +5084,62 @@ static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
static int stv090x_get_frontend(struct dvb_frontend *fe)
{
struct stv090x_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u8 tmp;
u32 reg = 0;
if (state->rec_mode == 2) {
u32 mc;
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,
};
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
};
mc = state->modcod;
p->pilot = (state->pilots & 0x01) ? PILOT_ON : PILOT_OFF;
p->modulation = modcod2mod[mc];
p->fec_inner = modcod2fec[mc];
} else if (state->rec_mode == 1) {
reg = STV090x_READ_DEMOD(state, VITCURPUN);
switch( reg & 0x1F ) {
case 0x0d:
p->fec_inner = FEC_1_2;
break;
case 0x12:
p->fec_inner = FEC_2_3;
break;
case 0x15:
p->fec_inner = FEC_3_4;
break;
case 0x18:
p->fec_inner = FEC_5_6;
break;
case 0x1a:
p->fec_inner = FEC_7_8;
break;
default:
p->fec_inner = FEC_NONE;
break;
}
p->rolloff = ROLLOFF_35;
} else {
}
return 0;
}
@ -5152,6 +5254,8 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
demod,
state->internal->dev_ver);
printk("STV0900 version 0x%02x\n", state->internal->dev_ver);
return &state->frontend;
err_remove:

View File

@ -274,6 +274,7 @@ struct stv090x_state {
s32 DemodTimeout;
s32 FecTimeout;
u32 rec_mode;
};
#endif /* __STV090x_PRIV_H */