diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-audio.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 463 |
1 files changed, 345 insertions, 118 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 2f846f5e0f9f..45608d50529c 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -23,87 +23,137 @@ | |||
23 | 23 | ||
24 | #include "cx25840-core.h" | 24 | #include "cx25840-core.h" |
25 | 25 | ||
26 | static int set_audclk_freq(struct i2c_client *client, u32 freq) | 26 | /* |
27 | * Note: The PLL and SRC parameters are based on a reference frequency that | ||
28 | * would ideally be: | ||
29 | * | ||
30 | * NTSC Color subcarrier freq * 8 = 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz | ||
31 | * | ||
32 | * However, it's not the exact reference frequency that matters, only that the | ||
33 | * firmware and modules that comprise the driver for a particular board all | ||
34 | * use the same value (close to the ideal value). | ||
35 | * | ||
36 | * Comments below will note which reference frequency is assumed for various | ||
37 | * parameters. They will usually be one of | ||
38 | * | ||
39 | * ref_freq = 28.636360 MHz | ||
40 | * or | ||
41 | * ref_freq = 28.636363 MHz | ||
42 | */ | ||
43 | |||
44 | static int cx25840_set_audclk_freq(struct i2c_client *client, u32 freq) | ||
27 | { | 45 | { |
28 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | 46 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
29 | 47 | ||
30 | if (freq != 32000 && freq != 44100 && freq != 48000) | ||
31 | return -EINVAL; | ||
32 | |||
33 | /* common for all inputs and rates */ | ||
34 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | ||
35 | if (!state->is_cx23885 && !state->is_cx231xx) | ||
36 | cx25840_write(client, 0x127, 0x50); | ||
37 | |||
38 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | 48 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
39 | switch (freq) { | 49 | switch (freq) { |
40 | case 32000: | 50 | case 32000: |
41 | if (state->is_cx23885) { | 51 | /* |
42 | /* We don't have register values | 52 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
43 | * so avoid destroying registers. */ | 53 | * AUX_PLL Integer = 0x06, AUX PLL Post Divider = 0x10 |
44 | break; | 54 | */ |
45 | } | 55 | cx25840_write4(client, 0x108, 0x1006040f); |
46 | 56 | ||
47 | if (!state->is_cx231xx) { | 57 | /* |
48 | /* VID_PLL and AUX_PLL */ | 58 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe |
49 | cx25840_write4(client, 0x108, 0x1006040f); | 59 | * 28636360 * 0xf.15f17f0/4 = 108 MHz |
50 | 60 | * 432 MHz pre-postdivide | |
51 | /* AUX_PLL_FRAC */ | 61 | */ |
52 | cx25840_write4(client, 0x110, 0x01bb39ee); | 62 | |
53 | } | 63 | /* |
54 | 64 | * AUX_PLL Fraction = 0x1bb39ee | |
55 | if (state->is_cx25836) | 65 | * 28636363 * 0x6.dd9cf70/0x10 = 32000 * 384 |
66 | * 196.6 MHz pre-postdivide | ||
67 | * FIXME < 200 MHz is out of specified valid range | ||
68 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
69 | */ | ||
70 | cx25840_write4(client, 0x110, 0x01bb39ee); | ||
71 | |||
72 | /* | ||
73 | * SA_MCLK_SEL = 1 | ||
74 | * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider | ||
75 | */ | ||
76 | cx25840_write(client, 0x127, 0x50); | ||
77 | |||
78 | if (is_cx2583x(state)) | ||
56 | break; | 79 | break; |
57 | 80 | ||
58 | /* src3/4/6_ctl = 0x0801f77f */ | 81 | /* src3/4/6_ctl */ |
82 | /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */ | ||
59 | cx25840_write4(client, 0x900, 0x0801f77f); | 83 | cx25840_write4(client, 0x900, 0x0801f77f); |
60 | cx25840_write4(client, 0x904, 0x0801f77f); | 84 | cx25840_write4(client, 0x904, 0x0801f77f); |
61 | cx25840_write4(client, 0x90c, 0x0801f77f); | 85 | cx25840_write4(client, 0x90c, 0x0801f77f); |
62 | break; | 86 | break; |
63 | 87 | ||
64 | case 44100: | 88 | case 44100: |
65 | if (state->is_cx23885) { | 89 | /* |
66 | /* We don't have register values | 90 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
67 | * so avoid destroying registers. */ | 91 | * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x10 |
92 | */ | ||
93 | cx25840_write4(client, 0x108, 0x1009040f); | ||
94 | |||
95 | /* | ||
96 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe | ||
97 | * 28636360 * 0xf.15f17f0/4 = 108 MHz | ||
98 | * 432 MHz pre-postdivide | ||
99 | */ | ||
100 | |||
101 | /* | ||
102 | * AUX_PLL Fraction = 0x0ec6bd6 | ||
103 | * 28636363 * 0x9.7635eb0/0x10 = 44100 * 384 | ||
104 | * 271 MHz pre-postdivide | ||
105 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
106 | */ | ||
107 | cx25840_write4(client, 0x110, 0x00ec6bd6); | ||
108 | |||
109 | /* | ||
110 | * SA_MCLK_SEL = 1 | ||
111 | * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider | ||
112 | */ | ||
113 | cx25840_write(client, 0x127, 0x50); | ||
114 | |||
115 | if (is_cx2583x(state)) | ||
68 | break; | 116 | break; |
69 | } | ||
70 | |||
71 | if (!state->is_cx231xx) { | ||
72 | /* VID_PLL and AUX_PLL */ | ||
73 | cx25840_write4(client, 0x108, 0x1009040f); | ||
74 | |||
75 | /* AUX_PLL_FRAC */ | ||
76 | cx25840_write4(client, 0x110, 0x00ec6bd6); | ||
77 | } | ||
78 | 117 | ||
79 | if (state->is_cx25836) | 118 | /* src3/4/6_ctl */ |
80 | break; | 119 | /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */ |
81 | |||
82 | /* src3/4/6_ctl = 0x08016d59 */ | ||
83 | cx25840_write4(client, 0x900, 0x08016d59); | 120 | cx25840_write4(client, 0x900, 0x08016d59); |
84 | cx25840_write4(client, 0x904, 0x08016d59); | 121 | cx25840_write4(client, 0x904, 0x08016d59); |
85 | cx25840_write4(client, 0x90c, 0x08016d59); | 122 | cx25840_write4(client, 0x90c, 0x08016d59); |
86 | break; | 123 | break; |
87 | 124 | ||
88 | case 48000: | 125 | case 48000: |
89 | if (state->is_cx23885) { | 126 | /* |
90 | /* We don't have register values | 127 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
91 | * so avoid destroying registers. */ | 128 | * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x10 |
92 | break; | 129 | */ |
93 | } | 130 | cx25840_write4(client, 0x108, 0x100a040f); |
94 | 131 | ||
95 | if (!state->is_cx231xx) { | 132 | /* |
96 | /* VID_PLL and AUX_PLL */ | 133 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe |
97 | cx25840_write4(client, 0x108, 0x100a040f); | 134 | * 28636360 * 0xf.15f17f0/4 = 108 MHz |
98 | 135 | * 432 MHz pre-postdivide | |
99 | /* AUX_PLL_FRAC */ | 136 | */ |
100 | cx25840_write4(client, 0x110, 0x0098d6e5); | 137 | |
101 | } | 138 | /* |
102 | 139 | * AUX_PLL Fraction = 0x098d6e5 | |
103 | if (state->is_cx25836) | 140 | * 28636363 * 0xa.4c6b728/0x10 = 48000 * 384 |
141 | * 295 MHz pre-postdivide | ||
142 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
143 | */ | ||
144 | cx25840_write4(client, 0x110, 0x0098d6e5); | ||
145 | |||
146 | /* | ||
147 | * SA_MCLK_SEL = 1 | ||
148 | * SA_MCLK_DIV = 0x10 = 384/384 * AUX_PLL post dvivider | ||
149 | */ | ||
150 | cx25840_write(client, 0x127, 0x50); | ||
151 | |||
152 | if (is_cx2583x(state)) | ||
104 | break; | 153 | break; |
105 | 154 | ||
106 | /* src3/4/6_ctl = 0x08014faa */ | 155 | /* src3/4/6_ctl */ |
156 | /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ | ||
107 | cx25840_write4(client, 0x900, 0x08014faa); | 157 | cx25840_write4(client, 0x900, 0x08014faa); |
108 | cx25840_write4(client, 0x904, 0x08014faa); | 158 | cx25840_write4(client, 0x904, 0x08014faa); |
109 | cx25840_write4(client, 0x90c, 0x08014faa); | 159 | cx25840_write4(client, 0x90c, 0x08014faa); |
@@ -112,91 +162,249 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
112 | } else { | 162 | } else { |
113 | switch (freq) { | 163 | switch (freq) { |
114 | case 32000: | 164 | case 32000: |
115 | if (state->is_cx23885) { | 165 | /* |
116 | /* We don't have register values | 166 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
117 | * so avoid destroying registers. */ | 167 | * AUX_PLL Integer = 0x08, AUX PLL Post Divider = 0x1e |
118 | break; | 168 | */ |
119 | } | 169 | cx25840_write4(client, 0x108, 0x1e08040f); |
120 | 170 | ||
121 | if (!state->is_cx231xx) { | 171 | /* |
122 | /* VID_PLL and AUX_PLL */ | 172 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe |
123 | cx25840_write4(client, 0x108, 0x1e08040f); | 173 | * 28636360 * 0xf.15f17f0/4 = 108 MHz |
124 | 174 | * 432 MHz pre-postdivide | |
125 | /* AUX_PLL_FRAC */ | 175 | */ |
126 | cx25840_write4(client, 0x110, 0x012a0869); | 176 | |
127 | } | 177 | /* |
178 | * AUX_PLL Fraction = 0x12a0869 | ||
179 | * 28636363 * 0x8.9504348/0x1e = 32000 * 256 | ||
180 | * 246 MHz pre-postdivide | ||
181 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
182 | */ | ||
183 | cx25840_write4(client, 0x110, 0x012a0869); | ||
184 | |||
185 | /* | ||
186 | * SA_MCLK_SEL = 1 | ||
187 | * SA_MCLK_DIV = 0x14 = 256/384 * AUX_PLL post dvivider | ||
188 | */ | ||
189 | cx25840_write(client, 0x127, 0x54); | ||
128 | 190 | ||
129 | if (state->is_cx25836) | 191 | if (is_cx2583x(state)) |
130 | break; | 192 | break; |
131 | 193 | ||
132 | /* src1_ctl = 0x08010000 */ | 194 | /* src1_ctl */ |
195 | /* 0x1.0000 = 32000/32000 */ | ||
133 | cx25840_write4(client, 0x8f8, 0x08010000); | 196 | cx25840_write4(client, 0x8f8, 0x08010000); |
134 | 197 | ||
135 | /* src3/4/6_ctl = 0x08020000 */ | 198 | /* src3/4/6_ctl */ |
199 | /* 0x2.0000 = 2 * (32000/32000) */ | ||
136 | cx25840_write4(client, 0x900, 0x08020000); | 200 | cx25840_write4(client, 0x900, 0x08020000); |
137 | cx25840_write4(client, 0x904, 0x08020000); | 201 | cx25840_write4(client, 0x904, 0x08020000); |
138 | cx25840_write4(client, 0x90c, 0x08020000); | 202 | cx25840_write4(client, 0x90c, 0x08020000); |
139 | |||
140 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ | ||
141 | cx25840_write(client, 0x127, 0x54); | ||
142 | break; | 203 | break; |
143 | 204 | ||
144 | case 44100: | 205 | case 44100: |
145 | if (state->is_cx23885) { | 206 | /* |
146 | /* We don't have register values | 207 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
147 | * so avoid destroying registers. */ | 208 | * AUX_PLL Integer = 0x09, AUX PLL Post Divider = 0x18 |
148 | break; | 209 | */ |
149 | } | 210 | cx25840_write4(client, 0x108, 0x1809040f); |
150 | 211 | ||
151 | 212 | /* | |
152 | if (!state->is_cx231xx) { | 213 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe |
153 | /* VID_PLL and AUX_PLL */ | 214 | * 28636360 * 0xf.15f17f0/4 = 108 MHz |
154 | cx25840_write4(client, 0x108, 0x1809040f); | 215 | * 432 MHz pre-postdivide |
155 | 216 | */ | |
156 | /* AUX_PLL_FRAC */ | 217 | |
157 | cx25840_write4(client, 0x110, 0x00ec6bd6); | 218 | /* |
158 | } | 219 | * AUX_PLL Fraction = 0x0ec6bd6 |
159 | 220 | * 28636363 * 0x9.7635eb0/0x18 = 44100 * 256 | |
160 | if (state->is_cx25836) | 221 | * 271 MHz pre-postdivide |
222 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
223 | */ | ||
224 | cx25840_write4(client, 0x110, 0x00ec6bd6); | ||
225 | |||
226 | /* | ||
227 | * SA_MCLK_SEL = 1 | ||
228 | * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider | ||
229 | */ | ||
230 | cx25840_write(client, 0x127, 0x50); | ||
231 | |||
232 | if (is_cx2583x(state)) | ||
161 | break; | 233 | break; |
162 | 234 | ||
163 | /* src1_ctl = 0x08010000 */ | 235 | /* src1_ctl */ |
236 | /* 0x1.60cd = 44100/32000 */ | ||
164 | cx25840_write4(client, 0x8f8, 0x080160cd); | 237 | cx25840_write4(client, 0x8f8, 0x080160cd); |
165 | 238 | ||
166 | /* src3/4/6_ctl = 0x08020000 */ | 239 | /* src3/4/6_ctl */ |
240 | /* 0x1.7385 = 2 * (32000/44100) */ | ||
167 | cx25840_write4(client, 0x900, 0x08017385); | 241 | cx25840_write4(client, 0x900, 0x08017385); |
168 | cx25840_write4(client, 0x904, 0x08017385); | 242 | cx25840_write4(client, 0x904, 0x08017385); |
169 | cx25840_write4(client, 0x90c, 0x08017385); | 243 | cx25840_write4(client, 0x90c, 0x08017385); |
170 | break; | 244 | break; |
171 | 245 | ||
172 | case 48000: | 246 | case 48000: |
173 | if (!state->is_cx23885 && !state->is_cx231xx) { | 247 | /* |
174 | /* VID_PLL and AUX_PLL */ | 248 | * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 |
175 | cx25840_write4(client, 0x108, 0x180a040f); | 249 | * AUX_PLL Integer = 0x0a, AUX PLL Post Divider = 0x18 |
250 | */ | ||
251 | cx25840_write4(client, 0x108, 0x180a040f); | ||
252 | |||
253 | /* | ||
254 | * VID_PLL Fraction (register 0x10c) = 0x2be2fe | ||
255 | * 28636360 * 0xf.15f17f0/4 = 108 MHz | ||
256 | * 432 MHz pre-postdivide | ||
257 | */ | ||
258 | |||
259 | /* | ||
260 | * AUX_PLL Fraction = 0x098d6e5 | ||
261 | * 28636363 * 0xa.4c6b728/0x18 = 48000 * 256 | ||
262 | * 295 MHz pre-postdivide | ||
263 | * FIXME 28636363 ref_freq doesn't match VID PLL ref | ||
264 | */ | ||
265 | cx25840_write4(client, 0x110, 0x0098d6e5); | ||
266 | |||
267 | /* | ||
268 | * SA_MCLK_SEL = 1 | ||
269 | * SA_MCLK_DIV = 0x10 = 256/384 * AUX_PLL post dvivider | ||
270 | */ | ||
271 | cx25840_write(client, 0x127, 0x50); | ||
272 | |||
273 | if (is_cx2583x(state)) | ||
274 | break; | ||
176 | 275 | ||
177 | /* AUX_PLL_FRAC */ | 276 | /* src1_ctl */ |
178 | cx25840_write4(client, 0x110, 0x0098d6e5); | 277 | /* 0x1.8000 = 48000/32000 */ |
179 | } | 278 | cx25840_write4(client, 0x8f8, 0x08018000); |
180 | 279 | ||
181 | if (state->is_cx25836) | 280 | /* src3/4/6_ctl */ |
182 | break; | 281 | /* 0x1.5555 = 2 * (32000/48000) */ |
282 | cx25840_write4(client, 0x900, 0x08015555); | ||
283 | cx25840_write4(client, 0x904, 0x08015555); | ||
284 | cx25840_write4(client, 0x90c, 0x08015555); | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | state->audclk_freq = freq; | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq) | ||
295 | { | ||
296 | return cx25840_set_audclk_freq(client, freq); | ||
297 | } | ||
298 | |||
299 | static int cx23885_set_audclk_freq(struct i2c_client *client, u32 freq) | ||
300 | { | ||
301 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | ||
302 | |||
303 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | ||
304 | switch (freq) { | ||
305 | case 32000: | ||
306 | case 44100: | ||
307 | case 48000: | ||
308 | /* We don't have register values | ||
309 | * so avoid destroying registers. */ | ||
310 | /* FIXME return -EINVAL; */ | ||
311 | break; | ||
312 | } | ||
313 | } else { | ||
314 | switch (freq) { | ||
315 | case 32000: | ||
316 | case 44100: | ||
317 | /* We don't have register values | ||
318 | * so avoid destroying registers. */ | ||
319 | /* FIXME return -EINVAL; */ | ||
320 | break; | ||
321 | |||
322 | case 48000: | ||
323 | /* src1_ctl */ | ||
324 | /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */ | ||
325 | cx25840_write4(client, 0x8f8, 0x0801867c); | ||
326 | |||
327 | /* src3/4/6_ctl */ | ||
328 | /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ | ||
329 | cx25840_write4(client, 0x900, 0x08014faa); | ||
330 | cx25840_write4(client, 0x904, 0x08014faa); | ||
331 | cx25840_write4(client, 0x90c, 0x08014faa); | ||
332 | break; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | state->audclk_freq = freq; | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int cx231xx_set_audclk_freq(struct i2c_client *client, u32 freq) | ||
342 | { | ||
343 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | ||
344 | |||
345 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | ||
346 | switch (freq) { | ||
347 | case 32000: | ||
348 | /* src3/4/6_ctl */ | ||
349 | /* 0x1.f77f = (4 * 28636360/8 * 2/455) / 32000 */ | ||
350 | cx25840_write4(client, 0x900, 0x0801f77f); | ||
351 | cx25840_write4(client, 0x904, 0x0801f77f); | ||
352 | cx25840_write4(client, 0x90c, 0x0801f77f); | ||
353 | break; | ||
354 | |||
355 | case 44100: | ||
356 | /* src3/4/6_ctl */ | ||
357 | /* 0x1.6d59 = (4 * 28636360/8 * 2/455) / 44100 */ | ||
358 | cx25840_write4(client, 0x900, 0x08016d59); | ||
359 | cx25840_write4(client, 0x904, 0x08016d59); | ||
360 | cx25840_write4(client, 0x90c, 0x08016d59); | ||
361 | break; | ||
362 | |||
363 | case 48000: | ||
364 | /* src3/4/6_ctl */ | ||
365 | /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ | ||
366 | cx25840_write4(client, 0x900, 0x08014faa); | ||
367 | cx25840_write4(client, 0x904, 0x08014faa); | ||
368 | cx25840_write4(client, 0x90c, 0x08014faa); | ||
369 | break; | ||
370 | } | ||
371 | } else { | ||
372 | switch (freq) { | ||
373 | /* FIXME These cases make different assumptions about audclk */ | ||
374 | case 32000: | ||
375 | /* src1_ctl */ | ||
376 | /* 0x1.0000 = 32000/32000 */ | ||
377 | cx25840_write4(client, 0x8f8, 0x08010000); | ||
183 | 378 | ||
184 | if (!state->is_cx23885 && !state->is_cx231xx) { | 379 | /* src3/4/6_ctl */ |
185 | /* src1_ctl */ | 380 | /* 0x2.0000 = 2 * (32000/32000) */ |
186 | cx25840_write4(client, 0x8f8, 0x08018000); | 381 | cx25840_write4(client, 0x900, 0x08020000); |
382 | cx25840_write4(client, 0x904, 0x08020000); | ||
383 | cx25840_write4(client, 0x90c, 0x08020000); | ||
384 | break; | ||
187 | 385 | ||
188 | /* src3/4/6_ctl */ | 386 | case 44100: |
189 | cx25840_write4(client, 0x900, 0x08015555); | 387 | /* src1_ctl */ |
190 | cx25840_write4(client, 0x904, 0x08015555); | 388 | /* 0x1.60cd = 44100/32000 */ |
191 | cx25840_write4(client, 0x90c, 0x08015555); | 389 | cx25840_write4(client, 0x8f8, 0x080160cd); |
192 | } else { | ||
193 | 390 | ||
194 | cx25840_write4(client, 0x8f8, 0x0801867c); | 391 | /* src3/4/6_ctl */ |
392 | /* 0x1.7385 = 2 * (32000/44100) */ | ||
393 | cx25840_write4(client, 0x900, 0x08017385); | ||
394 | cx25840_write4(client, 0x904, 0x08017385); | ||
395 | cx25840_write4(client, 0x90c, 0x08017385); | ||
396 | break; | ||
195 | 397 | ||
196 | cx25840_write4(client, 0x900, 0x08014faa); | 398 | case 48000: |
197 | cx25840_write4(client, 0x904, 0x08014faa); | 399 | /* src1_ctl */ |
198 | cx25840_write4(client, 0x90c, 0x08014faa); | 400 | /* 0x1.867c = 48000 / (2 * 28636360/8 * 2/455) */ |
199 | } | 401 | cx25840_write4(client, 0x8f8, 0x0801867c); |
402 | |||
403 | /* src3/4/6_ctl */ | ||
404 | /* 0x1.4faa = (4 * 28636360/8 * 2/455) / 48000 */ | ||
405 | cx25840_write4(client, 0x900, 0x08014faa); | ||
406 | cx25840_write4(client, 0x904, 0x08014faa); | ||
407 | cx25840_write4(client, 0x90c, 0x08014faa); | ||
200 | break; | 408 | break; |
201 | } | 409 | } |
202 | } | 410 | } |
@@ -206,6 +414,25 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
206 | return 0; | 414 | return 0; |
207 | } | 415 | } |
208 | 416 | ||
417 | static int set_audclk_freq(struct i2c_client *client, u32 freq) | ||
418 | { | ||
419 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | ||
420 | |||
421 | if (freq != 32000 && freq != 44100 && freq != 48000) | ||
422 | return -EINVAL; | ||
423 | |||
424 | if (is_cx231xx(state)) | ||
425 | return cx231xx_set_audclk_freq(client, freq); | ||
426 | |||
427 | if (is_cx2388x(state)) | ||
428 | return cx23885_set_audclk_freq(client, freq); | ||
429 | |||
430 | if (is_cx2583x(state)) | ||
431 | return cx25836_set_audclk_freq(client, freq); | ||
432 | |||
433 | return cx25840_set_audclk_freq(client, freq); | ||
434 | } | ||
435 | |||
209 | void cx25840_audio_set_path(struct i2c_client *client) | 436 | void cx25840_audio_set_path(struct i2c_client *client) |
210 | { | 437 | { |
211 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | 438 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
@@ -243,7 +470,7 @@ void cx25840_audio_set_path(struct i2c_client *client) | |||
243 | cx25840_and_or(client, 0x810, ~0x1, 0x00); | 470 | cx25840_and_or(client, 0x810, ~0x1, 0x00); |
244 | 471 | ||
245 | /* Ensure the controller is running when we exit */ | 472 | /* Ensure the controller is running when we exit */ |
246 | if (state->is_cx23885 || state->is_cx231xx) | 473 | if (is_cx2388x(state) || is_cx231xx(state)) |
247 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 474 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
248 | } | 475 | } |
249 | 476 | ||
@@ -383,7 +610,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) | |||
383 | struct cx25840_state *state = to_state(sd); | 610 | struct cx25840_state *state = to_state(sd); |
384 | int retval; | 611 | int retval; |
385 | 612 | ||
386 | if (!state->is_cx25836) | 613 | if (!is_cx2583x(state)) |
387 | cx25840_and_or(client, 0x810, ~0x1, 1); | 614 | cx25840_and_or(client, 0x810, ~0x1, 1); |
388 | if (state->aud_input != CX25840_AUDIO_SERIAL) { | 615 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
389 | cx25840_and_or(client, 0x803, ~0x10, 0); | 616 | cx25840_and_or(client, 0x803, ~0x10, 0); |
@@ -392,7 +619,7 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) | |||
392 | retval = set_audclk_freq(client, freq); | 619 | retval = set_audclk_freq(client, freq); |
393 | if (state->aud_input != CX25840_AUDIO_SERIAL) | 620 | if (state->aud_input != CX25840_AUDIO_SERIAL) |
394 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 621 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
395 | if (!state->is_cx25836) | 622 | if (!is_cx2583x(state)) |
396 | cx25840_and_or(client, 0x810, ~0x1, 0); | 623 | cx25840_and_or(client, 0x810, ~0x1, 0); |
397 | return retval; | 624 | return retval; |
398 | } | 625 | } |