aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-07-23 19:28:23 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-26 11:54:18 -0400
commitf8f6296adad30cadd65555dfde489d1080b2001c (patch)
treeced8241e11edc65dff96e9602369785ddb83eae0
parentfff4205f1d64163132609942314e94ec3ba2ed6b (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.c41
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);