diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-07 20:11:53 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-08 06:12:44 -0400 |
commit | 752a62b2ec9c21931dce869f2ae2c921c83a1164 (patch) | |
tree | 2cbcebc4cd623a187a1c6c2d6b55075a71790e72 /drivers/media/dvb-frontends/cx24123.c | |
parent | 0562aef296c251e50b0934e6af113c511349dd9c (diff) |
[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: Hans-Peter Jansen <hpj@urpla.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends/cx24123.c')
-rw-r--r-- | drivers/media/dvb-frontends/cx24123.c | 28 |
1 files changed, 7 insertions, 21 deletions
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index 68c88ab58e71..a771da3e9f99 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <asm/div64.h> | ||
29 | 30 | ||
30 | #include "dvb_frontend.h" | 31 | #include "dvb_frontend.h" |
31 | #include "cx24123.h" | 32 | #include "cx24123.h" |
@@ -452,7 +453,8 @@ static u32 cx24123_int_log2(u32 a, u32 b) | |||
452 | 453 | ||
453 | static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) | 454 | static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) |
454 | { | 455 | { |
455 | u32 tmp, sample_rate, ratio, sample_gain; | 456 | u64 tmp; |
457 | u32 sample_rate, ratio, sample_gain; | ||
456 | u8 pll_mult; | 458 | u8 pll_mult; |
457 | 459 | ||
458 | /* check if symbol rate is within limits */ | 460 | /* check if symbol rate is within limits */ |
@@ -482,27 +484,11 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) | |||
482 | 484 | ||
483 | sample_rate = pll_mult * XTAL; | 485 | sample_rate = pll_mult * XTAL; |
484 | 486 | ||
485 | /* | 487 | /* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */ |
486 | SYSSymbolRate[21:0] = (srate << 23) / sample_rate | ||
487 | |||
488 | We have to use 32 bit unsigned arithmetic without precision loss. | ||
489 | The maximum srate is 45000000 or 0x02AEA540. This number has | ||
490 | only 6 clear bits on top, hence we can shift it left only 6 bits | ||
491 | at a time. Borrowed from cx24110.c | ||
492 | */ | ||
493 | |||
494 | tmp = srate << 6; | ||
495 | ratio = tmp / sample_rate; | ||
496 | |||
497 | tmp = (tmp % sample_rate) << 6; | ||
498 | ratio = (ratio << 6) + (tmp / sample_rate); | ||
499 | |||
500 | tmp = (tmp % sample_rate) << 6; | ||
501 | ratio = (ratio << 6) + (tmp / sample_rate); | ||
502 | |||
503 | tmp = (tmp % sample_rate) << 5; | ||
504 | ratio = (ratio << 5) + (tmp / sample_rate); | ||
505 | 488 | ||
489 | tmp = ((u64)srate) << 23; | ||
490 | do_div(tmp, sample_rate); | ||
491 | ratio = (u32) tmp; | ||
506 | 492 | ||
507 | cx24123_writereg(state, 0x01, pll_mult * 6); | 493 | cx24123_writereg(state, 0x01, pll_mult * 6); |
508 | 494 | ||