diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r-- | drivers/media/dvb/frontends/stv090x.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 6c99a86c8ef..e74419b682d 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3418,14 +3418,12 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) int res = 0; int min = 0, med; - if (val < tab[min].read) - res = tab[min].real; - else if (val >= tab[max].read) - res = tab[max].real; - else { + if ((val >= tab[min].read && val < tab[max].read) || + (val >= tab[max].read && val < tab[min].read)) { while ((max - min) > 1) { med = (max + min) / 2; - if (val >= tab[min].read && val < tab[med].read) + if ((val >= tab[min].read && val < tab[med].read) || + (val >= tab[med].read && val < tab[min].read)) max = med; else min = med; @@ -3434,6 +3432,18 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) (tab[max].real - tab[min].real) / (tab[max].read - tab[min].read)) + tab[min].real; + } else { + if (tab[min].read < tab[max].read) { + if (val < tab[min].read) + res = tab[min].real; + else if (val >= tab[max].read) + res = tab[max].real; + } else { + if (val >= tab[min].read) + res = tab[min].real; + else if (val < tab[max].read) + res = tab[max].real; + } } return res; @@ -3443,16 +3453,22 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct stv090x_state *state = fe->demodulator_priv; u32 reg; - s32 agc; + s32 agc_0, agc_1, agc; + s32 str; reg = STV090x_READ_DEMOD(state, AGCIQIN1); - agc = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + reg = STV090x_READ_DEMOD(state, AGCIQIN0); + agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); + agc = MAKEWORD16(agc_1, agc_0); - *strength = stv090x_table_lookup(stv090x_rf_tab, ARRAY_SIZE(stv090x_rf_tab) - 1, agc); + str = stv090x_table_lookup(stv090x_rf_tab, + ARRAY_SIZE(stv090x_rf_tab) - 1, agc); if (agc > stv090x_rf_tab[0].read) - *strength = 5; + str = 0; else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) - *strength = -100; + str = -100; + *strength = (str + 100) * 0xFFFF / 100; return 0; } @@ -3463,6 +3479,8 @@ 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; + s32 div; + u32 last; switch (state->delsys) { case STV090x_DVBS2: @@ -3474,14 +3492,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); - val_0 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); + val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD); val += MAKEWORD16(val_1, val_0); msleep(1); } val /= 16; - *cnr = stv090x_table_lookup(stv090x_s2cn_tab, ARRAY_SIZE(stv090x_s2cn_tab) - 1, val); - if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s2cn_tab) - 1].read) - *cnr = 1000; + last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; + div = stv090x_s2cn_tab[0].read - + stv090x_s2cn_tab[last].read; + *cnr = 0xFFFF - ((val * 0xFFFF) / div); } break; @@ -3495,14 +3514,15 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); - val_0 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); + val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD); val += MAKEWORD16(val_1, val_0); msleep(1); } val /= 16; - *cnr = stv090x_table_lookup(stv090x_s1cn_tab, ARRAY_SIZE(stv090x_s1cn_tab) - 1, val); - if (val < stv090x_s2cn_tab[ARRAY_SIZE(stv090x_s1cn_tab) - 1].read) - *cnr = 1000; + last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; + div = stv090x_s1cn_tab[0].read - + stv090x_s1cn_tab[last].read; + *cnr = 0xFFFF - ((val * 0xFFFF) / div); } break; default: |