aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/media/video/cx25840
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c463
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c372
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h22
-rw-r--r--drivers/media/video/cx25840/cx25840-firmware.c10
4 files changed, 654 insertions, 213 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
26static 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
44static 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
294static inline int cx25836_set_audclk_freq(struct i2c_client *client, u32 freq)
295{
296 return cx25840_set_audclk_freq(client, freq);
297}
298
299static 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
341static 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
417static 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
209void cx25840_audio_set_path(struct i2c_client *client) 436void 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}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1aeaf18a9bea..f2461cd3de5a 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -259,6 +259,13 @@ static void cx23885_initialize(struct i2c_client *client)
259 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 259 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
260 struct workqueue_struct *q; 260 struct workqueue_struct *q;
261 261
262 /*
263 * Come out of digital power down
264 * The CX23888, at least, needs this, otherwise registers aside from
265 * 0x0-0x2 can't be read or written.
266 */
267 cx25840_write(client, 0x000, 0);
268
262 /* Internal Reset */ 269 /* Internal Reset */
263 cx25840_and_or(client, 0x102, ~0x01, 0x01); 270 cx25840_and_or(client, 0x102, ~0x01, 0x01);
264 cx25840_and_or(client, 0x102, ~0x01, 0x00); 271 cx25840_and_or(client, 0x102, ~0x01, 0x00);
@@ -269,18 +276,45 @@ static void cx23885_initialize(struct i2c_client *client)
269 /* DIF in reset? */ 276 /* DIF in reset? */
270 cx25840_write(client, 0x398, 0); 277 cx25840_write(client, 0x398, 0);
271 278
272 /* Trust the default xtal, no division */ 279 /*
273 /* This changes for the cx23888 products */ 280 * Trust the default xtal, no division
281 * '885: 28.636363... MHz
282 * '887: 25.000000 MHz
283 * '888: 50.000000 MHz
284 */
274 cx25840_write(client, 0x2, 0x76); 285 cx25840_write(client, 0x2, 0x76);
275 286
276 /* Bring down the regulator for AUX clk */ 287 /* Power up all the PLL's and DLL */
277 cx25840_write(client, 0x1, 0x40); 288 cx25840_write(client, 0x1, 0x40);
278 289
279 /* Sys PLL frac */ 290 /* Sys PLL */
280 cx25840_write4(client, 0x11c, 0x01d1744c); 291 switch (state->id) {
281 292 case V4L2_IDENT_CX23888_AV:
282 /* Sys PLL int */ 293 /*
283 cx25840_write4(client, 0x118, 0x00000416); 294 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
295 * 572.73 MHz before post divide
296 */
297 cx25840_write4(client, 0x11c, 0x00e8ba26);
298 cx25840_write4(client, 0x118, 0x0000040b);
299 break;
300 case V4L2_IDENT_CX23887_AV:
301 /*
302 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
303 * 572.73 MHz before post divide
304 */
305 cx25840_write4(client, 0x11c, 0x01d1744c);
306 cx25840_write4(client, 0x118, 0x00000416);
307 break;
308 case V4L2_IDENT_CX23885_AV:
309 default:
310 /*
311 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
312 * 572.73 MHz before post divide
313 */
314 cx25840_write4(client, 0x11c, 0x00000000);
315 cx25840_write4(client, 0x118, 0x00000414);
316 break;
317 }
284 318
285 /* Disable DIF bypass */ 319 /* Disable DIF bypass */
286 cx25840_write4(client, 0x33c, 0x00000001); 320 cx25840_write4(client, 0x33c, 0x00000001);
@@ -288,11 +322,15 @@ static void cx23885_initialize(struct i2c_client *client)
288 /* DIF Src phase inc */ 322 /* DIF Src phase inc */
289 cx25840_write4(client, 0x340, 0x0df7df83); 323 cx25840_write4(client, 0x340, 0x0df7df83);
290 324
291 /* Vid PLL frac */ 325 /*
292 cx25840_write4(client, 0x10c, 0x01b6db7b); 326 * Vid PLL
293 327 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second
294 /* Vid PLL int */ 328 *
295 cx25840_write4(client, 0x108, 0x00000512); 329 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz
330 * 432.0 MHz before post divide
331 */
332 cx25840_write4(client, 0x10c, 0x002be2c9);
333 cx25840_write4(client, 0x108, 0x0000040f);
296 334
297 /* Luma */ 335 /* Luma */
298 cx25840_write4(client, 0x414, 0x00107d12); 336 cx25840_write4(client, 0x414, 0x00107d12);
@@ -300,11 +338,43 @@ static void cx23885_initialize(struct i2c_client *client)
300 /* Chroma */ 338 /* Chroma */
301 cx25840_write4(client, 0x420, 0x3d008282); 339 cx25840_write4(client, 0x420, 0x3d008282);
302 340
303 /* Aux PLL frac */ 341 /*
304 cx25840_write4(client, 0x114, 0x017dbf48); 342 * Aux PLL
305 343 * Initial setup for audio sample clock:
306 /* Aux PLL int */ 344 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz
307 cx25840_write4(client, 0x110, 0x000a030e); 345 * Intial I2S output/master clock(?):
346 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
347 */
348 switch (state->id) {
349 case V4L2_IDENT_CX23888_AV:
350 /*
351 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
352 * 368.64 MHz before post divide
353 * 122.88 MHz / 0xa = 12.288 MHz
354 */
355 cx25840_write4(client, 0x114, 0x00bedfa4);
356 cx25840_write4(client, 0x110, 0x000a0307);
357 break;
358 case V4L2_IDENT_CX23887_AV:
359 /*
360 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
361 * 368.64 MHz before post divide
362 * 122.88 MHz / 0xa = 12.288 MHz
363 */
364 cx25840_write4(client, 0x114, 0x017dbf48);
365 cx25840_write4(client, 0x110, 0x000a030e);
366 break;
367 case V4L2_IDENT_CX23885_AV:
368 default:
369 /*
370 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
371 * 368.64 MHz before post divide
372 * 122.88 MHz / 0xa = 12.288 MHz
373 */
374 cx25840_write4(client, 0x114, 0x01bf0c9e);
375 cx25840_write4(client, 0x110, 0x000a030c);
376 break;
377 };
308 378
309 /* ADC2 input select */ 379 /* ADC2 input select */
310 cx25840_write(client, 0x102, 0x10); 380 cx25840_write(client, 0x102, 0x10);
@@ -494,7 +564,7 @@ void cx25840_std_setup(struct i2c_client *client)
494 } 564 }
495 565
496 /* DEBUG: Displays configured PLL frequency */ 566 /* DEBUG: Displays configured PLL frequency */
497 if (!state->is_cx231xx) { 567 if (!is_cx231xx(state)) {
498 pll_int = cx25840_read(client, 0x108); 568 pll_int = cx25840_read(client, 0x108);
499 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff; 569 pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
500 pll_post = cx25840_read(client, 0x109); 570 pll_post = cx25840_read(client, 0x109);
@@ -615,13 +685,30 @@ static void input_change(struct i2c_client *client)
615 } 685 }
616 cx25840_write(client, 0x80b, 0x00); 686 cx25840_write(client, 0x80b, 0x00);
617 } else if (std & V4L2_STD_PAL) { 687 } else if (std & V4L2_STD_PAL) {
618 /* Follow tuner change procedure for PAL */ 688 /* Autodetect audio standard and audio system */
619 cx25840_write(client, 0x808, 0xff); 689 cx25840_write(client, 0x808, 0xff);
620 cx25840_write(client, 0x80b, 0x10); 690 /* Since system PAL-L is pretty much non-existant and
691 not used by any public broadcast network, force
692 6.5 MHz carrier to be interpreted as System DK,
693 this avoids DK audio detection instability */
694 cx25840_write(client, 0x80b, 0x00);
621 } else if (std & V4L2_STD_SECAM) { 695 } else if (std & V4L2_STD_SECAM) {
622 /* Select autodetect for SECAM */ 696 /* Autodetect audio standard and audio system */
623 cx25840_write(client, 0x808, 0xff); 697 cx25840_write(client, 0x808, 0xff);
624 cx25840_write(client, 0x80b, 0x10); 698 /* If only one of SECAM-DK / SECAM-L is required, then force
699 6.5MHz carrier, else autodetect it */
700 if ((std & V4L2_STD_SECAM_DK) &&
701 !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
702 /* 6.5 MHz carrier to be interpreted as System DK */
703 cx25840_write(client, 0x80b, 0x00);
704 } else if (!(std & V4L2_STD_SECAM_DK) &&
705 (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {
706 /* 6.5 MHz carrier to be interpreted as System L */
707 cx25840_write(client, 0x80b, 0x08);
708 } else {
709 /* 6.5 MHz carrier to be autodetected */
710 cx25840_write(client, 0x80b, 0x10);
711 }
625 } 712 }
626 713
627 cx25840_and_or(client, 0x810, ~0x01, 0); 714 cx25840_and_or(client, 0x810, ~0x01, 0);
@@ -633,6 +720,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
633 struct cx25840_state *state = to_state(i2c_get_clientdata(client)); 720 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
634 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && 721 u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
635 vid_input <= CX25840_COMPOSITE8); 722 vid_input <= CX25840_COMPOSITE8);
723 u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==
724 CX25840_COMPONENT_ON;
725 int luma = vid_input & 0xf0;
726 int chroma = vid_input & 0xf00;
636 u8 reg; 727 u8 reg;
637 728
638 v4l_dbg(1, cx25840_debug, client, 729 v4l_dbg(1, cx25840_debug, client,
@@ -643,20 +734,14 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
643 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n", 734 v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",
644 vid_input); 735 vid_input);
645 reg = vid_input & 0xff; 736 reg = vid_input & 0xff;
646 if ((vid_input & CX25840_SVIDEO_ON) == CX25840_SVIDEO_ON) 737 is_composite = !is_component &&
647 is_composite = 0; 738 ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);
648 else
649 is_composite = 1;
650 739
651 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n", 740 v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",
652 reg, is_composite); 741 reg, is_composite);
653 } else 742 } else if (is_composite) {
654 if (is_composite) {
655 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); 743 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
656 } else { 744 } else {
657 int luma = vid_input & 0xf0;
658 int chroma = vid_input & 0xf00;
659
660 if ((vid_input & ~0xff0) || 745 if ((vid_input & ~0xff0) ||
661 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || 746 luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
662 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { 747 chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
@@ -678,7 +763,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
678 * configuration in reg (for the cx23885) so we have no 763 * configuration in reg (for the cx23885) so we have no
679 * need to attempt to flip bits for earlier av decoders. 764 * need to attempt to flip bits for earlier av decoders.
680 */ 765 */
681 if (!state->is_cx23885 && !state->is_cx231xx) { 766 if (!is_cx2388x(state) && !is_cx231xx(state)) {
682 switch (aud_input) { 767 switch (aud_input) {
683 case CX25840_AUDIO_SERIAL: 768 case CX25840_AUDIO_SERIAL:
684 /* do nothing, use serial audio input */ 769 /* do nothing, use serial audio input */
@@ -698,10 +783,13 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
698 783
699 cx25840_write(client, 0x103, reg); 784 cx25840_write(client, 0x103, reg);
700 785
701 /* Set INPUT_MODE to Composite (0) or S-Video (1) */ 786 /* Set INPUT_MODE to Composite, S-Video or Component */
702 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); 787 if (is_component)
788 cx25840_and_or(client, 0x401, ~0x6, 0x6);
789 else
790 cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
703 791
704 if (!state->is_cx23885 && !state->is_cx231xx) { 792 if (!is_cx2388x(state) && !is_cx231xx(state)) {
705 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ 793 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
706 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); 794 cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
707 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */ 795 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */
@@ -710,22 +798,31 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
710 else 798 else
711 cx25840_and_or(client, 0x102, ~0x4, 0); 799 cx25840_and_or(client, 0x102, ~0x4, 0);
712 } else { 800 } else {
713 if (is_composite) 801 /* Set DUAL_MODE_ADC2 to 1 if component*/
802 cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);
803 if (is_composite) {
714 /* ADC2 input select channel 2 */ 804 /* ADC2 input select channel 2 */
715 cx25840_and_or(client, 0x102, ~0x2, 0); 805 cx25840_and_or(client, 0x102, ~0x2, 0);
716 else 806 } else if (!is_component) {
717 /* ADC2 input select channel 3 */ 807 /* S-Video */
718 cx25840_and_or(client, 0x102, ~0x2, 2); 808 if (chroma >= CX25840_SVIDEO_CHROMA7) {
809 /* ADC2 input select channel 3 */
810 cx25840_and_or(client, 0x102, ~0x2, 2);
811 } else {
812 /* ADC2 input select channel 2 */
813 cx25840_and_or(client, 0x102, ~0x2, 0);
814 }
815 }
719 } 816 }
720 817
721 state->vid_input = vid_input; 818 state->vid_input = vid_input;
722 state->aud_input = aud_input; 819 state->aud_input = aud_input;
723 if (!state->is_cx25836) { 820 if (!is_cx2583x(state)) {
724 cx25840_audio_set_path(client); 821 cx25840_audio_set_path(client);
725 input_change(client); 822 input_change(client);
726 } 823 }
727 824
728 if (state->is_cx23885) { 825 if (is_cx2388x(state)) {
729 /* Audio channel 1 src : Parallel 1 */ 826 /* Audio channel 1 src : Parallel 1 */
730 cx25840_write(client, 0x124, 0x03); 827 cx25840_write(client, 0x124, 0x03);
731 828
@@ -741,7 +838,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
741 */ 838 */
742 cx25840_write(client, 0x918, 0xa0); 839 cx25840_write(client, 0x918, 0xa0);
743 cx25840_write(client, 0x919, 0x01); 840 cx25840_write(client, 0x919, 0x01);
744 } else if (state->is_cx231xx) { 841 } else if (is_cx231xx(state)) {
745 /* Audio channel 1 src : Parallel 1 */ 842 /* Audio channel 1 src : Parallel 1 */
746 cx25840_write(client, 0x124, 0x03); 843 cx25840_write(client, 0x124, 0x03);
747 844
@@ -805,7 +902,7 @@ static int set_v4lstd(struct i2c_client *client)
805 cx25840_and_or(client, 0x400, ~0xf, fmt); 902 cx25840_and_or(client, 0x400, ~0xf, fmt);
806 cx25840_and_or(client, 0x403, ~0x3, pal_m); 903 cx25840_and_or(client, 0x403, ~0x3, pal_m);
807 cx25840_std_setup(client); 904 cx25840_std_setup(client);
808 if (!state->is_cx25836) 905 if (!is_cx2583x(state))
809 input_change(client); 906 input_change(client);
810 return 0; 907 return 0;
811} 908}
@@ -868,7 +965,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
868 case V4L2_CID_AUDIO_TREBLE: 965 case V4L2_CID_AUDIO_TREBLE:
869 case V4L2_CID_AUDIO_BALANCE: 966 case V4L2_CID_AUDIO_BALANCE:
870 case V4L2_CID_AUDIO_MUTE: 967 case V4L2_CID_AUDIO_MUTE:
871 if (state->is_cx25836) 968 if (is_cx2583x(state))
872 return -EINVAL; 969 return -EINVAL;
873 return cx25840_audio_s_ctrl(sd, ctrl); 970 return cx25840_audio_s_ctrl(sd, ctrl);
874 971
@@ -905,7 +1002,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
905 case V4L2_CID_AUDIO_TREBLE: 1002 case V4L2_CID_AUDIO_TREBLE:
906 case V4L2_CID_AUDIO_BALANCE: 1003 case V4L2_CID_AUDIO_BALANCE:
907 case V4L2_CID_AUDIO_MUTE: 1004 case V4L2_CID_AUDIO_MUTE:
908 if (state->is_cx25836) 1005 if (is_cx2583x(state))
909 return -EINVAL; 1006 return -EINVAL;
910 return cx25840_audio_g_ctrl(sd, ctrl); 1007 return cx25840_audio_g_ctrl(sd, ctrl);
911 default: 1008 default:
@@ -1209,11 +1306,11 @@ static int cx25840_load_fw(struct v4l2_subdev *sd)
1209 if (!state->is_initialized) { 1306 if (!state->is_initialized) {
1210 /* initialize and load firmware */ 1307 /* initialize and load firmware */
1211 state->is_initialized = 1; 1308 state->is_initialized = 1;
1212 if (state->is_cx25836) 1309 if (is_cx2583x(state))
1213 cx25836_initialize(client); 1310 cx25836_initialize(client);
1214 else if (state->is_cx23885) 1311 else if (is_cx2388x(state))
1215 cx23885_initialize(client); 1312 cx23885_initialize(client);
1216 else if (state->is_cx231xx) 1313 else if (is_cx231xx(state))
1217 cx231xx_initialize(client); 1314 cx231xx_initialize(client);
1218 else 1315 else
1219 cx25840_initialize(client); 1316 cx25840_initialize(client);
@@ -1248,30 +1345,59 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
1248} 1345}
1249#endif 1346#endif
1250 1347
1348static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)
1349{
1350 struct cx25840_state *state = to_state(sd);
1351 struct i2c_client *client = v4l2_get_subdevdata(sd);
1352 u8 v;
1353
1354 if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))
1355 return 0;
1356
1357 v4l_dbg(1, cx25840_debug, client, "%s audio output\n",
1358 enable ? "enable" : "disable");
1359
1360 if (enable) {
1361 v = cx25840_read(client, 0x115) | 0x80;
1362 cx25840_write(client, 0x115, v);
1363 v = cx25840_read(client, 0x116) | 0x03;
1364 cx25840_write(client, 0x116, v);
1365 } else {
1366 v = cx25840_read(client, 0x115) & ~(0x80);
1367 cx25840_write(client, 0x115, v);
1368 v = cx25840_read(client, 0x116) & ~(0x03);
1369 cx25840_write(client, 0x116, v);
1370 }
1371 return 0;
1372}
1373
1251static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) 1374static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1252{ 1375{
1253 struct cx25840_state *state = to_state(sd); 1376 struct cx25840_state *state = to_state(sd);
1254 struct i2c_client *client = v4l2_get_subdevdata(sd); 1377 struct i2c_client *client = v4l2_get_subdevdata(sd);
1378 u8 v;
1255 1379
1256 v4l_dbg(1, cx25840_debug, client, "%s output\n", 1380 v4l_dbg(1, cx25840_debug, client, "%s video output\n",
1257 enable ? "enable" : "disable"); 1381 enable ? "enable" : "disable");
1258 if (enable) { 1382 if (enable) {
1259 if (state->is_cx23885 || state->is_cx231xx) { 1383 if (is_cx2388x(state) || is_cx231xx(state)) {
1260 u8 v = (cx25840_read(client, 0x421) | 0x0b); 1384 v = cx25840_read(client, 0x421) | 0x0b;
1261 cx25840_write(client, 0x421, v); 1385 cx25840_write(client, 0x421, v);
1262 } else { 1386 } else {
1263 cx25840_write(client, 0x115, 1387 v = cx25840_read(client, 0x115) | 0x0c;
1264 state->is_cx25836 ? 0x0c : 0x8c); 1388 cx25840_write(client, 0x115, v);
1265 cx25840_write(client, 0x116, 1389 v = cx25840_read(client, 0x116) | 0x04;
1266 state->is_cx25836 ? 0x04 : 0x07); 1390 cx25840_write(client, 0x116, v);
1267 } 1391 }
1268 } else { 1392 } else {
1269 if (state->is_cx23885 || state->is_cx231xx) { 1393 if (is_cx2388x(state) || is_cx231xx(state)) {
1270 u8 v = cx25840_read(client, 0x421) & ~(0x0b); 1394 v = cx25840_read(client, 0x421) & ~(0x0b);
1271 cx25840_write(client, 0x421, v); 1395 cx25840_write(client, 0x421, v);
1272 } else { 1396 } else {
1273 cx25840_write(client, 0x115, 0x00); 1397 v = cx25840_read(client, 0x115) & ~(0x0c);
1274 cx25840_write(client, 0x116, 0x00); 1398 cx25840_write(client, 0x115, v);
1399 v = cx25840_read(client, 0x116) & ~(0x04);
1400 cx25840_write(client, 0x116, v);
1275 } 1401 }
1276 } 1402 }
1277 return 0; 1403 return 0;
@@ -1292,7 +1418,7 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1292 default: 1418 default:
1293 break; 1419 break;
1294 } 1420 }
1295 if (state->is_cx25836) 1421 if (is_cx2583x(state))
1296 return -EINVAL; 1422 return -EINVAL;
1297 1423
1298 switch (qc->id) { 1424 switch (qc->id) {
@@ -1346,7 +1472,7 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd,
1346 struct cx25840_state *state = to_state(sd); 1472 struct cx25840_state *state = to_state(sd);
1347 struct i2c_client *client = v4l2_get_subdevdata(sd); 1473 struct i2c_client *client = v4l2_get_subdevdata(sd);
1348 1474
1349 if (state->is_cx25836) 1475 if (is_cx2583x(state))
1350 return -EINVAL; 1476 return -EINVAL;
1351 return set_input(client, state->vid_input, input); 1477 return set_input(client, state->vid_input, input);
1352} 1478}
@@ -1356,7 +1482,7 @@ static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fr
1356 struct cx25840_state *state = to_state(sd); 1482 struct cx25840_state *state = to_state(sd);
1357 struct i2c_client *client = v4l2_get_subdevdata(sd); 1483 struct i2c_client *client = v4l2_get_subdevdata(sd);
1358 1484
1359 if (!state->is_cx25836) 1485 if (!is_cx2583x(state))
1360 input_change(client); 1486 input_change(client);
1361 return 0; 1487 return 0;
1362} 1488}
@@ -1373,7 +1499,7 @@ static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1373 return 0; 1499 return 0;
1374 1500
1375 vt->signal = vpres ? 0xffff : 0x0; 1501 vt->signal = vpres ? 0xffff : 0x0;
1376 if (state->is_cx25836) 1502 if (is_cx2583x(state))
1377 return 0; 1503 return 0;
1378 1504
1379 vt->capability |= 1505 vt->capability |=
@@ -1404,7 +1530,7 @@ static int cx25840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1404 struct cx25840_state *state = to_state(sd); 1530 struct cx25840_state *state = to_state(sd);
1405 struct i2c_client *client = v4l2_get_subdevdata(sd); 1531 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406 1532
1407 if (state->radio || state->is_cx25836) 1533 if (state->radio || is_cx2583x(state))
1408 return 0; 1534 return 0;
1409 1535
1410 switch (vt->audmode) { 1536 switch (vt->audmode) {
@@ -1445,11 +1571,11 @@ static int cx25840_reset(struct v4l2_subdev *sd, u32 val)
1445 struct cx25840_state *state = to_state(sd); 1571 struct cx25840_state *state = to_state(sd);
1446 struct i2c_client *client = v4l2_get_subdevdata(sd); 1572 struct i2c_client *client = v4l2_get_subdevdata(sd);
1447 1573
1448 if (state->is_cx25836) 1574 if (is_cx2583x(state))
1449 cx25836_initialize(client); 1575 cx25836_initialize(client);
1450 else if (state->is_cx23885) 1576 else if (is_cx2388x(state))
1451 cx23885_initialize(client); 1577 cx23885_initialize(client);
1452 else if (state->is_cx231xx) 1578 else if (is_cx231xx(state))
1453 cx231xx_initialize(client); 1579 cx231xx_initialize(client);
1454 else 1580 else
1455 cx25840_initialize(client); 1581 cx25840_initialize(client);
@@ -1470,7 +1596,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
1470 struct i2c_client *client = v4l2_get_subdevdata(sd); 1596 struct i2c_client *client = v4l2_get_subdevdata(sd);
1471 1597
1472 log_video_status(client); 1598 log_video_status(client);
1473 if (!state->is_cx25836) 1599 if (!is_cx2583x(state))
1474 log_audio_status(client); 1600 log_audio_status(client);
1475 return 0; 1601 return 0;
1476} 1602}
@@ -1502,6 +1628,7 @@ static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {
1502static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { 1628static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {
1503 .s_clock_freq = cx25840_s_clock_freq, 1629 .s_clock_freq = cx25840_s_clock_freq,
1504 .s_routing = cx25840_s_audio_routing, 1630 .s_routing = cx25840_s_audio_routing,
1631 .s_stream = cx25840_s_audio_stream,
1505}; 1632};
1506 1633
1507static const struct v4l2_subdev_video_ops cx25840_video_ops = { 1634static const struct v4l2_subdev_video_ops cx25840_video_ops = {
@@ -1521,12 +1648,50 @@ static const struct v4l2_subdev_ops cx25840_ops = {
1521 1648
1522/* ----------------------------------------------------------------------- */ 1649/* ----------------------------------------------------------------------- */
1523 1650
1651static u32 get_cx2388x_ident(struct i2c_client *client)
1652{
1653 u32 ret;
1654
1655 /* Come out of digital power down */
1656 cx25840_write(client, 0x000, 0);
1657
1658 /* Detecting whether the part is cx23885/7/8 is more
1659 * difficult than it needs to be. No ID register. Instead we
1660 * probe certain registers indicated in the datasheets to look
1661 * for specific defaults that differ between the silicon designs. */
1662
1663 /* It's either 885/7 if the IR Tx Clk Divider register exists */
1664 if (cx25840_read4(client, 0x204) & 0xffff) {
1665 /* CX23885 returns bogus repetitive byte values for the DIF,
1666 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */
1667 ret = cx25840_read4(client, 0x300);
1668 if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
1669 /* No DIF */
1670 ret = V4L2_IDENT_CX23885_AV;
1671 } else {
1672 /* CX23887 has a broken DIF, but the registers
1673 * appear valid (but unsed), good enough to detect. */
1674 ret = V4L2_IDENT_CX23887_AV;
1675 }
1676 } else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
1677 /* DIF PLL Freq Word reg exists; chip must be a CX23888 */
1678 ret = V4L2_IDENT_CX23888_AV;
1679 } else {
1680 v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
1681 ret = V4L2_IDENT_CX23887_AV;
1682 }
1683
1684 /* Back into digital power down */
1685 cx25840_write(client, 0x000, 2);
1686 return ret;
1687}
1688
1524static int cx25840_probe(struct i2c_client *client, 1689static int cx25840_probe(struct i2c_client *client,
1525 const struct i2c_device_id *did) 1690 const struct i2c_device_id *did)
1526{ 1691{
1527 struct cx25840_state *state; 1692 struct cx25840_state *state;
1528 struct v4l2_subdev *sd; 1693 struct v4l2_subdev *sd;
1529 u32 id; 1694 u32 id = V4L2_IDENT_NONE;
1530 u16 device_id; 1695 u16 device_id;
1531 1696
1532 /* Check if the adapter supports the needed features */ 1697 /* Check if the adapter supports the needed features */
@@ -1543,17 +1708,22 @@ static int cx25840_probe(struct i2c_client *client,
1543 * 0x83 for the cx2583x and 0x84 for the cx2584x */ 1708 * 0x83 for the cx2583x and 0x84 for the cx2584x */
1544 if ((device_id & 0xff00) == 0x8300) { 1709 if ((device_id & 0xff00) == 0x8300) {
1545 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1710 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1546 } 1711 } else if ((device_id & 0xff00) == 0x8400) {
1547 else if ((device_id & 0xff00) == 0x8400) {
1548 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1712 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
1549 } else if (device_id == 0x0000) { 1713 } else if (device_id == 0x0000) {
1550 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; 1714 id = get_cx2388x_ident(client);
1551 } else if (device_id == 0x1313) {
1552 id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
1553 } else if ((device_id & 0xfff0) == 0x5A30) { 1715 } else if ((device_id & 0xfff0) == 0x5A30) {
1554 id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); 1716 /* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
1555 } 1717 id = V4L2_IDENT_CX2310X_AV;
1556 else { 1718 } else if ((device_id & 0xff) == (device_id >> 8)) {
1719 v4l_err(client,
1720 "likely a confused/unresponsive cx2388[578] A/V decoder"
1721 " found @ 0x%x (%s)\n",
1722 client->addr << 1, client->adapter->name);
1723 v4l_err(client, "A method to reset it from the cx25840 driver"
1724 " software is not known at this time\n");
1725 return -ENODEV;
1726 } else {
1557 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); 1727 v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
1558 return -ENODEV; 1728 return -ENODEV;
1559 } 1729 }
@@ -1564,17 +1734,45 @@ static int cx25840_probe(struct i2c_client *client,
1564 1734
1565 sd = &state->sd; 1735 sd = &state->sd;
1566 v4l2_i2c_subdev_init(sd, client, &cx25840_ops); 1736 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
1567 /* Note: revision '(device_id & 0x0f) == 2' was never built. The 1737 switch (id) {
1568 marking skips from 0x1 == 22 to 0x3 == 23. */ 1738 case V4L2_IDENT_CX23885_AV:
1569 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", 1739 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
1570 (device_id & 0xfff0) >> 4, 1740 client->addr << 1, client->adapter->name);
1571 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f), 1741 break;
1572 client->addr << 1, client->adapter->name); 1742 case V4L2_IDENT_CX23887_AV:
1743 v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
1744 client->addr << 1, client->adapter->name);
1745 break;
1746 case V4L2_IDENT_CX23888_AV:
1747 v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
1748 client->addr << 1, client->adapter->name);
1749 break;
1750 case V4L2_IDENT_CX2310X_AV:
1751 v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
1752 device_id, client->addr << 1, client->adapter->name);
1753 break;
1754 case V4L2_IDENT_CX25840:
1755 case V4L2_IDENT_CX25841:
1756 case V4L2_IDENT_CX25842:
1757 case V4L2_IDENT_CX25843:
1758 /* Note: revision '(device_id & 0x0f) == 2' was never built. The
1759 marking skips from 0x1 == 22 to 0x3 == 23. */
1760 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
1761 (device_id & 0xfff0) >> 4,
1762 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1
1763 : (device_id & 0x0f),
1764 client->addr << 1, client->adapter->name);
1765 break;
1766 case V4L2_IDENT_CX25836:
1767 case V4L2_IDENT_CX25837:
1768 default:
1769 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
1770 (device_id & 0xfff0) >> 4, device_id & 0x0f,
1771 client->addr << 1, client->adapter->name);
1772 break;
1773 }
1573 1774
1574 state->c = client; 1775 state->c = client;
1575 state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
1576 state->is_cx23885 = (device_id == 0x0000) || (device_id == 0x1313);
1577 state->is_cx231xx = (device_id == 0x5a3e);
1578 state->vid_input = CX25840_COMPOSITE7; 1776 state->vid_input = CX25840_COMPOSITE7;
1579 state->aud_input = CX25840_AUDIO8; 1777 state->aud_input = CX25840_AUDIO8;
1580 state->audclk_freq = 48000; 1778 state->audclk_freq = 48000;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 814b56536994..55345444417f 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -23,6 +23,7 @@
23 23
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
26#include <media/v4l2-chip-ident.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
27 28
28/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is 29/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
@@ -48,9 +49,6 @@ struct cx25840_state {
48 int vbi_line_offset; 49 int vbi_line_offset;
49 u32 id; 50 u32 id;
50 u32 rev; 51 u32 rev;
51 int is_cx25836;
52 int is_cx23885;
53 int is_cx231xx;
54 int is_initialized; 52 int is_initialized;
55 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */ 53 wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
56 struct work_struct fw_work; /* work entry for fw load */ 54 struct work_struct fw_work; /* work entry for fw load */
@@ -61,6 +59,24 @@ static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
61 return container_of(sd, struct cx25840_state, sd); 59 return container_of(sd, struct cx25840_state, sd);
62} 60}
63 61
62static inline bool is_cx2583x(struct cx25840_state *state)
63{
64 return state->id == V4L2_IDENT_CX25836 ||
65 state->id == V4L2_IDENT_CX25837;
66}
67
68static inline bool is_cx231xx(struct cx25840_state *state)
69{
70 return state->id == V4L2_IDENT_CX2310X_AV;
71}
72
73static inline bool is_cx2388x(struct cx25840_state *state)
74{
75 return state->id == V4L2_IDENT_CX23885_AV ||
76 state->id == V4L2_IDENT_CX23887_AV ||
77 state->id == V4L2_IDENT_CX23888_AV;
78}
79
64/* ----------------------------------------------------------------------- */ 80/* ----------------------------------------------------------------------- */
65/* cx25850-core.c */ 81/* cx25850-core.c */
66int cx25840_write(struct i2c_client *client, u16 addr, u8 value); 82int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 1f483c1d0dbe..8150200511da 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -67,9 +67,9 @@ static const char *get_fw_name(struct i2c_client *client)
67 67
68 if (firmware[0]) 68 if (firmware[0])
69 return firmware; 69 return firmware;
70 if (state->is_cx23885) 70 if (is_cx2388x(state))
71 return "v4l-cx23885-avcore-01.fw"; 71 return "v4l-cx23885-avcore-01.fw";
72 if (state->is_cx231xx) 72 if (is_cx231xx(state))
73 return "v4l-cx231xx-avcore-01.fw"; 73 return "v4l-cx231xx-avcore-01.fw";
74 return "v4l-cx25840.fw"; 74 return "v4l-cx25840.fw";
75} 75}
@@ -112,13 +112,13 @@ int cx25840_loadfw(struct i2c_client *client)
112 int MAX_BUF_SIZE = FWSEND; 112 int MAX_BUF_SIZE = FWSEND;
113 u32 gpio_oe = 0, gpio_da = 0; 113 u32 gpio_oe = 0, gpio_da = 0;
114 114
115 if (state->is_cx23885) { 115 if (is_cx2388x(state)) {
116 /* Preserve the GPIO OE and output bits */ 116 /* Preserve the GPIO OE and output bits */
117 gpio_oe = cx25840_read(client, 0x160); 117 gpio_oe = cx25840_read(client, 0x160);
118 gpio_da = cx25840_read(client, 0x164); 118 gpio_da = cx25840_read(client, 0x164);
119 } 119 }
120 120
121 if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) { 121 if (is_cx231xx(state) && MAX_BUF_SIZE > 16) {
122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n"); 122 v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */ 123 MAX_BUF_SIZE = 16; /* cx231xx cannot accept more than 16 bytes at a time */
124 } 124 }
@@ -156,7 +156,7 @@ int cx25840_loadfw(struct i2c_client *client)
156 size = fw->size; 156 size = fw->size;
157 release_firmware(fw); 157 release_firmware(fw);
158 158
159 if (state->is_cx23885) { 159 if (is_cx2388x(state)) {
160 /* Restore GPIO configuration after f/w load */ 160 /* Restore GPIO configuration after f/w load */
161 cx25840_write(client, 0x160, gpio_oe); 161 cx25840_write(client, 0x160, gpio_oe);
162 cx25840_write(client, 0x164, gpio_da); 162 cx25840_write(client, 0x164, gpio_da);