Commit 752a62b2 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] cx24123: improve precision when calculating symbol rate ratio

Symbol rate ratio were using a rough calculus, as the code was
limited to 32 bits arithmetic. Change it to 64 bits, in order
to better estimate the bandwidth low-pass filter on the demod.
This should reduce the noise and improve reception.
Reported-by: default avatarHans-Peter Jansen <hpj@urpla.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0562aef2
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/div64.h>
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "cx24123.h" #include "cx24123.h"
...@@ -452,7 +453,8 @@ static u32 cx24123_int_log2(u32 a, u32 b) ...@@ -452,7 +453,8 @@ static u32 cx24123_int_log2(u32 a, u32 b)
static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
{ {
u32 tmp, sample_rate, ratio, sample_gain; u64 tmp;
u32 sample_rate, ratio, sample_gain;
u8 pll_mult; u8 pll_mult;
/* check if symbol rate is within limits */ /* check if symbol rate is within limits */
...@@ -482,27 +484,11 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) ...@@ -482,27 +484,11 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
sample_rate = pll_mult * XTAL; sample_rate = pll_mult * XTAL;
/* /* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */
SYSSymbolRate[21:0] = (srate << 23) / sample_rate
We have to use 32 bit unsigned arithmetic without precision loss.
The maximum srate is 45000000 or 0x02AEA540. This number has
only 6 clear bits on top, hence we can shift it left only 6 bits
at a time. Borrowed from cx24110.c
*/
tmp = srate << 6;
ratio = tmp / sample_rate;
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 5;
ratio = (ratio << 5) + (tmp / sample_rate);
tmp = ((u64)srate) << 23;
do_div(tmp, sample_rate);
ratio = (u32) tmp;
cx24123_writereg(state, 0x01, pll_mult * 6); cx24123_writereg(state, 0x01, pll_mult * 6);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment