V4L/DVB (12887): DIB7000P: SNR calcuation forr DiB7000P
authorOlivier Grenie <olivier.grenie@dibcom.fr>
Tue, 15 Sep 2009 09:46:52 +0000 (06:46 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 19 Sep 2009 03:14:10 +0000 (00:14 -0300)
Add the SNR monitoring for the dib7000p. The result is in dB.

Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/frontends/dib7000p.c

index fc96fbf03d6dc9d1bbf9cce827ac950184c6d1d5..55ef6eeb0769f9b8f9aa352962be6418e2f8f827 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 
+#include "dvb_math.h"
 #include "dvb_frontend.h"
 
 #include "dib7000p.h"
@@ -1217,7 +1218,37 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 
 static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-       *snr = 0x0000;
+       struct dib7000p_state *state = fe->demodulator_priv;
+       u16 val;
+       s32 signal_mant, signal_exp, noise_mant, noise_exp;
+       u32 result = 0;
+
+       val = dib7000p_read_word(state, 479);
+       noise_mant = (val >> 4) & 0xff;
+       noise_exp = ((val & 0xf) << 2);
+       val = dib7000p_read_word(state, 480);
+       noise_exp += ((val >> 14) & 0x3);
+       if ((noise_exp & 0x20) != 0)
+               noise_exp -= 0x40;
+
+       signal_mant = (val >> 6) & 0xFF;
+       signal_exp  = (val & 0x3F);
+       if ((signal_exp & 0x20) != 0)
+               signal_exp -= 0x40;
+
+       if (signal_mant != 0)
+               result = intlog10(2) * 10 * signal_exp + 10 *
+                       intlog10(signal_mant);
+       else
+               result = intlog10(2) * 10 * signal_exp - 100;
+
+       if (noise_mant != 0)
+               result -= intlog10(2) * 10 * noise_exp + 10 *
+                       intlog10(noise_mant);
+       else
+               result -= intlog10(2) * 10 * noise_exp - 100;
+
+       *snr = result / ((1 << 24) / 10);
        return 0;
 }