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 | 158 | ||||
-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, 881 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..8b46ef7d9ff8 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,80 @@ 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; | ||
544 | 477 | ||
545 | if (i801_setup(dev)) { | 478 | err = pci_enable_device(dev); |
546 | dev_warn(&dev->dev, | 479 | if (err) { |
547 | "I801 not detected, module not inserted.\n"); | 480 | dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n", |
548 | return -ENODEV; | 481 | err); |
482 | goto exit; | ||
549 | } | 483 | } |
550 | 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; | ||
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; | ||
500 | } | ||
501 | |||
502 | pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); | ||
503 | temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ | ||
504 | if (!(temp & SMBHSTCFG_HST_EN)) { | ||
505 | dev_info(&dev->dev, "Enabling SMBus device\n"); | ||
506 | temp |= SMBHSTCFG_HST_EN; | ||
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"); | ||
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_release; | ||
524 | } | ||
525 | return 0; | ||
526 | |||
527 | exit_release: | ||
528 | pci_release_region(dev, SMBBAR); | ||
529 | exit: | ||
530 | return err; | ||
557 | } | 531 | } |
558 | 532 | ||
559 | static void __devexit i801_remove(struct pci_dev *dev) | 533 | static void __devexit i801_remove(struct pci_dev *dev) |
560 | { | 534 | { |
561 | i2c_del_adapter(&i801_adapter); | 535 | i2c_del_adapter(&i801_adapter); |
562 | release_region(i801_smba, (isich4 ? 16 : 8)); | 536 | pci_release_region(dev, SMBBAR); |
537 | /* | ||
538 | * do not call pci_disable_device(dev) since it can cause hard hangs on | ||
539 | * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) | ||
540 | */ | ||
563 | } | 541 | } |
564 | 542 | ||
565 | static struct pci_driver i801_driver = { | 543 | 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); |