Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] msi2500: revise synthesizer calculation

Update synthesizer calculation to model I prefer nowadays. It is mostly
just renaming some variables, but also minor functionality change how
integer and fractional part are divided (using div_u64_rem()). Also, add
'schematic' of synthesizer following my current understanding.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Antti Palosaari and committed by
Mauro Carvalho Chehab
faf22b13 83e64b4d

+34 -15
+34 -15
drivers/media/usb/msi2500/msi2500.c
··· 682 682 return ret; 683 683 } 684 684 685 - #define F_REF 24000000 686 - #define DIV_R_IN 2 687 685 static int msi2500_set_usb_adc(struct msi2500_state *s) 688 686 { 689 - int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract; 687 + int ret; 688 + unsigned int f_vco, f_sr, div_n, k, k_cw, div_out; 690 689 u32 reg3, reg4, reg7; 691 690 struct v4l2_ctrl *bandwidth_auto; 692 691 struct v4l2_ctrl *bandwidth; ··· 727 728 } 728 729 729 730 /* 731 + * Fractional-N synthesizer 732 + * 733 + * +----------------------------------------+ 734 + * v | 735 + * Fref +----+ +-------+ +-----+ +------+ +---+ 736 + * ------> | PD | --> | VCO | --> | /2 | ------> | /N.F | <-- | K | 737 + * +----+ +-------+ +-----+ +------+ +---+ 738 + * | 739 + * | 740 + * v 741 + * +-------+ +-----+ Fout 742 + * | /Rout | --> | /12 | ------> 743 + * +-------+ +-----+ 744 + */ 745 + /* 730 746 * Synthesizer config is just a educated guess... 731 747 * 732 748 * [7:0] 0x03, register address ··· 768 754 * 769 755 * VCO 202000000 - 720000000++ 770 756 */ 757 + 758 + #define F_REF 24000000 759 + #define DIV_PRE_N 2 760 + #define DIV_LO_OUT 12 771 761 reg3 = 0x01000303; 772 762 reg4 = 0x00000004; 773 763 774 - /* XXX: Filters? AGC? */ 764 + /* XXX: Filters? AGC? VCO band? */ 775 765 if (f_sr < 6000000) 776 766 reg3 |= 0x1 << 20; 777 767 else if (f_sr < 7000000) ··· 785 767 else 786 768 reg3 |= 0xd << 20; 787 769 788 - for (div_r_out = 4; div_r_out < 16; div_r_out += 2) { 789 - f_vco = f_sr * div_r_out * 12; 790 - dev_dbg(s->dev, "div_r_out=%d f_vco=%d\n", div_r_out, f_vco); 770 + for (div_out = 4; div_out < 16; div_out += 2) { 771 + f_vco = f_sr * div_out * DIV_LO_OUT; 772 + dev_dbg(s->dev, "div_out=%d f_vco=%d\n", div_out, f_vco); 791 773 if (f_vco >= 202000000) 792 774 break; 793 775 } 794 776 795 - div_n = f_vco / (F_REF * DIV_R_IN); 796 - div_m = f_vco % (F_REF * DIV_R_IN); 797 - fract = 0x200000ul * div_m / (F_REF * DIV_R_IN); 777 + /* Calculate PLL integer and fractional control word. */ 778 + div_n = div_u64_rem(f_vco, DIV_PRE_N * F_REF, &k); 779 + k_cw = div_u64((u64) k * 0x200000, DIV_PRE_N * F_REF); 798 780 799 781 reg3 |= div_n << 16; 800 - reg3 |= (div_r_out / 2 - 1) << 10; 801 - reg3 |= ((fract >> 20) & 0x000001) << 15; /* [20] */ 802 - reg4 |= ((fract >> 0) & 0x0fffff) << 8; /* [19:0] */ 782 + reg3 |= (div_out / 2 - 1) << 10; 783 + reg3 |= ((k_cw >> 20) & 0x000001) << 15; /* [20] */ 784 + reg4 |= ((k_cw >> 0) & 0x0fffff) << 8; /* [19:0] */ 803 785 804 - dev_dbg(s->dev, "f_sr=%d f_vco=%d div_n=%d div_m=%d div_r_out=%d reg3=%08x reg4=%08x\n", 805 - f_sr, f_vco, div_n, div_m, div_r_out, reg3, reg4); 786 + dev_dbg(s->dev, 787 + "f_sr=%u f_vco=%u div_n=%u k=%u div_out=%u reg3=%08x reg4=%08x\n", 788 + f_sr, f_vco, div_n, k, div_out, reg3, reg4); 806 789 807 790 ret = msi2500_ctrl_msg(s, CMD_WREG, 0x00608008); 808 791 if (ret)