Skip to content

Commit 773db47

Browse files
committed
apply mutability patch from steve-m#10
1 parent c7d970a commit 773db47

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

src/tuner_r82xx.c

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,11 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
419419
int rc, i;
420420
unsigned sleep_time = 10000;
421421
uint64_t vco_freq;
422-
uint32_t vco_fra; /* VCO contribution by SDM (kHz) */
423-
uint32_t vco_min = 1770000;
424-
uint32_t vco_max = vco_min * 2;
425-
uint32_t freq_khz, pll_ref, pll_ref_khz;
426-
uint16_t n_sdm = 2;
427-
uint16_t sdm = 0;
422+
uint64_t vco_div;
423+
uint32_t vco_min = 1770000; /* kHz */
424+
uint32_t vco_max = vco_min * 2; /* kHz */
425+
uint32_t freq_khz, pll_ref;
426+
uint32_t sdm = 0;
428427
uint8_t mix_div = 2;
429428
uint8_t div_buf = 0;
430429
uint8_t div_num = 0;
@@ -436,7 +435,6 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
436435
/* Frequency in kHz */
437436
freq_khz = (freq + 500) / 1000;
438437
pll_ref = priv->cfg->xtal;
439-
pll_ref_khz = (priv->cfg->xtal + 500) / 1000;
440438

441439
rc = r82xx_write_reg_mask(priv, 0x10, refdiv2, 0x10);
442440
if (rc < 0)
@@ -485,8 +483,35 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
485483
return rc;
486484

487485
vco_freq = (uint64_t)freq * (uint64_t)mix_div;
488-
nint = vco_freq / (2 * pll_ref);
489-
vco_fra = (vco_freq - 2 * pll_ref * nint) / 1000;
486+
487+
/*
488+
* We want to approximate:
489+
*
490+
* vco_freq / (2 * pll_ref)
491+
*
492+
* in the form:
493+
*
494+
* nint + sdm/65536
495+
*
496+
* where nint,sdm are integers and 0 < nint, 0 <= sdm < 65536
497+
*
498+
* Scaling to fixed point and rounding:
499+
*
500+
* vco_div = 65536*(nint + sdm/65536) = int( 0.5 + 65536 * vco_freq / (2 * pll_ref) )
501+
* vco_div = 65536*nint + sdm = int( (pll_ref + 65536 * vco_freq) / (2 * pll_ref) )
502+
*/
503+
504+
vco_div = (pll_ref + 65536 * vco_freq) / (2 * pll_ref);
505+
nint = (uint32_t) (vco_div / 65536);
506+
sdm = (uint32_t) (vco_div % 65536);
507+
508+
#if 0
509+
{
510+
uint64_t actual_vco = (uint64_t)2 * pll_ref * nint + (uint64_t)2 * pll_ref * sdm / 65536;
511+
fprintf(stderr, "[R82XX] requested %uHz; selected mix_div=%u vco_freq=%lu nint=%u sdm=%u; actual_vco=%lu; tuning error=%+dHz\n",
512+
freq, mix_div, vco_freq, nint, sdm, actual_vco, (int32_t) (actual_vco - vco_freq) / mix_div);
513+
}
514+
#endif
490515

491516
if (nint > ((128 / vco_power_ref) - 1)) {
492517
fprintf(stderr, "[R82XX] No valid PLL values for %u Hz!\n", freq);
@@ -501,7 +526,7 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
501526
return rc;
502527

503528
/* pw_sdm */
504-
if (!vco_fra)
529+
if (sdm == 0)
505530
val = 0x08;
506531
else
507532
val = 0x00;
@@ -510,17 +535,6 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
510535
if (rc < 0)
511536
return rc;
512537

513-
/* sdm calculator */
514-
while (vco_fra > 1) {
515-
if (vco_fra > (2 * pll_ref_khz / n_sdm)) {
516-
sdm = sdm + 32768 / (n_sdm / 2);
517-
vco_fra = vco_fra - 2 * pll_ref_khz / n_sdm;
518-
if (n_sdm >= 0x8000)
519-
break;
520-
}
521-
n_sdm <<= 1;
522-
}
523-
524538
rc = r82xx_write_reg(priv, 0x16, sdm >> 8);
525539
if (rc < 0)
526540
return rc;

0 commit comments

Comments
 (0)