diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 26 | ||||
| -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 | ||||
| -rw-r--r-- | drivers/i2c/chips/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/i2c/chips/m41t00.c | 346 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/i2c-dev.c | 5 |
11 files changed, 877 insertions, 281 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d6d44946a283..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 |
| @@ -252,12 +255,12 @@ config I2C_POWERMAC | |||
| 252 | will be called i2c-powermac. | 255 | will be called i2c-powermac. |
| 253 | 256 | ||
| 254 | config I2C_MPC | 257 | config I2C_MPC |
| 255 | tristate "MPC107/824x/85xx/52xx" | 258 | tristate "MPC107/824x/85xx/52xx/86xx" |
| 256 | depends on I2C && PPC32 | 259 | depends on I2C && PPC32 |
| 257 | help | 260 | help |
| 258 | If you say yes to this option, support will be included for the | 261 | If you say yes to this option, support will be included for the |
| 259 | built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and | 262 | built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and |
| 260 | MPC85xx family processors. The driver may also work on 52xx | 263 | MPC85xx/MPC8641 family processors. The driver may also work on 52xx |
| 261 | family processors, though interrupts are known not to work. | 264 | family processors, though interrupts are known not to work. |
| 262 | 265 | ||
| 263 | This driver can also be built as a module. If so, the module | 266 | This driver can also be built as a module. If so, the module |
| @@ -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 | } |
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 7aa5c38f0855..87ee3ce58618 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig | |||
| @@ -39,6 +39,7 @@ config SENSORS_EEPROM | |||
| 39 | config SENSORS_PCF8574 | 39 | config SENSORS_PCF8574 |
| 40 | tristate "Philips PCF8574 and PCF8574A" | 40 | tristate "Philips PCF8574 and PCF8574A" |
| 41 | depends on I2C && EXPERIMENTAL | 41 | depends on I2C && EXPERIMENTAL |
| 42 | default n | ||
| 42 | help | 43 | help |
| 43 | If you say yes here you get support for Philips PCF8574 and | 44 | If you say yes here you get support for Philips PCF8574 and |
| 44 | PCF8574A chips. | 45 | PCF8574A chips. |
| @@ -46,6 +47,9 @@ config SENSORS_PCF8574 | |||
| 46 | This driver can also be built as a module. If so, the module | 47 | This driver can also be built as a module. If so, the module |
| 47 | will be called pcf8574. | 48 | will be called pcf8574. |
| 48 | 49 | ||
| 50 | These devices are hard to detect and rarely found on mainstream | ||
| 51 | hardware. If unsure, say N. | ||
| 52 | |||
| 49 | config SENSORS_PCA9539 | 53 | config SENSORS_PCA9539 |
| 50 | tristate "Philips PCA9539 16-bit I/O port" | 54 | tristate "Philips PCA9539 16-bit I/O port" |
| 51 | depends on I2C && EXPERIMENTAL | 55 | depends on I2C && EXPERIMENTAL |
| @@ -59,12 +63,16 @@ config SENSORS_PCA9539 | |||
| 59 | config SENSORS_PCF8591 | 63 | config SENSORS_PCF8591 |
| 60 | tristate "Philips PCF8591" | 64 | tristate "Philips PCF8591" |
| 61 | depends on I2C && EXPERIMENTAL | 65 | depends on I2C && EXPERIMENTAL |
| 66 | default n | ||
| 62 | help | 67 | help |
| 63 | If you say yes here you get support for Philips PCF8591 chips. | 68 | If you say yes here you get support for Philips PCF8591 chips. |
| 64 | 69 | ||
| 65 | This driver can also be built as a module. If so, the module | 70 | This driver can also be built as a module. If so, the module |
| 66 | will be called pcf8591. | 71 | will be called pcf8591. |
| 67 | 72 | ||
| 73 | These devices are hard to detect and rarely found on mainstream | ||
| 74 | hardware. If unsure, say N. | ||
| 75 | |||
| 68 | config ISP1301_OMAP | 76 | config ISP1301_OMAP |
| 69 | tristate "Philips ISP1301 with OMAP OTG" | 77 | tristate "Philips ISP1301 with OMAP OTG" |
| 70 | depends on I2C && ARCH_OMAP_OTG | 78 | depends on I2C && ARCH_OMAP_OTG |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 99ab4ec34390..2dd0a34d9472 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * drivers/i2c/chips/m41t00.c | 2 | * I2C client/driver for the ST M41T00 family of i2c rtc chips. |
| 3 | * | ||
| 4 | * I2C client/driver for the ST M41T00 Real-Time Clock chip. | ||
| 5 | * | 3 | * |
| 6 | * Author: Mark A. Greer <mgreer@mvista.com> | 4 | * Author: Mark A. Greer <mgreer@mvista.com> |
| 7 | * | 5 | * |
| 8 | * 2005 (c) MontaVista Software, Inc. This file is licensed under | 6 | * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under |
| 9 | * the terms of the GNU General Public License version 2. This program | 7 | * the terms of the GNU General Public License version 2. This program |
| 10 | * is licensed "as is" without any warranty of any kind, whether express | 8 | * is licensed "as is" without any warranty of any kind, whether express |
| 11 | * or implied. | 9 | * or implied. |
| @@ -13,9 +11,6 @@ | |||
| 13 | /* | 11 | /* |
| 14 | * This i2c client/driver wedges between the drivers/char/genrtc.c RTC | 12 | * This i2c client/driver wedges between the drivers/char/genrtc.c RTC |
| 15 | * interface and the SMBus interface of the i2c subsystem. | 13 | * interface and the SMBus interface of the i2c subsystem. |
| 16 | * It would be more efficient to use i2c msgs/i2c_transfer directly but, as | ||
| 17 | * recommened in .../Documentation/i2c/writing-clients section | ||
| 18 | * "Sending and receiving", using SMBus level communication is preferred. | ||
| 19 | */ | 14 | */ |
| 20 | 15 | ||
| 21 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| @@ -24,56 +19,110 @@ | |||
| 24 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 25 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
| 26 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
| 27 | #include <linux/mutex.h> | ||
| 28 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
| 29 | 23 | #include <linux/platform_device.h> | |
| 24 | #include <linux/m41t00.h> | ||
| 30 | #include <asm/time.h> | 25 | #include <asm/time.h> |
| 31 | #include <asm/rtc.h> | 26 | #include <asm/rtc.h> |
| 32 | 27 | ||
| 33 | #define M41T00_DRV_NAME "m41t00" | ||
| 34 | |||
| 35 | static DEFINE_MUTEX(m41t00_mutex); | ||
| 36 | |||
| 37 | static struct i2c_driver m41t00_driver; | 28 | static struct i2c_driver m41t00_driver; |
| 38 | static struct i2c_client *save_client; | 29 | static struct i2c_client *save_client; |
| 39 | 30 | ||
| 40 | static unsigned short ignore[] = { I2C_CLIENT_END }; | 31 | static unsigned short ignore[] = { I2C_CLIENT_END }; |
| 41 | static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; | 32 | static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
| 42 | 33 | ||
| 43 | static struct i2c_client_address_data addr_data = { | 34 | static struct i2c_client_address_data addr_data = { |
| 44 | .normal_i2c = normal_addr, | 35 | .normal_i2c = normal_addr, |
| 45 | .probe = ignore, | 36 | .probe = ignore, |
| 46 | .ignore = ignore, | 37 | .ignore = ignore, |
| 38 | }; | ||
| 39 | |||
| 40 | struct m41t00_chip_info { | ||
| 41 | u8 type; | ||
| 42 | char *name; | ||
| 43 | u8 read_limit; | ||
| 44 | u8 sec; /* Offsets for chip regs */ | ||
| 45 | u8 min; | ||
| 46 | u8 hour; | ||
| 47 | u8 day; | ||
| 48 | u8 mon; | ||
| 49 | u8 year; | ||
| 50 | u8 alarm_mon; | ||
| 51 | u8 alarm_hour; | ||
| 52 | u8 sqw; | ||
| 53 | u8 sqw_freq; | ||
| 47 | }; | 54 | }; |
| 48 | 55 | ||
| 56 | static struct m41t00_chip_info m41t00_chip_info_tbl[] = { | ||
| 57 | { | ||
| 58 | .type = M41T00_TYPE_M41T00, | ||
| 59 | .name = "m41t00", | ||
| 60 | .read_limit = 5, | ||
| 61 | .sec = 0, | ||
| 62 | .min = 1, | ||
| 63 | .hour = 2, | ||
| 64 | .day = 4, | ||
| 65 | .mon = 5, | ||
| 66 | .year = 6, | ||
| 67 | }, | ||
| 68 | { | ||
| 69 | .type = M41T00_TYPE_M41T81, | ||
| 70 | .name = "m41t81", | ||
| 71 | .read_limit = 1, | ||
| 72 | .sec = 1, | ||
| 73 | .min = 2, | ||
| 74 | .hour = 3, | ||
| 75 | .day = 5, | ||
| 76 | .mon = 6, | ||
| 77 | .year = 7, | ||
| 78 | .alarm_mon = 0xa, | ||
| 79 | .alarm_hour = 0xc, | ||
| 80 | .sqw = 0x13, | ||
| 81 | }, | ||
| 82 | { | ||
| 83 | .type = M41T00_TYPE_M41T85, | ||
| 84 | .name = "m41t85", | ||
| 85 | .read_limit = 1, | ||
| 86 | .sec = 1, | ||
| 87 | .min = 2, | ||
| 88 | .hour = 3, | ||
| 89 | .day = 5, | ||
| 90 | .mon = 6, | ||
| 91 | .year = 7, | ||
| 92 | .alarm_mon = 0xa, | ||
| 93 | .alarm_hour = 0xc, | ||
| 94 | .sqw = 0x13, | ||
| 95 | }, | ||
| 96 | }; | ||
| 97 | static struct m41t00_chip_info *m41t00_chip; | ||
| 98 | |||
| 49 | ulong | 99 | ulong |
| 50 | m41t00_get_rtc_time(void) | 100 | m41t00_get_rtc_time(void) |
| 51 | { | 101 | { |
| 52 | s32 sec, min, hour, day, mon, year; | 102 | s32 sec, min, hour, day, mon, year; |
| 53 | s32 sec1, min1, hour1, day1, mon1, year1; | 103 | s32 sec1, min1, hour1, day1, mon1, year1; |
| 54 | ulong limit = 10; | 104 | u8 reads = 0; |
| 105 | u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */ | ||
| 106 | struct i2c_msg msgs[] = { | ||
| 107 | { | ||
| 108 | .addr = save_client->addr, | ||
| 109 | .flags = 0, | ||
| 110 | .len = 1, | ||
| 111 | .buf = msgbuf, | ||
| 112 | }, | ||
| 113 | { | ||
| 114 | .addr = save_client->addr, | ||
| 115 | .flags = I2C_M_RD, | ||
| 116 | .len = 8, | ||
| 117 | .buf = buf, | ||
| 118 | }, | ||
| 119 | }; | ||
| 55 | 120 | ||
| 56 | sec = min = hour = day = mon = year = 0; | 121 | sec = min = hour = day = mon = year = 0; |
| 57 | sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; | ||
| 58 | 122 | ||
| 59 | mutex_lock(&m41t00_mutex); | ||
| 60 | do { | 123 | do { |
| 61 | if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) | 124 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) |
| 62 | && ((min = i2c_smbus_read_byte_data(save_client, 1)) | 125 | goto read_err; |
| 63 | >= 0) | ||
| 64 | && ((hour = i2c_smbus_read_byte_data(save_client, 2)) | ||
| 65 | >= 0) | ||
| 66 | && ((day = i2c_smbus_read_byte_data(save_client, 4)) | ||
| 67 | >= 0) | ||
| 68 | && ((mon = i2c_smbus_read_byte_data(save_client, 5)) | ||
| 69 | >= 0) | ||
| 70 | && ((year = i2c_smbus_read_byte_data(save_client, 6)) | ||
| 71 | >= 0) | ||
| 72 | && ((sec == sec1) && (min == min1) && (hour == hour1) | ||
| 73 | && (day == day1) && (mon == mon1) | ||
| 74 | && (year == year1))) | ||
| 75 | |||
| 76 | break; | ||
| 77 | 126 | ||
| 78 | sec1 = sec; | 127 | sec1 = sec; |
| 79 | min1 = min; | 128 | min1 = min; |
| @@ -81,69 +130,88 @@ m41t00_get_rtc_time(void) | |||
| 81 | day1 = day; | 130 | day1 = day; |
| 82 | mon1 = mon; | 131 | mon1 = mon; |
| 83 | year1 = year; | 132 | year1 = year; |
| 84 | } while (--limit > 0); | ||
| 85 | mutex_unlock(&m41t00_mutex); | ||
| 86 | |||
| 87 | if (limit == 0) { | ||
| 88 | dev_warn(&save_client->dev, | ||
| 89 | "m41t00: can't read rtc chip\n"); | ||
| 90 | sec = min = hour = day = mon = year = 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | sec &= 0x7f; | ||
| 94 | min &= 0x7f; | ||
| 95 | hour &= 0x3f; | ||
| 96 | day &= 0x3f; | ||
| 97 | mon &= 0x1f; | ||
| 98 | year &= 0xff; | ||
| 99 | 133 | ||
| 100 | BCD_TO_BIN(sec); | 134 | sec = buf[m41t00_chip->sec] & 0x7f; |
| 101 | BCD_TO_BIN(min); | 135 | min = buf[m41t00_chip->min] & 0x7f; |
| 102 | BCD_TO_BIN(hour); | 136 | hour = buf[m41t00_chip->hour] & 0x3f; |
| 103 | BCD_TO_BIN(day); | 137 | day = buf[m41t00_chip->day] & 0x3f; |
| 104 | BCD_TO_BIN(mon); | 138 | mon = buf[m41t00_chip->mon] & 0x1f; |
| 105 | BCD_TO_BIN(year); | 139 | year = buf[m41t00_chip->year]; |
| 140 | } while ((++reads < m41t00_chip->read_limit) && ((sec != sec1) | ||
| 141 | || (min != min1) || (hour != hour1) || (day != day1) | ||
| 142 | || (mon != mon1) || (year != year1))); | ||
| 143 | |||
| 144 | if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1) | ||
| 145 | || (hour != hour1) || (day != day1) || (mon != mon1) | ||
| 146 | || (year != year1))) | ||
| 147 | goto read_err; | ||
| 148 | |||
| 149 | sec = BCD2BIN(sec); | ||
| 150 | min = BCD2BIN(min); | ||
| 151 | hour = BCD2BIN(hour); | ||
| 152 | day = BCD2BIN(day); | ||
| 153 | mon = BCD2BIN(mon); | ||
| 154 | year = BCD2BIN(year); | ||
| 106 | 155 | ||
| 107 | year += 1900; | 156 | year += 1900; |
| 108 | if (year < 1970) | 157 | if (year < 1970) |
| 109 | year += 100; | 158 | year += 100; |
| 110 | 159 | ||
| 111 | return mktime(year, mon, day, hour, min, sec); | 160 | return mktime(year, mon, day, hour, min, sec); |
| 161 | |||
| 162 | read_err: | ||
| 163 | dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n"); | ||
| 164 | return 0; | ||
| 112 | } | 165 | } |
| 166 | EXPORT_SYMBOL_GPL(m41t00_get_rtc_time); | ||
| 113 | 167 | ||
| 114 | static void | 168 | static void |
| 115 | m41t00_set(void *arg) | 169 | m41t00_set(void *arg) |
| 116 | { | 170 | { |
| 117 | struct rtc_time tm; | 171 | struct rtc_time tm; |
| 118 | ulong nowtime = *(ulong *)arg; | 172 | int nowtime = *(int *)arg; |
| 173 | s32 sec, min, hour, day, mon, year; | ||
| 174 | u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 }; | ||
| 175 | struct i2c_msg msgs[] = { | ||
| 176 | { | ||
| 177 | .addr = save_client->addr, | ||
| 178 | .flags = 0, | ||
| 179 | .len = 1, | ||
| 180 | .buf = msgbuf, | ||
| 181 | }, | ||
| 182 | { | ||
| 183 | .addr = save_client->addr, | ||
| 184 | .flags = I2C_M_RD, | ||
| 185 | .len = 8, | ||
| 186 | .buf = buf, | ||
| 187 | }, | ||
| 188 | }; | ||
| 119 | 189 | ||
| 120 | to_tm(nowtime, &tm); | 190 | to_tm(nowtime, &tm); |
| 121 | tm.tm_year = (tm.tm_year - 1900) % 100; | 191 | tm.tm_year = (tm.tm_year - 1900) % 100; |
| 122 | 192 | ||
| 123 | BIN_TO_BCD(tm.tm_sec); | 193 | sec = BIN2BCD(tm.tm_sec); |
| 124 | BIN_TO_BCD(tm.tm_min); | 194 | min = BIN2BCD(tm.tm_min); |
| 125 | BIN_TO_BCD(tm.tm_hour); | 195 | hour = BIN2BCD(tm.tm_hour); |
| 126 | BIN_TO_BCD(tm.tm_mon); | 196 | day = BIN2BCD(tm.tm_mday); |
| 127 | BIN_TO_BCD(tm.tm_mday); | 197 | mon = BIN2BCD(tm.tm_mon); |
| 128 | BIN_TO_BCD(tm.tm_year); | 198 | year = BIN2BCD(tm.tm_year); |
| 129 | 199 | ||
| 130 | mutex_lock(&m41t00_mutex); | 200 | /* Read reg values into buf[0..7]/wbuf[1..8] */ |
| 131 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) | 201 | if (i2c_transfer(save_client->adapter, msgs, 2) < 0) { |
| 132 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) | 202 | dev_err(&save_client->dev, "m41t00_set: Read error\n"); |
| 133 | < 0) | 203 | return; |
| 134 | || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) | 204 | } |
| 135 | < 0) | 205 | |
| 136 | || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) | 206 | wbuf[0] = 0; /* offset into rtc's regs */ |
| 137 | < 0) | 207 | buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f); |
| 138 | || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) | 208 | buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f); |
| 139 | < 0) | 209 | buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f); |
| 140 | || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) | 210 | buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f); |
| 141 | < 0)) | 211 | buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f); |
| 142 | 212 | ||
| 143 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); | 213 | if (i2c_master_send(save_client, wbuf, 9) < 0) |
| 144 | 214 | dev_err(&save_client->dev, "m41t00_set: Write error\n"); | |
| 145 | mutex_unlock(&m41t00_mutex); | ||
| 146 | return; | ||
| 147 | } | 215 | } |
| 148 | 216 | ||
| 149 | static ulong new_time; | 217 | static ulong new_time; |
| @@ -162,6 +230,48 @@ m41t00_set_rtc_time(ulong nowtime) | |||
| 162 | 230 | ||
| 163 | return 0; | 231 | return 0; |
| 164 | } | 232 | } |
| 233 | EXPORT_SYMBOL_GPL(m41t00_set_rtc_time); | ||
| 234 | |||
| 235 | /* | ||
| 236 | ***************************************************************************** | ||
| 237 | * | ||
| 238 | * platform_data Driver Interface | ||
| 239 | * | ||
| 240 | ***************************************************************************** | ||
| 241 | */ | ||
| 242 | static int __init | ||
| 243 | m41t00_platform_probe(struct platform_device *pdev) | ||
| 244 | { | ||
| 245 | struct m41t00_platform_data *pdata; | ||
| 246 | int i; | ||
| 247 | |||
| 248 | if (pdev && (pdata = pdev->dev.platform_data)) { | ||
| 249 | normal_addr[0] = pdata->i2c_addr; | ||
| 250 | |||
| 251 | for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++) | ||
| 252 | if (m41t00_chip_info_tbl[i].type == pdata->type) { | ||
| 253 | m41t00_chip = &m41t00_chip_info_tbl[i]; | ||
| 254 | m41t00_chip->sqw_freq = pdata->sqw_freq; | ||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | return -ENODEV; | ||
| 259 | } | ||
| 260 | |||
| 261 | static int __exit | ||
| 262 | m41t00_platform_remove(struct platform_device *pdev) | ||
| 263 | { | ||
| 264 | return 0; | ||
| 265 | } | ||
| 266 | |||
| 267 | static struct platform_driver m41t00_platform_driver = { | ||
| 268 | .probe = m41t00_platform_probe, | ||
| 269 | .remove = m41t00_platform_remove, | ||
| 270 | .driver = { | ||
| 271 | .owner = THIS_MODULE, | ||
| 272 | .name = M41T00_DRV_NAME, | ||
| 273 | }, | ||
| 274 | }; | ||
| 165 | 275 | ||
| 166 | /* | 276 | /* |
| 167 | ***************************************************************************** | 277 | ***************************************************************************** |
| @@ -176,23 +286,71 @@ m41t00_probe(struct i2c_adapter *adap, int addr, int kind) | |||
| 176 | struct i2c_client *client; | 286 | struct i2c_client *client; |
| 177 | int rc; | 287 | int rc; |
| 178 | 288 | ||
| 289 | if (!i2c_check_functionality(adap, I2C_FUNC_I2C | ||
| 290 | | I2C_FUNC_SMBUS_BYTE_DATA)) | ||
| 291 | return 0; | ||
| 292 | |||
| 179 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 293 | client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); |
| 180 | if (!client) | 294 | if (!client) |
| 181 | return -ENOMEM; | 295 | return -ENOMEM; |
| 182 | 296 | ||
| 183 | strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); | 297 | strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE); |
| 184 | client->addr = addr; | 298 | client->addr = addr; |
| 185 | client->adapter = adap; | 299 | client->adapter = adap; |
| 186 | client->driver = &m41t00_driver; | 300 | client->driver = &m41t00_driver; |
| 187 | 301 | ||
| 188 | if ((rc = i2c_attach_client(client)) != 0) { | 302 | if ((rc = i2c_attach_client(client))) |
| 189 | kfree(client); | 303 | goto attach_err; |
| 190 | return rc; | 304 | |
| 305 | if (m41t00_chip->type != M41T00_TYPE_M41T00) { | ||
| 306 | /* If asked, disable SQW, set SQW frequency & re-enable */ | ||
| 307 | if (m41t00_chip->sqw_freq) | ||
| 308 | if (((rc = i2c_smbus_read_byte_data(client, | ||
| 309 | m41t00_chip->alarm_mon)) < 0) | ||
| 310 | || ((rc = i2c_smbus_write_byte_data(client, | ||
| 311 | m41t00_chip->alarm_mon, rc & ~0x40)) <0) | ||
| 312 | || ((rc = i2c_smbus_write_byte_data(client, | ||
| 313 | m41t00_chip->sqw, | ||
| 314 | m41t00_chip->sqw_freq)) < 0) | ||
| 315 | || ((rc = i2c_smbus_write_byte_data(client, | ||
| 316 | m41t00_chip->alarm_mon, rc | 0x40)) <0)) | ||
| 317 | goto sqw_err; | ||
| 318 | |||
| 319 | /* Make sure HT (Halt Update) bit is cleared */ | ||
| 320 | if ((rc = i2c_smbus_read_byte_data(client, | ||
| 321 | m41t00_chip->alarm_hour)) < 0) | ||
| 322 | goto ht_err; | ||
| 323 | |||
| 324 | if (rc & 0x40) | ||
| 325 | if ((rc = i2c_smbus_write_byte_data(client, | ||
| 326 | m41t00_chip->alarm_hour, rc & ~0x40))<0) | ||
| 327 | goto ht_err; | ||
| 191 | } | 328 | } |
| 192 | 329 | ||
| 193 | m41t00_wq = create_singlethread_workqueue("m41t00"); | 330 | /* Make sure ST (stop) bit is cleared */ |
| 331 | if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0) | ||
| 332 | goto st_err; | ||
| 333 | |||
| 334 | if (rc & 0x80) | ||
| 335 | if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec, | ||
| 336 | rc & ~0x80)) < 0) | ||
| 337 | goto st_err; | ||
| 338 | |||
| 339 | m41t00_wq = create_singlethread_workqueue(m41t00_chip->name); | ||
| 194 | save_client = client; | 340 | save_client = client; |
| 195 | return 0; | 341 | return 0; |
| 342 | |||
| 343 | st_err: | ||
| 344 | dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n"); | ||
| 345 | goto attach_err; | ||
| 346 | ht_err: | ||
| 347 | dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n"); | ||
| 348 | goto attach_err; | ||
| 349 | sqw_err: | ||
| 350 | dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n"); | ||
| 351 | attach_err: | ||
| 352 | kfree(client); | ||
| 353 | return rc; | ||
| 196 | } | 354 | } |
| 197 | 355 | ||
| 198 | static int | 356 | static int |
| @@ -204,7 +362,7 @@ m41t00_attach(struct i2c_adapter *adap) | |||
| 204 | static int | 362 | static int |
| 205 | m41t00_detach(struct i2c_client *client) | 363 | m41t00_detach(struct i2c_client *client) |
| 206 | { | 364 | { |
| 207 | int rc; | 365 | int rc; |
| 208 | 366 | ||
| 209 | if ((rc = i2c_detach_client(client)) == 0) { | 367 | if ((rc = i2c_detach_client(client)) == 0) { |
| 210 | kfree(client); | 368 | kfree(client); |
| @@ -225,14 +383,18 @@ static struct i2c_driver m41t00_driver = { | |||
| 225 | static int __init | 383 | static int __init |
| 226 | m41t00_init(void) | 384 | m41t00_init(void) |
| 227 | { | 385 | { |
| 228 | return i2c_add_driver(&m41t00_driver); | 386 | int rc; |
| 387 | |||
| 388 | if (!(rc = platform_driver_register(&m41t00_platform_driver))) | ||
| 389 | rc = i2c_add_driver(&m41t00_driver); | ||
| 390 | return rc; | ||
| 229 | } | 391 | } |
| 230 | 392 | ||
| 231 | static void __exit | 393 | static void __exit |
| 232 | m41t00_exit(void) | 394 | m41t00_exit(void) |
| 233 | { | 395 | { |
| 234 | i2c_del_driver(&m41t00_driver); | 396 | i2c_del_driver(&m41t00_driver); |
| 235 | return; | 397 | platform_driver_unregister(&m41t00_platform_driver); |
| 236 | } | 398 | } |
| 237 | 399 | ||
| 238 | module_init(m41t00_init); | 400 | module_init(m41t00_init); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 45e2cdf54736..a45155f799d4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) | |||
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | 918 | s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, |
| 919 | u8 length, u8 *values) | 919 | u8 length, const u8 *values) |
| 920 | { | 920 | { |
| 921 | union i2c_smbus_data data; | 921 | union i2c_smbus_data data; |
| 922 | 922 | ||
| @@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val | |||
| 944 | } | 944 | } |
| 945 | 945 | ||
| 946 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | 946 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, |
| 947 | u8 length, u8 *values) | 947 | u8 length, const u8 *values) |
| 948 | { | 948 | { |
| 949 | union i2c_smbus_data data; | 949 | union i2c_smbus_data data; |
| 950 | 950 | ||
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index ed7eed388bae..58ccddd5c237 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
| @@ -426,10 +426,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
| 426 | 426 | ||
| 427 | /* register this i2c device with the driver core */ | 427 | /* register this i2c device with the driver core */ |
| 428 | i2c_dev->adap = adap; | 428 | i2c_dev->adap = adap; |
| 429 | if (adap->dev.parent == &platform_bus) | 429 | dev = &adap->dev; |
| 430 | dev = &adap->dev; | ||
| 431 | else | ||
| 432 | dev = adap->dev.parent; | ||
| 433 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, | 430 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, |
| 434 | MKDEV(I2C_MAJOR, i2c_dev->minor), | 431 | MKDEV(I2C_MAJOR, i2c_dev->minor), |
| 435 | dev, "i2c-%d", i2c_dev->minor); | 432 | dev, "i2c-%d", i2c_dev->minor); |
