diff options
author | Andy Walls <awalls@radix.net> | 2008-07-23 19:28:23 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-26 11:54:18 -0400 |
commit | f8f6296adad30cadd65555dfde489d1080b2001c (patch) | |
tree | ced8241e11edc65dff96e9602369785ddb83eae0 | |
parent | fff4205f1d64163132609942314e94ec3ba2ed6b (diff) |
V4L/DVB (8461): cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input
cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input so it
works. The AUX_PLL VCO was being operated at 196.6 MHz out of the spec'ed
200-600 MHz range. Fixed the multipler and post dividers to operate the VCO
within specification and added comments on how magic numbers are derived.
Thanks to Hans Verkuil for pointing out this interesting problem to solve.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/cx18/cx18-av-audio.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index c40a286de1b9..7245d37ef34f 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c | |||
@@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
30 | if (freq != 32000 && freq != 44100 && freq != 48000) | 30 | if (freq != 32000 && freq != 44100 && freq != 48000) |
31 | return -EINVAL; | 31 | return -EINVAL; |
32 | 32 | ||
33 | /* common for all inputs and rates */ | ||
34 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 33 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
35 | cx18_av_write(cx, 0x127, 0x50); | 34 | cx18_av_write(cx, 0x127, 0x50); |
36 | 35 | ||
@@ -38,15 +37,20 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
38 | switch (freq) { | 37 | switch (freq) { |
39 | case 32000: | 38 | case 32000: |
40 | /* VID_PLL and AUX_PLL */ | 39 | /* VID_PLL and AUX_PLL */ |
41 | cx18_av_write4(cx, 0x108, 0x1006040f); | 40 | cx18_av_write4(cx, 0x108, 0x1408040f); |
42 | 41 | ||
43 | /* AUX_PLL_FRAC */ | 42 | /* AUX_PLL_FRAC */ |
44 | cx18_av_write4(cx, 0x110, 0x01bb39ee); | 43 | /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */ |
44 | cx18_av_write4(cx, 0x110, 0x012a0863); | ||
45 | 45 | ||
46 | /* src3/4/6_ctl = 0x0801f77f */ | 46 | /* src3/4/6_ctl */ |
47 | /* 0x1.f77f = (4 * 15734.26) / 32000 */ | ||
47 | cx18_av_write4(cx, 0x900, 0x0801f77f); | 48 | cx18_av_write4(cx, 0x900, 0x0801f77f); |
48 | cx18_av_write4(cx, 0x904, 0x0801f77f); | 49 | cx18_av_write4(cx, 0x904, 0x0801f77f); |
49 | cx18_av_write4(cx, 0x90c, 0x0801f77f); | 50 | cx18_av_write4(cx, 0x90c, 0x0801f77f); |
51 | |||
52 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ | ||
53 | cx18_av_write(cx, 0x127, 0x54); | ||
50 | break; | 54 | break; |
51 | 55 | ||
52 | case 44100: | 56 | case 44100: |
@@ -54,9 +58,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
54 | cx18_av_write4(cx, 0x108, 0x1009040f); | 58 | cx18_av_write4(cx, 0x108, 0x1009040f); |
55 | 59 | ||
56 | /* AUX_PLL_FRAC */ | 60 | /* AUX_PLL_FRAC */ |
61 | /* 0x9.7635eb * 28,636,363 / 0x10 = 44100 * 384 */ | ||
57 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); | 62 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); |
58 | 63 | ||
59 | /* src3/4/6_ctl = 0x08016d59 */ | 64 | /* src3/4/6_ctl */ |
65 | /* 0x1.6d59 = (4 * 15734.26) / 44100 */ | ||
60 | cx18_av_write4(cx, 0x900, 0x08016d59); | 66 | cx18_av_write4(cx, 0x900, 0x08016d59); |
61 | cx18_av_write4(cx, 0x904, 0x08016d59); | 67 | cx18_av_write4(cx, 0x904, 0x08016d59); |
62 | cx18_av_write4(cx, 0x90c, 0x08016d59); | 68 | cx18_av_write4(cx, 0x90c, 0x08016d59); |
@@ -67,9 +73,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
67 | cx18_av_write4(cx, 0x108, 0x100a040f); | 73 | cx18_av_write4(cx, 0x108, 0x100a040f); |
68 | 74 | ||
69 | /* AUX_PLL_FRAC */ | 75 | /* AUX_PLL_FRAC */ |
76 | /* 0xa.4c6b728 * 28,636,363 / 0x10 = 48000 * 384 */ | ||
70 | cx18_av_write4(cx, 0x110, 0x0098d6e5); | 77 | cx18_av_write4(cx, 0x110, 0x0098d6e5); |
71 | 78 | ||
72 | /* src3/4/6_ctl = 0x08014faa */ | 79 | /* src3/4/6_ctl */ |
80 | /* 0x1.4faa = (4 * 15734.26) / 48000 */ | ||
73 | cx18_av_write4(cx, 0x900, 0x08014faa); | 81 | cx18_av_write4(cx, 0x900, 0x08014faa); |
74 | cx18_av_write4(cx, 0x904, 0x08014faa); | 82 | cx18_av_write4(cx, 0x904, 0x08014faa); |
75 | cx18_av_write4(cx, 0x90c, 0x08014faa); | 83 | cx18_av_write4(cx, 0x90c, 0x08014faa); |
@@ -82,12 +90,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
82 | cx18_av_write4(cx, 0x108, 0x1e08040f); | 90 | cx18_av_write4(cx, 0x108, 0x1e08040f); |
83 | 91 | ||
84 | /* AUX_PLL_FRAC */ | 92 | /* AUX_PLL_FRAC */ |
93 | /* 0x8.9504348 * 28,636,363 / 0x1e = 32000 * 256 */ | ||
85 | cx18_av_write4(cx, 0x110, 0x012a0869); | 94 | cx18_av_write4(cx, 0x110, 0x012a0869); |
86 | 95 | ||
87 | /* src1_ctl = 0x08010000 */ | 96 | /* src1_ctl */ |
97 | /* 0x1.0000 = 32000/32000 */ | ||
88 | cx18_av_write4(cx, 0x8f8, 0x08010000); | 98 | cx18_av_write4(cx, 0x8f8, 0x08010000); |
89 | 99 | ||
90 | /* src3/4/6_ctl = 0x08020000 */ | 100 | /* src3/4/6_ctl */ |
101 | /* 0x2.0000 = 2 * (32000/32000) */ | ||
91 | cx18_av_write4(cx, 0x900, 0x08020000); | 102 | cx18_av_write4(cx, 0x900, 0x08020000); |
92 | cx18_av_write4(cx, 0x904, 0x08020000); | 103 | cx18_av_write4(cx, 0x904, 0x08020000); |
93 | cx18_av_write4(cx, 0x90c, 0x08020000); | 104 | cx18_av_write4(cx, 0x90c, 0x08020000); |
@@ -101,12 +112,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
101 | cx18_av_write4(cx, 0x108, 0x1809040f); | 112 | cx18_av_write4(cx, 0x108, 0x1809040f); |
102 | 113 | ||
103 | /* AUX_PLL_FRAC */ | 114 | /* AUX_PLL_FRAC */ |
115 | /* 0x9.76346B * 28,636,363 / 0x18 = 44100 * 256 */ | ||
104 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); | 116 | cx18_av_write4(cx, 0x110, 0x00ec6bd6); |
105 | 117 | ||
106 | /* src1_ctl = 0x08010000 */ | 118 | /* src1_ctl */ |
119 | /* 0x1.60cd = 44100/32000 */ | ||
107 | cx18_av_write4(cx, 0x8f8, 0x080160cd); | 120 | cx18_av_write4(cx, 0x8f8, 0x080160cd); |
108 | 121 | ||
109 | /* src3/4/6_ctl = 0x08020000 */ | 122 | /* src3/4/6_ctl */ |
123 | /* 0x1.7385 = 2 * (32000/44100) */ | ||
110 | cx18_av_write4(cx, 0x900, 0x08017385); | 124 | cx18_av_write4(cx, 0x900, 0x08017385); |
111 | cx18_av_write4(cx, 0x904, 0x08017385); | 125 | cx18_av_write4(cx, 0x904, 0x08017385); |
112 | cx18_av_write4(cx, 0x90c, 0x08017385); | 126 | cx18_av_write4(cx, 0x90c, 0x08017385); |
@@ -117,12 +131,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) | |||
117 | cx18_av_write4(cx, 0x108, 0x180a040f); | 131 | cx18_av_write4(cx, 0x108, 0x180a040f); |
118 | 132 | ||
119 | /* AUX_PLL_FRAC */ | 133 | /* AUX_PLL_FRAC */ |
134 | /* 0xa.4c6b728 * 28,636,363 / 0x18 = 48000 * 256 */ | ||
120 | cx18_av_write4(cx, 0x110, 0x0098d6e5); | 135 | cx18_av_write4(cx, 0x110, 0x0098d6e5); |
121 | 136 | ||
122 | /* src1_ctl = 0x08010000 */ | 137 | /* src1_ctl */ |
138 | /* 0x1.8000 = 48000/32000 */ | ||
123 | cx18_av_write4(cx, 0x8f8, 0x08018000); | 139 | cx18_av_write4(cx, 0x8f8, 0x08018000); |
124 | 140 | ||
125 | /* src3/4/6_ctl = 0x08020000 */ | 141 | /* src3/4/6_ctl */ |
142 | /* 0x1.5555 = 2 * (32000/48000) */ | ||
126 | cx18_av_write4(cx, 0x900, 0x08015555); | 143 | cx18_av_write4(cx, 0x900, 0x08015555); |
127 | cx18_av_write4(cx, 0x904, 0x08015555); | 144 | cx18_av_write4(cx, 0x904, 0x08015555); |
128 | cx18_av_write4(cx, 0x90c, 0x08015555); | 145 | cx18_av_write4(cx, 0x90c, 0x08015555); |