diff options
author | Ben Gardner <bgardner@wabtec.com> | 2006-01-18 16:48:26 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 17:21:50 -0500 |
commit | 16ffc5c99554bc1630bc3939e0950a75b2b1c811 (patch) | |
tree | 553e2cbee905e84954e86618ba8782596f5f1fe7 /drivers/i2c | |
parent | 8a05940d742174a87427a3fe746712d49d4b8c4b (diff) |
[PATCH] i2c: scx200_acb add support for the CS5535/CS5536
scx200_acb: Add support for the CS5535/CS5536
Signed-off-by: Ben Gardner <bgardner@wabtec.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/scx200_acb.c | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 02150bb25d43..0ae77f84ffe8 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -2,6 +2,7 @@ | |||
2 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | 2 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> |
3 | 3 | ||
4 | National Semiconductor SCx200 ACCESS.bus support | 4 | National Semiconductor SCx200 ACCESS.bus support |
5 | Also supports the AMD CS5535 and AMD CS5536 | ||
5 | 6 | ||
6 | Based on i2c-keywest.c which is: | 7 | Based on i2c-keywest.c which is: |
7 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> | 8 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
33 | #include <asm/io.h> | 34 | #include <asm/io.h> |
35 | #include <asm/msr.h> | ||
34 | 36 | ||
35 | #include <linux/scx200.h> | 37 | #include <linux/scx200.h> |
36 | 38 | ||
@@ -416,7 +418,7 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
416 | return 0; | 418 | return 0; |
417 | } | 419 | } |
418 | 420 | ||
419 | static int __init scx200_acb_create(int base, int index) | 421 | static int __init scx200_acb_create(const char *text, int base, int index) |
420 | { | 422 | { |
421 | struct scx200_acb_iface *iface; | 423 | struct scx200_acb_iface *iface; |
422 | struct i2c_adapter *adapter; | 424 | struct i2c_adapter *adapter; |
@@ -432,7 +434,7 @@ static int __init scx200_acb_create(int base, int index) | |||
432 | 434 | ||
433 | adapter = &iface->adapter; | 435 | adapter = &iface->adapter; |
434 | i2c_set_adapdata(adapter, iface); | 436 | i2c_set_adapdata(adapter, iface); |
435 | snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index); | 437 | snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index); |
436 | adapter->owner = THIS_MODULE; | 438 | adapter->owner = THIS_MODULE; |
437 | adapter->id = I2C_HW_SMBUS_SCX200; | 439 | adapter->id = I2C_HW_SMBUS_SCX200; |
438 | adapter->algo = &scx200_acb_algorithm; | 440 | adapter->algo = &scx200_acb_algorithm; |
@@ -440,8 +442,9 @@ static int __init scx200_acb_create(int base, int index) | |||
440 | 442 | ||
441 | init_MUTEX(&iface->sem); | 443 | init_MUTEX(&iface->sem); |
442 | 444 | ||
443 | snprintf(description, sizeof(description), | 445 | snprintf(description, sizeof(description), "%s ACCESS.bus [%s]", |
444 | "NatSemi SCx200 ACCESS.bus [%s]", adapter->name); | 446 | text, adapter->name); |
447 | |||
445 | if (request_region(base, 8, description) == 0) { | 448 | if (request_region(base, 8, description) == 0) { |
446 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", | 449 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", |
447 | base, base + 8-1); | 450 | base, base + 8-1); |
@@ -485,24 +488,50 @@ static struct pci_device_id scx200[] = { | |||
485 | { }, | 488 | { }, |
486 | }; | 489 | }; |
487 | 490 | ||
491 | static struct pci_device_id divil_pci[] = { | ||
492 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
493 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
494 | { } /* NULL entry */ | ||
495 | }; | ||
496 | |||
497 | #define MSR_LBAR_SMB 0x5140000B | ||
498 | |||
499 | static int scx200_add_cs553x(void) | ||
500 | { | ||
501 | u32 low, hi; | ||
502 | u32 smb_base; | ||
503 | |||
504 | /* Grab & reserve the SMB I/O range */ | ||
505 | rdmsr(MSR_LBAR_SMB, low, hi); | ||
506 | |||
507 | /* Check the IO mask and whether SMB is enabled */ | ||
508 | if (hi != 0x0000F001) { | ||
509 | printk(KERN_WARNING NAME ": SMBus not enabled\n"); | ||
510 | return -ENODEV; | ||
511 | } | ||
512 | |||
513 | /* SMBus IO size is 8 bytes */ | ||
514 | smb_base = low & 0x0000FFF8; | ||
515 | |||
516 | return scx200_acb_create("CS5535", smb_base, 0); | ||
517 | } | ||
518 | |||
488 | static int __init scx200_acb_init(void) | 519 | static int __init scx200_acb_init(void) |
489 | { | 520 | { |
490 | int i; | 521 | int i; |
491 | int rc; | 522 | int rc = -ENODEV; |
492 | 523 | ||
493 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); | 524 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); |
494 | 525 | ||
495 | /* Verify that this really is a SCx200 processor */ | 526 | /* Verify that this really is a SCx200 processor */ |
496 | if (pci_dev_present(scx200) == 0) | 527 | if (pci_dev_present(scx200)) { |
497 | return -ENODEV; | 528 | for (i = 0; i < MAX_DEVICES; ++i) { |
529 | if (base[i] > 0) | ||
530 | rc = scx200_acb_create("SCx200", base[i], i); | ||
531 | } | ||
532 | } else if (pci_dev_present(divil_pci)) | ||
533 | rc = scx200_add_cs553x(); | ||
498 | 534 | ||
499 | rc = -ENXIO; | ||
500 | for (i = 0; i < MAX_DEVICES; ++i) { | ||
501 | if (base[i] > 0) | ||
502 | rc = scx200_acb_create(base[i], i); | ||
503 | } | ||
504 | if (scx200_acb_list) | ||
505 | return 0; | ||
506 | return rc; | 535 | return rc; |
507 | } | 536 | } |
508 | 537 | ||