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); |
