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