aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx25840
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-09-26 23:00:48 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:18 -0500
commite283d78083271c9faf784daad6367dfb903d0f06 (patch)
tree23c371b1b9aa4fcc2e609fe10785f497d63d2e34 /drivers/media/video/cx25840
parent9eef550a9a98c1e3d15aaf490812949fdeb01c7c (diff)
V4L/DVB (13090): cx25840: Init PLLs properly for CX2388[578] A/V cores
The SYS and AUX PLLs need to be initialized to different values based on the chip: CX23885, CX23887, CX23888, as each uses a different crystal frequency: 28.6363 MHz, 25.0 MHz, 50.0 MHz. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c106
1 files changed, 88 insertions, 18 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index a6446e637f17..56ead3d37926 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);