diff options
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/Kconfig | 22 | ||||
-rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 154 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-nforce2.c | 38 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-ocores.c | 341 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 33 | ||||
-rw-r--r-- | drivers/i2c/busses/scx200_acb.c | 202 |
7 files changed, 610 insertions, 181 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index fbeae821ffb3..884320e70403 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -163,7 +163,7 @@ config I2C_PXA_SLAVE | |||
163 | I2C bus. | 163 | I2C bus. |
164 | 164 | ||
165 | config I2C_PIIX4 | 165 | config I2C_PIIX4 |
166 | tristate "Intel PIIX4" | 166 | tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" |
167 | depends on I2C && PCI | 167 | depends on I2C && PCI |
168 | help | 168 | help |
169 | If you say yes to this option, support will be included for the Intel | 169 | If you say yes to this option, support will be included for the Intel |
@@ -172,6 +172,9 @@ config I2C_PIIX4 | |||
172 | of Broadcom): | 172 | of Broadcom): |
173 | Intel PIIX4 | 173 | Intel PIIX4 |
174 | Intel 440MX | 174 | Intel 440MX |
175 | ATI IXP200 | ||
176 | ATI IXP300 | ||
177 | ATI IXP400 | ||
175 | Serverworks OSB4 | 178 | Serverworks OSB4 |
176 | Serverworks CSB5 | 179 | Serverworks CSB5 |
177 | Serverworks CSB6 | 180 | Serverworks CSB6 |
@@ -273,6 +276,17 @@ config I2C_NFORCE2 | |||
273 | This driver can also be built as a module. If so, the module | 276 | This driver can also be built as a module. If so, the module |
274 | will be called i2c-nforce2. | 277 | will be called i2c-nforce2. |
275 | 278 | ||
279 | config I2C_OCORES | ||
280 | tristate "OpenCores I2C Controller" | ||
281 | depends on I2C && EXPERIMENTAL | ||
282 | help | ||
283 | If you say yes to this option, support will be included for the | ||
284 | OpenCores I2C controller. For details see | ||
285 | http://www.opencores.org/projects.cgi/web/i2c/overview | ||
286 | |||
287 | This driver can also be built as a module. If so, the module | ||
288 | will be called i2c-ocores. | ||
289 | |||
276 | config I2C_PARPORT | 290 | config I2C_PARPORT |
277 | tristate "Parallel port adapter" | 291 | tristate "Parallel port adapter" |
278 | depends on I2C && PARPORT | 292 | depends on I2C && PARPORT |
@@ -500,6 +514,7 @@ config I2C_PCA_ISA | |||
500 | tristate "PCA9564 on an ISA bus" | 514 | tristate "PCA9564 on an ISA bus" |
501 | depends on I2C | 515 | depends on I2C |
502 | select I2C_ALGOPCA | 516 | select I2C_ALGOPCA |
517 | default n | ||
503 | help | 518 | help |
504 | This driver supports ISA boards using the Philips PCA 9564 | 519 | This driver supports ISA boards using the Philips PCA 9564 |
505 | Parallel bus to I2C bus controller | 520 | Parallel bus to I2C bus controller |
@@ -507,6 +522,11 @@ config I2C_PCA_ISA | |||
507 | This driver can also be built as a module. If so, the module | 522 | This driver can also be built as a module. If so, the module |
508 | will be called i2c-pca-isa. | 523 | will be called i2c-pca-isa. |
509 | 524 | ||
525 | This device is almost undetectable and using this driver on a | ||
526 | system which doesn't have this device will result in long | ||
527 | delays when I2C/SMBus chip drivers are loaded (e.g. at boot | ||
528 | time). If unsure, say N. | ||
529 | |||
510 | config I2C_MV64XXX | 530 | config I2C_MV64XXX |
511 | tristate "Marvell mv64xxx I2C Controller" | 531 | tristate "Marvell mv64xxx I2C Controller" |
512 | depends on I2C && MV64X60 && EXPERIMENTAL | 532 | depends on I2C && MV64X60 && EXPERIMENTAL |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index b44831dff683..ac56df53155b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o | |||
23 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o | 23 | obj-$(CONFIG_I2C_MPC) += i2c-mpc.o |
24 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o | 24 | obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o |
25 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o | 25 | obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o |
26 | obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o | ||
26 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o | 27 | obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o |
27 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o | 28 | obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o |
28 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o | 29 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index dfca74933625..3e0d04d5a800 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | i801.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring | 3 | monitoring |
4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, | 4 | Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, |
5 | Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker | 5 | Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker |
@@ -36,7 +36,7 @@ | |||
36 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). | 36 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). |
37 | For SMBus support, they are similar to the PIIX4 and are part | 37 | For SMBus support, they are similar to the PIIX4 and are part |
38 | of Intel's '810' and other chipsets. | 38 | of Intel's '810' and other chipsets. |
39 | See the doc/busses/i2c-i801 file for details. | 39 | See the file Documentation/i2c/busses/i2c-i801 for details. |
40 | I2C Block Read and Process Call are not supported. | 40 | I2C Block Read and Process Call are not supported. |
41 | */ | 41 | */ |
42 | 42 | ||
@@ -66,9 +66,8 @@ | |||
66 | #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ | 66 | #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */ |
67 | 67 | ||
68 | /* PCI Address Constants */ | 68 | /* PCI Address Constants */ |
69 | #define SMBBA 0x020 | 69 | #define SMBBAR 4 |
70 | #define SMBHSTCFG 0x040 | 70 | #define SMBHSTCFG 0x040 |
71 | #define SMBREV 0x008 | ||
72 | 71 | ||
73 | /* Host configuration bits for SMBHSTCFG */ | 72 | /* Host configuration bits for SMBHSTCFG */ |
74 | #define SMBHSTCFG_HST_EN 1 | 73 | #define SMBHSTCFG_HST_EN 1 |
@@ -92,92 +91,16 @@ | |||
92 | #define I801_START 0x40 | 91 | #define I801_START 0x40 |
93 | #define I801_PEC_EN 0x80 /* ICH4 only */ | 92 | #define I801_PEC_EN 0x80 /* ICH4 only */ |
94 | 93 | ||
95 | /* insmod parameters */ | ||
96 | |||
97 | /* If force_addr is set to anything different from 0, we forcibly enable | ||
98 | the I801 at the given address. VERY DANGEROUS! */ | ||
99 | static u16 force_addr; | ||
100 | module_param(force_addr, ushort, 0); | ||
101 | MODULE_PARM_DESC(force_addr, | ||
102 | "Forcibly enable the I801 at the given address. " | ||
103 | "EXTREMELY DANGEROUS!"); | ||
104 | 94 | ||
105 | static int i801_transaction(void); | 95 | static int i801_transaction(void); |
106 | static int i801_block_transaction(union i2c_smbus_data *data, char read_write, | 96 | static int i801_block_transaction(union i2c_smbus_data *data, char read_write, |
107 | int command, int hwpec); | 97 | int command, int hwpec); |
108 | 98 | ||
109 | static unsigned short i801_smba; | 99 | static unsigned long i801_smba; |
110 | static struct pci_driver i801_driver; | 100 | static struct pci_driver i801_driver; |
111 | static struct pci_dev *I801_dev; | 101 | static struct pci_dev *I801_dev; |
112 | static int isich4; | 102 | static int isich4; |
113 | 103 | ||
114 | static int i801_setup(struct pci_dev *dev) | ||
115 | { | ||
116 | int error_return = 0; | ||
117 | unsigned char temp; | ||
118 | |||
119 | /* Note: we keep on searching until we have found 'function 3' */ | ||
120 | if(PCI_FUNC(dev->devfn) != 3) | ||
121 | return -ENODEV; | ||
122 | |||
123 | I801_dev = dev; | ||
124 | if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || | ||
125 | (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || | ||
126 | (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) | ||
127 | isich4 = 1; | ||
128 | else | ||
129 | isich4 = 0; | ||
130 | |||
131 | /* Determine the address of the SMBus areas */ | ||
132 | if (force_addr) { | ||
133 | i801_smba = force_addr & 0xfff0; | ||
134 | } else { | ||
135 | pci_read_config_word(I801_dev, SMBBA, &i801_smba); | ||
136 | i801_smba &= 0xfff0; | ||
137 | if(i801_smba == 0) { | ||
138 | dev_err(&dev->dev, "SMB base address uninitialized " | ||
139 | "- upgrade BIOS or use force_addr=0xaddr\n"); | ||
140 | return -ENODEV; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) { | ||
145 | dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n", | ||
146 | i801_smba); | ||
147 | error_return = -EBUSY; | ||
148 | goto END; | ||
149 | } | ||
150 | |||
151 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); | ||
152 | temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ | ||
153 | pci_write_config_byte(I801_dev, SMBHSTCFG, temp); | ||
154 | |||
155 | /* If force_addr is set, we program the new address here. Just to make | ||
156 | sure, we disable the device first. */ | ||
157 | if (force_addr) { | ||
158 | pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe); | ||
159 | pci_write_config_word(I801_dev, SMBBA, i801_smba); | ||
160 | pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01); | ||
161 | dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to " | ||
162 | "new address %04x!\n", i801_smba); | ||
163 | } else if ((temp & 1) == 0) { | ||
164 | pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1); | ||
165 | dev_warn(&dev->dev, "enabling SMBus device\n"); | ||
166 | } | ||
167 | |||
168 | if (temp & 0x02) | ||
169 | dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n"); | ||
170 | else | ||
171 | dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); | ||
172 | |||
173 | pci_read_config_byte(I801_dev, SMBREV, &temp); | ||
174 | dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); | ||
175 | dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); | ||
176 | |||
177 | END: | ||
178 | return error_return; | ||
179 | } | ||
180 | |||
181 | static int i801_transaction(void) | 104 | static int i801_transaction(void) |
182 | { | 105 | { |
183 | int temp; | 106 | int temp; |
@@ -334,8 +257,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, | |||
334 | /* We will always wait for a fraction of a second! */ | 257 | /* We will always wait for a fraction of a second! */ |
335 | timeout = 0; | 258 | timeout = 0; |
336 | do { | 259 | do { |
337 | temp = inb_p(SMBHSTSTS); | ||
338 | msleep(1); | 260 | msleep(1); |
261 | temp = inb_p(SMBHSTSTS); | ||
339 | } | 262 | } |
340 | while ((!(temp & 0x80)) | 263 | while ((!(temp & 0x80)) |
341 | && (timeout++ < MAX_TIMEOUT)); | 264 | && (timeout++ < MAX_TIMEOUT)); |
@@ -393,8 +316,8 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, | |||
393 | /* wait for INTR bit as advised by Intel */ | 316 | /* wait for INTR bit as advised by Intel */ |
394 | timeout = 0; | 317 | timeout = 0; |
395 | do { | 318 | do { |
396 | temp = inb_p(SMBHSTSTS); | ||
397 | msleep(1); | 319 | msleep(1); |
320 | temp = inb_p(SMBHSTSTS); | ||
398 | } while ((!(temp & 0x02)) | 321 | } while ((!(temp & 0x02)) |
399 | && (timeout++ < MAX_TIMEOUT)); | 322 | && (timeout++ < MAX_TIMEOUT)); |
400 | 323 | ||
@@ -541,25 +464,76 @@ MODULE_DEVICE_TABLE (pci, i801_ids); | |||
541 | 464 | ||
542 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) | 465 | static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) |
543 | { | 466 | { |
467 | unsigned char temp; | ||
468 | int err; | ||
469 | |||
470 | I801_dev = dev; | ||
471 | if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || | ||
472 | (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || | ||
473 | (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) | ||
474 | isich4 = 1; | ||
475 | else | ||
476 | isich4 = 0; | ||
477 | |||
478 | err = pci_enable_device(dev); | ||
479 | if (err) { | ||
480 | dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", | ||
481 | err); | ||
482 | goto exit; | ||
483 | } | ||
484 | |||
485 | /* Determine the address of the SMBus area */ | ||
486 | i801_smba = pci_resource_start(dev, SMBBAR); | ||
487 | if (!i801_smba) { | ||
488 | dev_err(&dev->dev, "SMBus base address uninitialized, " | ||
489 | "upgrade BIOS\n"); | ||
490 | err = -ENODEV; | ||
491 | goto exit_disable; | ||
492 | } | ||
493 | |||
494 | err = pci_request_region(dev, SMBBAR, i801_driver.name); | ||
495 | if (err) { | ||
496 | dev_err(&dev->dev, "Failed to request SMBus region " | ||
497 | "0x%lx-0x%lx\n", i801_smba, | ||
498 | pci_resource_end(dev, SMBBAR)); | ||
499 | goto exit_disable; | ||
500 | } | ||
544 | 501 | ||
545 | if (i801_setup(dev)) { | 502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); |
546 | dev_warn(&dev->dev, | 503 | temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ |
547 | "I801 not detected, module not inserted.\n"); | 504 | if (!(temp & SMBHSTCFG_HST_EN)) { |
548 | return -ENODEV; | 505 | dev_info(&dev->dev, "Enabling SMBus device\n"); |
506 | temp |= SMBHSTCFG_HST_EN; | ||
549 | } | 507 | } |
508 | pci_write_config_byte(I801_dev, SMBHSTCFG, temp); | ||
509 | |||
510 | if (temp & SMBHSTCFG_SMB_SMI_EN) | ||
511 | dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); | ||
512 | else | ||
513 | dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n"); | ||
550 | 514 | ||
551 | /* set up the driverfs linkage to our parent device */ | 515 | /* set up the driverfs linkage to our parent device */ |
552 | i801_adapter.dev.parent = &dev->dev; | 516 | i801_adapter.dev.parent = &dev->dev; |
553 | 517 | ||
554 | snprintf(i801_adapter.name, I2C_NAME_SIZE, | 518 | snprintf(i801_adapter.name, I2C_NAME_SIZE, |
555 | "SMBus I801 adapter at %04x", i801_smba); | 519 | "SMBus I801 adapter at %04lx", i801_smba); |
556 | return i2c_add_adapter(&i801_adapter); | 520 | err = i2c_add_adapter(&i801_adapter); |
521 | if (err) { | ||
522 | dev_err(&dev->dev, "Failed to add SMBus adapter\n"); | ||
523 | goto exit_disable; | ||
524 | } | ||
525 | |||
526 | exit_disable: | ||
527 | pci_disable_device(dev); | ||
528 | exit: | ||
529 | return err; | ||
557 | } | 530 | } |
558 | 531 | ||
559 | static void __devexit i801_remove(struct pci_dev *dev) | 532 | static void __devexit i801_remove(struct pci_dev *dev) |
560 | { | 533 | { |
561 | i2c_del_adapter(&i801_adapter); | 534 | i2c_del_adapter(&i801_adapter); |
562 | release_region(i801_smba, (isich4 ? 16 : 8)); | 535 | pci_release_region(dev, SMBBAR); |
536 | pci_disable_device(dev); | ||
563 | } | 537 | } |
564 | 538 | ||
565 | static struct pci_driver i801_driver = { | 539 | static struct pci_driver i801_driver = { |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 2d80eb26f688..604b49e22df1 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
@@ -31,6 +31,8 @@ | |||
31 | nForce3 250Gb MCP 00E4 | 31 | nForce3 250Gb MCP 00E4 |
32 | nForce4 MCP 0052 | 32 | nForce4 MCP 0052 |
33 | nForce4 MCP-04 0034 | 33 | nForce4 MCP-04 0034 |
34 | nForce4 MCP51 0264 | ||
35 | nForce4 MCP55 0368 | ||
34 | 36 | ||
35 | This driver supports the 2 SMBuses that are included in the MCP of the | 37 | This driver supports the 2 SMBuses that are included in the MCP of the |
36 | nForce2/3/4 chipsets. | 38 | nForce2/3/4 chipsets. |
@@ -64,6 +66,7 @@ struct nforce2_smbus { | |||
64 | 66 | ||
65 | /* | 67 | /* |
66 | * nVidia nForce2 SMBus control register definitions | 68 | * nVidia nForce2 SMBus control register definitions |
69 | * (Newer incarnations use standard BARs 4 and 5 instead) | ||
67 | */ | 70 | */ |
68 | #define NFORCE_PCI_SMB1 0x50 | 71 | #define NFORCE_PCI_SMB1 0x50 |
69 | #define NFORCE_PCI_SMB2 0x54 | 72 | #define NFORCE_PCI_SMB2 0x54 |
@@ -259,6 +262,8 @@ static struct pci_device_id nforce2_ids[] = { | |||
259 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, | 262 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, |
260 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, | 263 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, |
261 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, | 264 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, |
265 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) }, | ||
266 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, | ||
262 | { 0 } | 267 | { 0 } |
263 | }; | 268 | }; |
264 | 269 | ||
@@ -266,19 +271,29 @@ static struct pci_device_id nforce2_ids[] = { | |||
266 | MODULE_DEVICE_TABLE (pci, nforce2_ids); | 271 | MODULE_DEVICE_TABLE (pci, nforce2_ids); |
267 | 272 | ||
268 | 273 | ||
269 | static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg, | 274 | static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, |
270 | struct nforce2_smbus *smbus, char *name) | 275 | int alt_reg, struct nforce2_smbus *smbus, const char *name) |
271 | { | 276 | { |
272 | u16 iobase; | ||
273 | int error; | 277 | int error; |
274 | 278 | ||
275 | if (pci_read_config_word(dev, reg, &iobase) != PCIBIOS_SUCCESSFUL) { | 279 | smbus->base = pci_resource_start(dev, bar); |
276 | dev_err(&smbus->adapter.dev, "Error reading PCI config for %s\n", name); | 280 | if (smbus->base) { |
277 | return -1; | 281 | smbus->size = pci_resource_len(dev, bar); |
282 | } else { | ||
283 | /* Older incarnations of the device used non-standard BARs */ | ||
284 | u16 iobase; | ||
285 | |||
286 | if (pci_read_config_word(dev, alt_reg, &iobase) | ||
287 | != PCIBIOS_SUCCESSFUL) { | ||
288 | dev_err(&dev->dev, "Error reading PCI config for %s\n", | ||
289 | name); | ||
290 | return -1; | ||
291 | } | ||
292 | |||
293 | smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; | ||
294 | smbus->size = 8; | ||
278 | } | 295 | } |
279 | smbus->dev = dev; | 296 | smbus->dev = dev; |
280 | smbus->base = iobase & 0xfffc; | ||
281 | smbus->size = 8; | ||
282 | 297 | ||
283 | if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { | 298 | if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { |
284 | dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", | 299 | dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", |
@@ -313,12 +328,13 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ | |||
313 | pci_set_drvdata(dev, smbuses); | 328 | pci_set_drvdata(dev, smbuses); |
314 | 329 | ||
315 | /* SMBus adapter 1 */ | 330 | /* SMBus adapter 1 */ |
316 | res1 = nforce2_probe_smb (dev, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); | 331 | res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1"); |
317 | if (res1 < 0) { | 332 | if (res1 < 0) { |
318 | dev_err(&dev->dev, "Error probing SMB1.\n"); | 333 | dev_err(&dev->dev, "Error probing SMB1.\n"); |
319 | smbuses[0].base = 0; /* to have a check value */ | 334 | smbuses[0].base = 0; /* to have a check value */ |
320 | } | 335 | } |
321 | res2 = nforce2_probe_smb (dev, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); | 336 | /* SMBus adapter 2 */ |
337 | res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2"); | ||
322 | if (res2 < 0) { | 338 | if (res2 < 0) { |
323 | dev_err(&dev->dev, "Error probing SMB2.\n"); | 339 | dev_err(&dev->dev, "Error probing SMB2.\n"); |
324 | smbuses[1].base = 0; /* to have a check value */ | 340 | smbuses[1].base = 0; /* to have a check value */ |
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c new file mode 100644 index 000000000000..592824087c49 --- /dev/null +++ b/drivers/i2c/busses/i2c-ocores.c | |||
@@ -0,0 +1,341 @@ | |||
1 | /* | ||
2 | * i2c-ocores.c: I2C bus driver for OpenCores I2C controller | ||
3 | * (http://www.opencores.org/projects.cgi/web/i2c/overview). | ||
4 | * | ||
5 | * Peter Korsgaard <jacmet@sunsite.dk> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/wait.h> | ||
22 | #include <linux/i2c-ocores.h> | ||
23 | #include <asm/io.h> | ||
24 | |||
25 | struct ocores_i2c { | ||
26 | void __iomem *base; | ||
27 | int regstep; | ||
28 | wait_queue_head_t wait; | ||
29 | struct i2c_adapter adap; | ||
30 | struct i2c_msg *msg; | ||
31 | int pos; | ||
32 | int nmsgs; | ||
33 | int state; /* see STATE_ */ | ||
34 | }; | ||
35 | |||
36 | /* registers */ | ||
37 | #define OCI2C_PRELOW 0 | ||
38 | #define OCI2C_PREHIGH 1 | ||
39 | #define OCI2C_CONTROL 2 | ||
40 | #define OCI2C_DATA 3 | ||
41 | #define OCI2C_CMD 4 /* write only */ | ||
42 | #define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ | ||
43 | |||
44 | #define OCI2C_CTRL_IEN 0x40 | ||
45 | #define OCI2C_CTRL_EN 0x80 | ||
46 | |||
47 | #define OCI2C_CMD_START 0x91 | ||
48 | #define OCI2C_CMD_STOP 0x41 | ||
49 | #define OCI2C_CMD_READ 0x21 | ||
50 | #define OCI2C_CMD_WRITE 0x11 | ||
51 | #define OCI2C_CMD_READ_ACK 0x21 | ||
52 | #define OCI2C_CMD_READ_NACK 0x29 | ||
53 | #define OCI2C_CMD_IACK 0x01 | ||
54 | |||
55 | #define OCI2C_STAT_IF 0x01 | ||
56 | #define OCI2C_STAT_TIP 0x02 | ||
57 | #define OCI2C_STAT_ARBLOST 0x20 | ||
58 | #define OCI2C_STAT_BUSY 0x40 | ||
59 | #define OCI2C_STAT_NACK 0x80 | ||
60 | |||
61 | #define STATE_DONE 0 | ||
62 | #define STATE_START 1 | ||
63 | #define STATE_WRITE 2 | ||
64 | #define STATE_READ 3 | ||
65 | #define STATE_ERROR 4 | ||
66 | |||
67 | static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) | ||
68 | { | ||
69 | iowrite8(value, i2c->base + reg * i2c->regstep); | ||
70 | } | ||
71 | |||
72 | static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) | ||
73 | { | ||
74 | return ioread8(i2c->base + reg * i2c->regstep); | ||
75 | } | ||
76 | |||
77 | static void ocores_process(struct ocores_i2c *i2c) | ||
78 | { | ||
79 | struct i2c_msg *msg = i2c->msg; | ||
80 | u8 stat = oc_getreg(i2c, OCI2C_STATUS); | ||
81 | |||
82 | if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { | ||
83 | /* stop has been sent */ | ||
84 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); | ||
85 | wake_up(&i2c->wait); | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | /* error? */ | ||
90 | if (stat & OCI2C_STAT_ARBLOST) { | ||
91 | i2c->state = STATE_ERROR; | ||
92 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); | ||
93 | return; | ||
94 | } | ||
95 | |||
96 | if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { | ||
97 | i2c->state = | ||
98 | (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; | ||
99 | |||
100 | if (stat & OCI2C_STAT_NACK) { | ||
101 | i2c->state = STATE_ERROR; | ||
102 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); | ||
103 | return; | ||
104 | } | ||
105 | } else | ||
106 | msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); | ||
107 | |||
108 | /* end of msg? */ | ||
109 | if (i2c->pos == msg->len) { | ||
110 | i2c->nmsgs--; | ||
111 | i2c->msg++; | ||
112 | i2c->pos = 0; | ||
113 | msg = i2c->msg; | ||
114 | |||
115 | if (i2c->nmsgs) { /* end? */ | ||
116 | /* send start? */ | ||
117 | if (!(msg->flags & I2C_M_NOSTART)) { | ||
118 | u8 addr = (msg->addr << 1); | ||
119 | |||
120 | if (msg->flags & I2C_M_RD) | ||
121 | addr |= 1; | ||
122 | |||
123 | i2c->state = STATE_START; | ||
124 | |||
125 | oc_setreg(i2c, OCI2C_DATA, addr); | ||
126 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); | ||
127 | return; | ||
128 | } else | ||
129 | i2c->state = (msg->flags & I2C_M_RD) | ||
130 | ? STATE_READ : STATE_WRITE; | ||
131 | } else { | ||
132 | i2c->state = STATE_DONE; | ||
133 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); | ||
134 | return; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | if (i2c->state == STATE_READ) { | ||
139 | oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? | ||
140 | OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); | ||
141 | } else { | ||
142 | oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); | ||
143 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs) | ||
148 | { | ||
149 | struct ocores_i2c *i2c = dev_id; | ||
150 | |||
151 | ocores_process(i2c); | ||
152 | |||
153 | return IRQ_HANDLED; | ||
154 | } | ||
155 | |||
156 | static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
157 | { | ||
158 | struct ocores_i2c *i2c = i2c_get_adapdata(adap); | ||
159 | |||
160 | i2c->msg = msgs; | ||
161 | i2c->pos = 0; | ||
162 | i2c->nmsgs = num; | ||
163 | i2c->state = STATE_START; | ||
164 | |||
165 | oc_setreg(i2c, OCI2C_DATA, | ||
166 | (i2c->msg->addr << 1) | | ||
167 | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); | ||
168 | |||
169 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); | ||
170 | |||
171 | if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || | ||
172 | (i2c->state == STATE_DONE), HZ)) | ||
173 | return (i2c->state == STATE_DONE) ? num : -EIO; | ||
174 | else | ||
175 | return -ETIMEDOUT; | ||
176 | } | ||
177 | |||
178 | static void ocores_init(struct ocores_i2c *i2c, | ||
179 | struct ocores_i2c_platform_data *pdata) | ||
180 | { | ||
181 | int prescale; | ||
182 | u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); | ||
183 | |||
184 | /* make sure the device is disabled */ | ||
185 | oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); | ||
186 | |||
187 | prescale = (pdata->clock_khz / (5*100)) - 1; | ||
188 | oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); | ||
189 | oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); | ||
190 | |||
191 | /* Init the device */ | ||
192 | oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); | ||
193 | oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); | ||
194 | } | ||
195 | |||
196 | |||
197 | static u32 ocores_func(struct i2c_adapter *adap) | ||
198 | { | ||
199 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
200 | } | ||
201 | |||
202 | static struct i2c_algorithm ocores_algorithm = { | ||
203 | .master_xfer = ocores_xfer, | ||
204 | .functionality = ocores_func, | ||
205 | }; | ||
206 | |||
207 | static struct i2c_adapter ocores_adapter = { | ||
208 | .owner = THIS_MODULE, | ||
209 | .name = "i2c-ocores", | ||
210 | .class = I2C_CLASS_HWMON, | ||
211 | .algo = &ocores_algorithm, | ||
212 | }; | ||
213 | |||
214 | |||
215 | static int __devinit ocores_i2c_probe(struct platform_device *pdev) | ||
216 | { | ||
217 | struct ocores_i2c *i2c; | ||
218 | struct ocores_i2c_platform_data *pdata; | ||
219 | struct resource *res, *res2; | ||
220 | int ret; | ||
221 | |||
222 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
223 | if (!res) | ||
224 | return -ENODEV; | ||
225 | |||
226 | res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
227 | if (!res2) | ||
228 | return -ENODEV; | ||
229 | |||
230 | pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data; | ||
231 | if (!pdata) | ||
232 | return -ENODEV; | ||
233 | |||
234 | i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); | ||
235 | if (!i2c) | ||
236 | return -ENOMEM; | ||
237 | |||
238 | if (!request_mem_region(res->start, res->end - res->start + 1, | ||
239 | pdev->name)) { | ||
240 | dev_err(&pdev->dev, "Memory region busy\n"); | ||
241 | ret = -EBUSY; | ||
242 | goto request_mem_failed; | ||
243 | } | ||
244 | |||
245 | i2c->base = ioremap(res->start, res->end - res->start + 1); | ||
246 | if (!i2c->base) { | ||
247 | dev_err(&pdev->dev, "Unable to map registers\n"); | ||
248 | ret = -EIO; | ||
249 | goto map_failed; | ||
250 | } | ||
251 | |||
252 | i2c->regstep = pdata->regstep; | ||
253 | ocores_init(i2c, pdata); | ||
254 | |||
255 | init_waitqueue_head(&i2c->wait); | ||
256 | ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c); | ||
257 | if (ret) { | ||
258 | dev_err(&pdev->dev, "Cannot claim IRQ\n"); | ||
259 | goto request_irq_failed; | ||
260 | } | ||
261 | |||
262 | /* hook up driver to tree */ | ||
263 | platform_set_drvdata(pdev, i2c); | ||
264 | i2c->adap = ocores_adapter; | ||
265 | i2c_set_adapdata(&i2c->adap, i2c); | ||
266 | i2c->adap.dev.parent = &pdev->dev; | ||
267 | |||
268 | /* add i2c adapter to i2c tree */ | ||
269 | ret = i2c_add_adapter(&i2c->adap); | ||
270 | if (ret) { | ||
271 | dev_err(&pdev->dev, "Failed to add adapter\n"); | ||
272 | goto add_adapter_failed; | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | |||
277 | add_adapter_failed: | ||
278 | free_irq(res2->start, i2c); | ||
279 | request_irq_failed: | ||
280 | iounmap(i2c->base); | ||
281 | map_failed: | ||
282 | release_mem_region(res->start, res->end - res->start + 1); | ||
283 | request_mem_failed: | ||
284 | kfree(i2c); | ||
285 | |||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int __devexit ocores_i2c_remove(struct platform_device* pdev) | ||
290 | { | ||
291 | struct ocores_i2c *i2c = platform_get_drvdata(pdev); | ||
292 | struct resource *res; | ||
293 | |||
294 | /* disable i2c logic */ | ||
295 | oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) | ||
296 | & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); | ||
297 | |||
298 | /* remove adapter & data */ | ||
299 | i2c_del_adapter(&i2c->adap); | ||
300 | platform_set_drvdata(pdev, NULL); | ||
301 | |||
302 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
303 | if (res) | ||
304 | free_irq(res->start, i2c); | ||
305 | |||
306 | iounmap(i2c->base); | ||
307 | |||
308 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
309 | if (res) | ||
310 | release_mem_region(res->start, res->end - res->start + 1); | ||
311 | |||
312 | kfree(i2c); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static struct platform_driver ocores_i2c_driver = { | ||
318 | .probe = ocores_i2c_probe, | ||
319 | .remove = __devexit_p(ocores_i2c_remove), | ||
320 | .driver = { | ||
321 | .owner = THIS_MODULE, | ||
322 | .name = "ocores-i2c", | ||
323 | }, | ||
324 | }; | ||
325 | |||
326 | static int __init ocores_i2c_init(void) | ||
327 | { | ||
328 | return platform_driver_register(&ocores_i2c_driver); | ||
329 | } | ||
330 | |||
331 | static void __exit ocores_i2c_exit(void) | ||
332 | { | ||
333 | platform_driver_unregister(&ocores_i2c_driver); | ||
334 | } | ||
335 | |||
336 | module_init(ocores_i2c_init); | ||
337 | module_exit(ocores_i2c_exit); | ||
338 | |||
339 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); | ||
340 | MODULE_DESCRIPTION("OpenCores I2C bus driver"); | ||
341 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index d9c7c00e71f9..8f2f65b793b9 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -102,13 +102,6 @@ MODULE_PARM_DESC(force_addr, | |||
102 | "Forcibly enable the PIIX4 at the given address. " | 102 | "Forcibly enable the PIIX4 at the given address. " |
103 | "EXTREMELY DANGEROUS!"); | 103 | "EXTREMELY DANGEROUS!"); |
104 | 104 | ||
105 | /* If fix_hstcfg is set to anything different from 0, we reset one of the | ||
106 | registers to be a valid value. */ | ||
107 | static int fix_hstcfg; | ||
108 | module_param (fix_hstcfg, int, 0); | ||
109 | MODULE_PARM_DESC(fix_hstcfg, | ||
110 | "Fix config register. Needed on some boards (Force CPCI735)."); | ||
111 | |||
112 | static int piix4_transaction(void); | 105 | static int piix4_transaction(void); |
113 | 106 | ||
114 | static unsigned short piix4_smba; | 107 | static unsigned short piix4_smba; |
@@ -137,7 +130,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
137 | /* Don't access SMBus on IBM systems which get corrupted eeproms */ | 130 | /* Don't access SMBus on IBM systems which get corrupted eeproms */ |
138 | if (dmi_check_system(piix4_dmi_table) && | 131 | if (dmi_check_system(piix4_dmi_table) && |
139 | PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { | 132 | PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { |
140 | dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module " | 133 | dev_err(&PIIX4_dev->dev, "IBM system detected; this module " |
141 | "may corrupt your serial eeprom! Refusing to load " | 134 | "may corrupt your serial eeprom! Refusing to load " |
142 | "module!\n"); | 135 | "module!\n"); |
143 | return -EPERM; | 136 | return -EPERM; |
@@ -166,22 +159,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
166 | 159 | ||
167 | pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); | 160 | pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); |
168 | 161 | ||
169 | /* Some BIOS will set up the chipset incorrectly and leave a register | ||
170 | in an undefined state (causing I2C to act very strangely). */ | ||
171 | if (temp & 0x02) { | ||
172 | if (fix_hstcfg) { | ||
173 | dev_info(&PIIX4_dev->dev, "Working around buggy BIOS " | ||
174 | "(I2C)\n"); | ||
175 | temp &= 0xfd; | ||
176 | pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp); | ||
177 | } else { | ||
178 | dev_info(&PIIX4_dev->dev, "Unusual config register " | ||
179 | "value\n"); | ||
180 | dev_info(&PIIX4_dev->dev, "Try using fix_hstcfg=1 if " | ||
181 | "you experience problems\n"); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | /* If force_addr is set, we program the new address here. Just to make | 162 | /* If force_addr is set, we program the new address here. Just to make |
186 | sure, we disable the PIIX4 first. */ | 163 | sure, we disable the PIIX4 first. */ |
187 | if (force_addr) { | 164 | if (force_addr) { |
@@ -214,7 +191,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
214 | } | 191 | } |
215 | } | 192 | } |
216 | 193 | ||
217 | if ((temp & 0x0E) == 8) | 194 | if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2)) |
218 | dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); | 195 | dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n"); |
219 | else if ((temp & 0x0E) == 0) | 196 | else if ((temp & 0x0E) == 0) |
220 | dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); | 197 | dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); |
@@ -413,6 +390,12 @@ static struct i2c_adapter piix4_adapter = { | |||
413 | static struct pci_device_id piix4_ids[] = { | 390 | static struct pci_device_id piix4_ids[] = { |
414 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), | 391 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3), |
415 | .driver_data = 3 }, | 392 | .driver_data = 3 }, |
393 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS), | ||
394 | .driver_data = 0 }, | ||
395 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS), | ||
396 | .driver_data = 0 }, | ||
397 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS), | ||
398 | .driver_data = 0 }, | ||
416 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), | 399 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4), |
417 | .driver_data = 0 }, | 400 | .driver_data = 0 }, |
418 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), | 401 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5), |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 766cc969c4d0..22a3eda04166 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
36 | #include <asm/msr.h> | ||
37 | 36 | ||
38 | #include <linux/scx200.h> | 37 | #include <linux/scx200.h> |
39 | 38 | ||
@@ -85,6 +84,10 @@ struct scx200_acb_iface { | |||
85 | u8 *ptr; | 84 | u8 *ptr; |
86 | char needs_reset; | 85 | char needs_reset; |
87 | unsigned len; | 86 | unsigned len; |
87 | |||
88 | /* PCI device info */ | ||
89 | struct pci_dev *pdev; | ||
90 | int bar; | ||
88 | }; | 91 | }; |
89 | 92 | ||
90 | /* Register Definitions */ | 93 | /* Register Definitions */ |
@@ -381,7 +384,7 @@ static struct i2c_algorithm scx200_acb_algorithm = { | |||
381 | static struct scx200_acb_iface *scx200_acb_list; | 384 | static struct scx200_acb_iface *scx200_acb_list; |
382 | static DECLARE_MUTEX(scx200_acb_list_mutex); | 385 | static DECLARE_MUTEX(scx200_acb_list_mutex); |
383 | 386 | ||
384 | static int scx200_acb_probe(struct scx200_acb_iface *iface) | 387 | static __init int scx200_acb_probe(struct scx200_acb_iface *iface) |
385 | { | 388 | { |
386 | u8 val; | 389 | u8 val; |
387 | 390 | ||
@@ -417,17 +420,16 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
417 | return 0; | 420 | return 0; |
418 | } | 421 | } |
419 | 422 | ||
420 | static int __init scx200_acb_create(const char *text, int base, int index) | 423 | static __init struct scx200_acb_iface *scx200_create_iface(const char *text, |
424 | int index) | ||
421 | { | 425 | { |
422 | struct scx200_acb_iface *iface; | 426 | struct scx200_acb_iface *iface; |
423 | struct i2c_adapter *adapter; | 427 | struct i2c_adapter *adapter; |
424 | int rc; | ||
425 | 428 | ||
426 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); | 429 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); |
427 | if (!iface) { | 430 | if (!iface) { |
428 | printk(KERN_ERR NAME ": can't allocate memory\n"); | 431 | printk(KERN_ERR NAME ": can't allocate memory\n"); |
429 | rc = -ENOMEM; | 432 | return NULL; |
430 | goto errout; | ||
431 | } | 433 | } |
432 | 434 | ||
433 | adapter = &iface->adapter; | 435 | adapter = &iface->adapter; |
@@ -440,26 +442,27 @@ static int __init scx200_acb_create(const char *text, int base, int index) | |||
440 | 442 | ||
441 | mutex_init(&iface->mutex); | 443 | mutex_init(&iface->mutex); |
442 | 444 | ||
443 | if (!request_region(base, 8, adapter->name)) { | 445 | return iface; |
444 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", | 446 | } |
445 | base, base + 8-1); | 447 | |
446 | rc = -EBUSY; | 448 | static int __init scx200_acb_create(struct scx200_acb_iface *iface) |
447 | goto errout_free; | 449 | { |
448 | } | 450 | struct i2c_adapter *adapter; |
449 | iface->base = base; | 451 | int rc; |
452 | |||
453 | adapter = &iface->adapter; | ||
450 | 454 | ||
451 | rc = scx200_acb_probe(iface); | 455 | rc = scx200_acb_probe(iface); |
452 | if (rc) { | 456 | if (rc) { |
453 | printk(KERN_WARNING NAME ": probe failed\n"); | 457 | printk(KERN_WARNING NAME ": probe failed\n"); |
454 | goto errout_release; | 458 | return rc; |
455 | } | 459 | } |
456 | 460 | ||
457 | scx200_acb_reset(iface); | 461 | scx200_acb_reset(iface); |
458 | 462 | ||
459 | if (i2c_add_adapter(adapter) < 0) { | 463 | if (i2c_add_adapter(adapter) < 0) { |
460 | printk(KERN_ERR NAME ": failed to register\n"); | 464 | printk(KERN_ERR NAME ": failed to register\n"); |
461 | rc = -ENODEV; | 465 | return -ENODEV; |
462 | goto errout_release; | ||
463 | } | 466 | } |
464 | 467 | ||
465 | down(&scx200_acb_list_mutex); | 468 | down(&scx200_acb_list_mutex); |
@@ -468,64 +471,148 @@ static int __init scx200_acb_create(const char *text, int base, int index) | |||
468 | up(&scx200_acb_list_mutex); | 471 | up(&scx200_acb_list_mutex); |
469 | 472 | ||
470 | return 0; | 473 | return 0; |
474 | } | ||
471 | 475 | ||
472 | errout_release: | 476 | static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, |
473 | release_region(iface->base, 8); | 477 | int bar) |
478 | { | ||
479 | struct scx200_acb_iface *iface; | ||
480 | int rc; | ||
481 | |||
482 | iface = scx200_create_iface(text, 0); | ||
483 | |||
484 | if (iface == NULL) | ||
485 | return -ENOMEM; | ||
486 | |||
487 | iface->pdev = pdev; | ||
488 | iface->bar = bar; | ||
489 | |||
490 | pci_enable_device_bars(iface->pdev, 1 << iface->bar); | ||
491 | |||
492 | rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); | ||
493 | |||
494 | if (rc != 0) { | ||
495 | printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", | ||
496 | iface->bar); | ||
497 | goto errout_free; | ||
498 | } | ||
499 | |||
500 | iface->base = pci_resource_start(iface->pdev, iface->bar); | ||
501 | rc = scx200_acb_create(iface); | ||
502 | |||
503 | if (rc == 0) | ||
504 | return 0; | ||
505 | |||
506 | pci_release_region(iface->pdev, iface->bar); | ||
507 | pci_dev_put(iface->pdev); | ||
474 | errout_free: | 508 | errout_free: |
475 | kfree(iface); | 509 | kfree(iface); |
476 | errout: | ||
477 | return rc; | 510 | return rc; |
478 | } | 511 | } |
479 | 512 | ||
480 | static struct pci_device_id scx200[] = { | 513 | static int __init scx200_create_isa(const char *text, unsigned long base, |
481 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, | 514 | int index) |
482 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, | 515 | { |
483 | { }, | 516 | struct scx200_acb_iface *iface; |
484 | }; | 517 | int rc; |
518 | |||
519 | iface = scx200_create_iface(text, index); | ||
520 | |||
521 | if (iface == NULL) | ||
522 | return -ENOMEM; | ||
523 | |||
524 | if (request_region(base, 8, iface->adapter.name) == 0) { | ||
525 | printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", | ||
526 | base, base + 8 - 1); | ||
527 | rc = -EBUSY; | ||
528 | goto errout_free; | ||
529 | } | ||
530 | |||
531 | iface->base = base; | ||
532 | rc = scx200_acb_create(iface); | ||
533 | |||
534 | if (rc == 0) | ||
535 | return 0; | ||
485 | 536 | ||
486 | static struct pci_device_id divil_pci[] = { | 537 | release_region(base, 8); |
487 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | 538 | errout_free: |
488 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 539 | kfree(iface); |
489 | { } /* NULL entry */ | 540 | return rc; |
541 | } | ||
542 | |||
543 | /* Driver data is an index into the scx200_data array that indicates | ||
544 | * the name and the BAR where the I/O address resource is located. ISA | ||
545 | * devices are flagged with a bar value of -1 */ | ||
546 | |||
547 | static struct pci_device_id scx200_pci[] = { | ||
548 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), | ||
549 | .driver_data = 0 }, | ||
550 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), | ||
551 | .driver_data = 0 }, | ||
552 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), | ||
553 | .driver_data = 1 }, | ||
554 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), | ||
555 | .driver_data = 2 } | ||
490 | }; | 556 | }; |
491 | 557 | ||
492 | #define MSR_LBAR_SMB 0x5140000B | 558 | static struct { |
559 | const char *name; | ||
560 | int bar; | ||
561 | } scx200_data[] = { | ||
562 | { "SCx200", -1 }, | ||
563 | { "CS5535", 0 }, | ||
564 | { "CS5536", 0 } | ||
565 | }; | ||
493 | 566 | ||
494 | static __init int scx200_add_cs553x(void) | 567 | static __init int scx200_scan_pci(void) |
495 | { | 568 | { |
496 | u32 low, hi; | 569 | int data, dev; |
497 | u32 smb_base; | 570 | int rc = -ENODEV; |
498 | 571 | struct pci_dev *pdev; | |
499 | /* Grab & reserve the SMB I/O range */ | 572 | |
500 | rdmsr(MSR_LBAR_SMB, low, hi); | 573 | for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { |
574 | pdev = pci_get_device(scx200_pci[dev].vendor, | ||
575 | scx200_pci[dev].device, NULL); | ||
576 | |||
577 | if (pdev == NULL) | ||
578 | continue; | ||
579 | |||
580 | data = scx200_pci[dev].driver_data; | ||
581 | |||
582 | /* if .bar is greater or equal to zero, this is a | ||
583 | * PCI device - otherwise, we assume | ||
584 | that the ports are ISA based | ||
585 | */ | ||
586 | |||
587 | if (scx200_data[data].bar >= 0) | ||
588 | rc = scx200_create_pci(scx200_data[data].name, pdev, | ||
589 | scx200_data[data].bar); | ||
590 | else { | ||
591 | int i; | ||
592 | |||
593 | for (i = 0; i < MAX_DEVICES; ++i) { | ||
594 | if (base[i] == 0) | ||
595 | continue; | ||
596 | |||
597 | rc = scx200_create_isa(scx200_data[data].name, | ||
598 | base[i], | ||
599 | i); | ||
600 | } | ||
601 | } | ||
501 | 602 | ||
502 | /* Check the IO mask and whether SMB is enabled */ | 603 | break; |
503 | if (hi != 0x0000F001) { | ||
504 | printk(KERN_WARNING NAME ": SMBus not enabled\n"); | ||
505 | return -ENODEV; | ||
506 | } | 604 | } |
507 | 605 | ||
508 | /* SMBus IO size is 8 bytes */ | 606 | return rc; |
509 | smb_base = low & 0x0000FFF8; | ||
510 | |||
511 | return scx200_acb_create("CS5535", smb_base, 0); | ||
512 | } | 607 | } |
513 | 608 | ||
514 | static int __init scx200_acb_init(void) | 609 | static int __init scx200_acb_init(void) |
515 | { | 610 | { |
516 | int i; | 611 | int rc; |
517 | int rc = -ENODEV; | ||
518 | 612 | ||
519 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); | 613 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); |
520 | 614 | ||
521 | /* Verify that this really is a SCx200 processor */ | 615 | rc = scx200_scan_pci(); |
522 | if (pci_dev_present(scx200)) { | ||
523 | for (i = 0; i < MAX_DEVICES; ++i) { | ||
524 | if (base[i] > 0) | ||
525 | rc = scx200_acb_create("SCx200", base[i], i); | ||
526 | } | ||
527 | } else if (pci_dev_present(divil_pci)) | ||
528 | rc = scx200_add_cs553x(); | ||
529 | 616 | ||
530 | /* If at least one bus was created, init must succeed */ | 617 | /* If at least one bus was created, init must succeed */ |
531 | if (scx200_acb_list) | 618 | if (scx200_acb_list) |
@@ -543,7 +630,14 @@ static void __exit scx200_acb_cleanup(void) | |||
543 | up(&scx200_acb_list_mutex); | 630 | up(&scx200_acb_list_mutex); |
544 | 631 | ||
545 | i2c_del_adapter(&iface->adapter); | 632 | i2c_del_adapter(&iface->adapter); |
546 | release_region(iface->base, 8); | 633 | |
634 | if (iface->pdev) { | ||
635 | pci_release_region(iface->pdev, iface->bar); | ||
636 | pci_dev_put(iface->pdev); | ||
637 | } | ||
638 | else | ||
639 | release_region(iface->base, 8); | ||
640 | |||
547 | kfree(iface); | 641 | kfree(iface); |
548 | down(&scx200_acb_list_mutex); | 642 | down(&scx200_acb_list_mutex); |
549 | } | 643 | } |