V4L/DVB (13353): stv090x: fixes STR and SNR calculation and normalizes the value...
authorAndreas Regel <andreas.regel@gmx.de>
Fri, 13 Nov 2009 21:14:00 +0000 (18:14 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 5 Dec 2009 20:41:29 +0000 (18:41 -0200)
Signed-off-by: Andreas Regel <andreas.regel@gmx.de>
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/frontends/stv090x.c

index 6c99a86..e74419b 100644 (file)
@@ -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: