|
|
@@ -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)
|