aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2013-07-09 01:44:56 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-08-20 12:33:46 -0400
commitb15208573d926e2fdf46a753ae167235d73e1bf6 (patch)
tree6e415e514b1c989f24385283edafe825ac186d2c /drivers/staging
parent34599b9b5305eb70644d54fe22e6df4aa5fef65c (diff)
[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')
-rw-r--r--drivers/staging/media/msi3101/sdr-msi3101.c58
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 87896eebc2a8..4de4f505f0ac 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)
960}; 960};
961 961
962#define F_REF 24000000 962#define F_REF 24000000
963#define DIV_R_IN 2
963static int msi3101_set_usb_adc(struct msi3101_state *s) 964static int msi3101_set_usb_adc(struct msi3101_state *s)
964{ 965{
965 int ret, div_n, div_m, div_r_out, f_sr; 966 int ret, div_n, div_m, div_r_out, f_sr, f_vco;
966 u32 reg4, reg3; 967 u32 reg4, reg3;
967 /* 968 /*
968 * FIXME: Synthesizer config is just a educated guess... 969 * Synthesizer config is just a educated guess...
969 * It seems to give reasonable values when N is 5-12 and output
970 * divider R is 2, which means sampling rates 5-12 Msps in practise.
971 * 970 *
972 * reg 3 ADC synthesizer config
973 * [7:0] 0x03, register address 971 * [7:0] 0x03, register address
974 * [8] 1, always 972 * [8] 1, always
975 * [9] ? 973 * [9] ?
@@ -984,42 +982,48 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
984 * output divider 982 * output divider
985 * val div 983 * val div
986 * 0 - (invalid) 984 * 0 - (invalid)
987 * 1 2 985 * 1 4
988 * 2 3 986 * 2 6
989 * 3 4 987 * 3 8
990 * 4 5 988 * 4 10
991 * 5 6 989 * 5 12
992 * 6 7 990 * 6 14
993 * 7 8 991 * 7 16
992 *
993 * VCO 202000000 - 720000000++
994 */ 994 */
995 995
996 f_sr = s->ctrl_sampling_rate->val64; 996 f_sr = s->ctrl_sampling_rate->val64;
997 reg3 = 0x01c00303; 997 reg3 = 0x01c00303;
998 998
999 for (div_n = 12; div_n > 5; div_n--) { 999 for (div_r_out = 4; div_r_out < 16; div_r_out += 2) {
1000 if (f_sr >= div_n * 1000000) 1000 f_vco = f_sr * div_r_out * 12;
1001 dev_dbg(&s->udev->dev, "%s: div_r_out=%d f_vco=%d\n",
1002 __func__, div_r_out, f_vco);
1003 if (f_vco >= 202000000)
1001 break; 1004 break;
1002 } 1005 }
1003 1006
1004 reg3 |= div_n << 16; 1007 div_n = f_vco / (F_REF * DIV_R_IN);
1005 1008 div_m = f_vco % (F_REF * DIV_R_IN);
1006 for (div_r_out = 2; div_r_out < 8; div_r_out++) {
1007 if (f_sr >= div_n * F_REF / div_r_out / 12)
1008 break;
1009 }
1010 1009
1011 reg3 |= (div_r_out - 1) << 10; 1010 reg3 |= div_n << 16;
1012 div_m = f_sr % (div_n * F_REF / div_r_out / 12); 1011 reg3 |= (div_r_out / 2 - 1) << 10;
1012 reg4 = 0x0ffffful * div_m / F_REF;
1013 1013
1014 if (div_m >= 500000) { 1014 if (reg4 >= 0x0ffffful) {
1015 dev_dbg(&s->udev->dev,
1016 "%s: extending fractional part value %08x\n",
1017 __func__, reg4);
1018 reg4 -= 0x0ffffful;
1015 reg3 |= 1 << 15; 1019 reg3 |= 1 << 15;
1016 div_m -= 500000;
1017 } 1020 }
1018 1021
1019 reg4 = ((div_m * 0x0ffffful / 500000) << 8) | 0x04; 1022 reg4 = (reg4 << 8) | 0x04;
1020 1023
1021 dev_dbg(&s->udev->dev, "%s: sr=%d n=%d m=%d r_out=%d reg4=%08x\n", 1024 dev_dbg(&s->udev->dev,
1022 __func__, f_sr, div_n, div_m, div_r_out, reg4); 1025 "%s: f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg4=%08x\n",
1026 __func__, f_sr, f_vco, div_n, div_m, div_r_out, reg4);
1023 1027
1024 ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00608008); 1028 ret = msi3101_ctrl_msg(s, CMD_WREG, 0x00608008);
1025 if (ret) 1029 if (ret)