diff options
author | Antti Palosaari <crope@iki.fi> | 2013-07-09 05:44:56 (GMT) |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-08-20 16:33:46 (GMT) |
commit | b15208573d926e2fdf46a753ae167235d73e1bf6 (patch) | |
tree | 6e415e514b1c989f24385283edafe825ac186d2c /drivers/staging/media/msi3101/sdr-msi3101.c | |
parent | 34599b9b5305eb70644d54fe22e6df4aa5fef65c (diff) | |
download | linux-b15208573d926e2fdf46a753ae167235d73e1bf6.tar.xz |
[media] msi3101: fix sampling rate calculation
These calculations seem to give 100% correct results. Calculation
formulas could be still a little bit wrong as I have no knowledge
what kind of dividers, multipliers and VCO limits there really is.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/staging/media/msi3101/sdr-msi3101.c')
-rw-r--r-- | drivers/staging/media/msi3101/sdr-msi3101.c | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c index 87896ee..4de4f50 100644 --- a/drivers/staging/media/msi3101/sdr-msi3101.c +++ b/drivers/staging/media/msi3101/sdr-msi3101.c @@ -960,16 +960,14 @@ static int msi3101_tuner_write(struct msi3101_state *s, u32 data) }; #define F_REF 24000000 +#define DIV_R_IN 2 static int msi3101_set_usb_adc(struct msi3101_state *s) { - int ret, div_n, div_m, div_r_out, f_sr; + int ret, div_n, div_m, div_r_out, f_sr, f_vco; u32 reg4, reg3; /* - * FIXME: Synthesizer config is just a educated guess... - * It seems to give reasonable values when N is 5-12 and output - * divider R is 2, which means sampling rates 5-12 Msps in practise. + * Synthesizer config is just a educated guess... * - * reg 3 ADC synthesizer config * [7:0] 0x03, register address * [8] 1, always * [9] ? @@ -984,42 +982,48 @@ static int msi3101_set_usb_adc(struct msi3101_state *s) * output divider * val div * 0 - (invalid) - * 1 2 - * 2 3 - * 3 4 - * 4 5 - * 5 6 - * 6 7 - * 7 8 + * 1 4 + * 2 6 + * 3 8 + * 4 10 + * 5 12 + * 6 14 + * 7 16 + * + * VCO 202000000 - 720000000++ */ f_sr = s->ctrl_sampling_rate->val64; reg3 = 0x01c00303; - for (div_n = 12; div_n > 5; div_n--) { - if (f_sr >= div_n * 1000000) + for (div_r_out = 4; div_r_out < 16; div_r_out += 2) { + f_vco = f_sr * div_r_out * 12; + dev_dbg(&s->udev->dev, "%s: div_r_out=%d f_vco=%d\n", + __func__, div_r_out, f_vco); + if (f_vco >= 202000000) break; } - reg3 |= div_n << 16; - - for (div_r_out = 2; div_r_out < 8; div_r_out++) { - if (f_sr >= div_n * F_REF / div_r_out / 12) - break; - } + div_n = f_vco / (F_REF * DIV_R_IN); + div_m = f_vco % (F_REF * DIV_R_IN); - reg3 |= (div_r_out - 1) << 10; - div_m = f_sr % (div_n * F_REF / div_r_out / 12); + reg3 |= div_n << 16; + reg3 |= (div_r_out / 2 - 1) << 10; + reg4 = 0x0ffffful * div_m / F_REF; - if (div_m >= 500000) { + if (reg4 >= 0x0ffffful) { + dev_dbg(&s->udev->dev, + "%s: extending fractional part value %08x\n", + __func__, reg4); + reg4 -= 0x0ffffful; reg3 |= 1 << 15; - div_m -= 500000; } - reg4 = ((div_m * 0x0ffffful / 500000) << 8) | 0x04; + reg4 = (reg4 << 8) | 0x04; - dev_dbg(&s->udev->dev, "%s: sr=%d n=%d m=%d r_out=%d reg4=%08x\n", - __func__, f_sr, div_n, div_m, div_r_out, reg4); + dev_dbg(&s->udev->dev, + "%s: f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg4=%08x\n", + __func__, f_sr, f_vco, div_n, div_m, div_r_out, reg4); ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00608008); if (ret) |