diff options
author | Marco Aurelio da Costa <costa@gamic.com> | 2009-03-28 16:34:44 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-03-28 16:34:44 -0400 |
commit | eff9ec95efaaf6b12d230f0ea7d3c295d3bc9d57 (patch) | |
tree | 741c1ec65283018583bc2a8d5577e3ce8c201994 /drivers/i2c/algos | |
parent | bac3e7c2aa2575a1c71f6fa643499676ca7c12c3 (diff) |
i2c-algo-pca: Add PCA9665 support
Add support for the PCA9665 I2C controller.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/algos')
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pca.c | 180 |
1 files changed, 166 insertions, 14 deletions
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 943d70ee5d59..a8e51bd1a4f5 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -46,6 +46,14 @@ static int i2c_debug; | |||
46 | #define pca_wait(adap) adap->wait_for_completion(adap->data) | 46 | #define pca_wait(adap) adap->wait_for_completion(adap->data) |
47 | #define pca_reset(adap) adap->reset_chip(adap->data) | 47 | #define pca_reset(adap) adap->reset_chip(adap->data) |
48 | 48 | ||
49 | static void pca9665_reset(void *pd) | ||
50 | { | ||
51 | struct i2c_algo_pca_data *adap = pd; | ||
52 | pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); | ||
53 | pca_outw(adap, I2C_PCA_IND, 0xA5); | ||
54 | pca_outw(adap, I2C_PCA_IND, 0x5A); | ||
55 | } | ||
56 | |||
49 | /* | 57 | /* |
50 | * Generate a start condition on the i2c bus. | 58 | * Generate a start condition on the i2c bus. |
51 | * | 59 | * |
@@ -333,27 +341,171 @@ static const struct i2c_algorithm pca_algo = { | |||
333 | .functionality = pca_func, | 341 | .functionality = pca_func, |
334 | }; | 342 | }; |
335 | 343 | ||
336 | static int pca_init(struct i2c_adapter *adap) | 344 | static unsigned int pca_probe_chip(struct i2c_adapter *adap) |
337 | { | 345 | { |
338 | static int freqs[] = {330,288,217,146,88,59,44,36}; | ||
339 | int clock; | ||
340 | struct i2c_algo_pca_data *pca_data = adap->algo_data; | 346 | struct i2c_algo_pca_data *pca_data = adap->algo_data; |
341 | 347 | /* The trick here is to check if there is an indirect register | |
342 | if (pca_data->i2c_clock > 7) { | 348 | * available. If there is one, we will read the value we first |
343 | printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n", | 349 | * wrote on I2C_PCA_IADR. Otherwise, we will read the last value |
344 | adap->name); | 350 | * we wrote on I2C_PCA_ADR |
345 | pca_data->i2c_clock = I2C_PCA_CON_59kHz; | 351 | */ |
352 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); | ||
353 | pca_outw(pca_data, I2C_PCA_IND, 0xAA); | ||
354 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO); | ||
355 | pca_outw(pca_data, I2C_PCA_IND, 0x00); | ||
356 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); | ||
357 | if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { | ||
358 | printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); | ||
359 | return I2C_PCA_CHIP_9665; | ||
360 | } else { | ||
361 | printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); | ||
362 | return I2C_PCA_CHIP_9564; | ||
346 | } | 363 | } |
364 | } | ||
365 | |||
366 | static int pca_init(struct i2c_adapter *adap) | ||
367 | { | ||
368 | struct i2c_algo_pca_data *pca_data = adap->algo_data; | ||
347 | 369 | ||
348 | adap->algo = &pca_algo; | 370 | adap->algo = &pca_algo; |
349 | 371 | ||
350 | pca_reset(pca_data); | 372 | if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) { |
373 | static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36}; | ||
374 | int clock; | ||
375 | |||
376 | if (pca_data->i2c_clock > 7) { | ||
377 | switch (pca_data->i2c_clock) { | ||
378 | case 330000: | ||
379 | pca_data->i2c_clock = I2C_PCA_CON_330kHz; | ||
380 | break; | ||
381 | case 288000: | ||
382 | pca_data->i2c_clock = I2C_PCA_CON_288kHz; | ||
383 | break; | ||
384 | case 217000: | ||
385 | pca_data->i2c_clock = I2C_PCA_CON_217kHz; | ||
386 | break; | ||
387 | case 146000: | ||
388 | pca_data->i2c_clock = I2C_PCA_CON_146kHz; | ||
389 | break; | ||
390 | case 88000: | ||
391 | pca_data->i2c_clock = I2C_PCA_CON_88kHz; | ||
392 | break; | ||
393 | case 59000: | ||
394 | pca_data->i2c_clock = I2C_PCA_CON_59kHz; | ||
395 | break; | ||
396 | case 44000: | ||
397 | pca_data->i2c_clock = I2C_PCA_CON_44kHz; | ||
398 | break; | ||
399 | case 36000: | ||
400 | pca_data->i2c_clock = I2C_PCA_CON_36kHz; | ||
401 | break; | ||
402 | default: | ||
403 | printk(KERN_WARNING | ||
404 | "%s: Invalid I2C clock speed selected." | ||
405 | " Using default 59kHz.\n", adap->name); | ||
406 | pca_data->i2c_clock = I2C_PCA_CON_59kHz; | ||
407 | } | ||
408 | } else { | ||
409 | printk(KERN_WARNING "%s: " | ||
410 | "Choosing the clock frequency based on " | ||
411 | "index is deprecated." | ||
412 | " Use the nominal frequency.\n", adap->name); | ||
413 | } | ||
414 | |||
415 | pca_reset(pca_data); | ||
416 | |||
417 | clock = pca_clock(pca_data); | ||
418 | printk(KERN_INFO "%s: Clock frequency is %dkHz\n", | ||
419 | adap->name, freqs[clock]); | ||
420 | |||
421 | pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); | ||
422 | } else { | ||
423 | int clock; | ||
424 | int mode; | ||
425 | int tlow, thi; | ||
426 | /* Values can be found on PCA9665 datasheet section 7.3.2.6 */ | ||
427 | int min_tlow, min_thi; | ||
428 | /* These values are the maximum raise and fall values allowed | ||
429 | * by the I2C operation mode (Standard, Fast or Fast+) | ||
430 | * They are used (added) below to calculate the clock dividers | ||
431 | * of PCA9665. Note that they are slightly different of the | ||
432 | * real maximum, to allow the change on mode exactly on the | ||
433 | * maximum clock rate for each mode | ||
434 | */ | ||
435 | int raise_fall_time; | ||
436 | |||
437 | struct i2c_algo_pca_data *pca_data = adap->algo_data; | ||
438 | |||
439 | /* Ignore the reset function from the module, | ||
440 | * we can use the parallel bus reset | ||
441 | */ | ||
442 | pca_data->reset_chip = pca9665_reset; | ||
443 | |||
444 | if (pca_data->i2c_clock > 1265800) { | ||
445 | printk(KERN_WARNING "%s: I2C clock speed too high." | ||
446 | " Using 1265.8kHz.\n", adap->name); | ||
447 | pca_data->i2c_clock = 1265800; | ||
448 | } | ||
449 | |||
450 | if (pca_data->i2c_clock < 60300) { | ||
451 | printk(KERN_WARNING "%s: I2C clock speed too low." | ||
452 | " Using 60.3kHz.\n", adap->name); | ||
453 | pca_data->i2c_clock = 60300; | ||
454 | } | ||
455 | |||
456 | /* To avoid integer overflow, use clock/100 for calculations */ | ||
457 | clock = pca_clock(pca_data) / 100; | ||
458 | |||
459 | if (pca_data->i2c_clock > 10000) { | ||
460 | mode = I2C_PCA_MODE_TURBO; | ||
461 | min_tlow = 14; | ||
462 | min_thi = 5; | ||
463 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | ||
464 | } else if (pca_data->i2c_clock > 4000) { | ||
465 | mode = I2C_PCA_MODE_FASTP; | ||
466 | min_tlow = 17; | ||
467 | min_thi = 9; | ||
468 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | ||
469 | } else if (pca_data->i2c_clock > 1000) { | ||
470 | mode = I2C_PCA_MODE_FAST; | ||
471 | min_tlow = 44; | ||
472 | min_thi = 20; | ||
473 | raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */ | ||
474 | } else { | ||
475 | mode = I2C_PCA_MODE_STD; | ||
476 | min_tlow = 157; | ||
477 | min_thi = 134; | ||
478 | raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */ | ||
479 | } | ||
480 | |||
481 | /* The minimum clock that respects the thi/tlow = 134/157 is | ||
482 | * 64800 Hz. Below that, we have to fix the tlow to 255 and | ||
483 | * calculate the thi factor. | ||
484 | */ | ||
485 | if (clock < 648) { | ||
486 | tlow = 255; | ||
487 | thi = 1000000 - clock * raise_fall_time; | ||
488 | thi /= (I2C_PCA_OSC_PER * clock) - tlow; | ||
489 | } else { | ||
490 | tlow = (1000000 - clock * raise_fall_time) * min_tlow; | ||
491 | tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow); | ||
492 | thi = tlow * min_thi / min_tlow; | ||
493 | } | ||
494 | |||
495 | pca_reset(pca_data); | ||
351 | 496 | ||
352 | clock = pca_clock(pca_data); | 497 | printk(KERN_INFO |
353 | printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, | 498 | "%s: Clock frequency is %dHz\n", adap->name, clock * 100); |
354 | freqs[clock]); | ||
355 | 499 | ||
356 | pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); | 500 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); |
501 | pca_outw(pca_data, I2C_PCA_IND, mode); | ||
502 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); | ||
503 | pca_outw(pca_data, I2C_PCA_IND, tlow); | ||
504 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); | ||
505 | pca_outw(pca_data, I2C_PCA_IND, thi); | ||
506 | |||
507 | pca_set_con(pca_data, I2C_PCA_CON_ENSIO); | ||
508 | } | ||
357 | udelay(500); /* 500 us for oscilator to stabilise */ | 509 | udelay(500); /* 500 us for oscilator to stabilise */ |
358 | 510 | ||
359 | return 0; | 511 | return 0; |
@@ -388,7 +540,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus); | |||
388 | 540 | ||
389 | MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " | 541 | MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, " |
390 | "Wolfram Sang <w.sang@pengutronix.de>"); | 542 | "Wolfram Sang <w.sang@pengutronix.de>"); |
391 | MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm"); | 543 | MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm"); |
392 | MODULE_LICENSE("GPL"); | 544 | MODULE_LICENSE("GPL"); |
393 | 545 | ||
394 | module_param(i2c_debug, int, 0); | 546 | module_param(i2c_debug, int, 0); |