]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/i2c/busses/i2c-piix4.c
924e84a53488c3aad5dae799fdd74af9c8dbd823
[linux-2.6-omap-h63xx.git] / drivers / i2c / busses / i2c-piix4.c
1 /*
2     piix4.c - Part of lm_sensors, Linux kernel modules for hardware
3               monitoring
4     Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
5     Philip Edelbrock <phil@netroedge.com>
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /*
23    Supports:
24         Intel PIIX4, 440MX
25         Serverworks OSB4, CSB5, CSB6, HT-1000
26         ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
27         SMSC Victory66
28
29    Note: we assume there can only be one device, with one SMBus interface.
30 */
31
32 #include <linux/module.h>
33 #include <linux/moduleparam.h>
34 #include <linux/pci.h>
35 #include <linux/kernel.h>
36 #include <linux/delay.h>
37 #include <linux/stddef.h>
38 #include <linux/ioport.h>
39 #include <linux/i2c.h>
40 #include <linux/init.h>
41 #include <linux/dmi.h>
42 #include <linux/acpi.h>
43 #include <asm/io.h>
44
45
46 /* PIIX4 SMBus address offsets */
47 #define SMBHSTSTS       (0 + piix4_smba)
48 #define SMBHSLVSTS      (1 + piix4_smba)
49 #define SMBHSTCNT       (2 + piix4_smba)
50 #define SMBHSTCMD       (3 + piix4_smba)
51 #define SMBHSTADD       (4 + piix4_smba)
52 #define SMBHSTDAT0      (5 + piix4_smba)
53 #define SMBHSTDAT1      (6 + piix4_smba)
54 #define SMBBLKDAT       (7 + piix4_smba)
55 #define SMBSLVCNT       (8 + piix4_smba)
56 #define SMBSHDWCMD      (9 + piix4_smba)
57 #define SMBSLVEVT       (0xA + piix4_smba)
58 #define SMBSLVDAT       (0xC + piix4_smba)
59
60 /* count for request_region */
61 #define SMBIOSIZE       8
62
63 /* PCI Address Constants */
64 #define SMBBA           0x090
65 #define SMBHSTCFG       0x0D2
66 #define SMBSLVC         0x0D3
67 #define SMBSHDW1        0x0D4
68 #define SMBSHDW2        0x0D5
69 #define SMBREV          0x0D6
70
71 /* Other settings */
72 #define MAX_TIMEOUT     500
73 #define  ENABLE_INT9    0
74
75 /* PIIX4 constants */
76 #define PIIX4_QUICK             0x00
77 #define PIIX4_BYTE              0x04
78 #define PIIX4_BYTE_DATA         0x08
79 #define PIIX4_WORD_DATA         0x0C
80 #define PIIX4_BLOCK_DATA        0x14
81
82 /* insmod parameters */
83
84 /* If force is set to anything different from 0, we forcibly enable the
85    PIIX4. DANGEROUS! */
86 static int force;
87 module_param (force, int, 0);
88 MODULE_PARM_DESC(force, "Forcibly enable the PIIX4. DANGEROUS!");
89
90 /* If force_addr is set to anything different from 0, we forcibly enable
91    the PIIX4 at the given address. VERY DANGEROUS! */
92 static int force_addr;
93 module_param (force_addr, int, 0);
94 MODULE_PARM_DESC(force_addr,
95                  "Forcibly enable the PIIX4 at the given address. "
96                  "EXTREMELY DANGEROUS!");
97
98 static unsigned short piix4_smba;
99 static int srvrworks_csb5_delay;
100 static struct pci_driver piix4_driver;
101 static struct i2c_adapter piix4_adapter;
102
103 static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
104         {
105                 .ident = "Sapphire AM2RD790",
106                 .matches = {
107                         DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
108                         DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
109                 },
110         },
111         {
112                 .ident = "DFI Lanparty UT 790FX",
113                 .matches = {
114                         DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
115                         DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
116                 },
117         },
118         { }
119 };
120
121 /* The IBM entry is in a separate table because we only check it
122    on Intel-based systems */
123 static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
124         {
125                 .ident = "IBM",
126                 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
127         },
128         { },
129 };
130
131 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
132                                 const struct pci_device_id *id)
133 {
134         unsigned char temp;
135
136         if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
137             (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
138                 srvrworks_csb5_delay = 1;
139
140         /* On some motherboards, it was reported that accessing the SMBus
141            caused severe hardware problems */
142         if (dmi_check_system(piix4_dmi_blacklist)) {
143                 dev_err(&PIIX4_dev->dev,
144                         "Accessing the SMBus on this system is unsafe!\n");
145                 return -EPERM;
146         }
147
148         /* Don't access SMBus on IBM systems which get corrupted eeproms */
149         if (dmi_check_system(piix4_dmi_ibm) &&
150                         PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
151                 dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
152                         "may corrupt your serial eeprom! Refusing to load "
153                         "module!\n");
154                 return -EPERM;
155         }
156
157         /* Determine the address of the SMBus areas */
158         if (force_addr) {
159                 piix4_smba = force_addr & 0xfff0;
160                 force = 0;
161         } else {
162                 pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
163                 piix4_smba &= 0xfff0;
164                 if(piix4_smba == 0) {
165                         dev_err(&PIIX4_dev->dev, "SMBus base address "
166                                 "uninitialized - upgrade BIOS or use "
167                                 "force_addr=0xaddr\n");
168                         return -ENODEV;
169                 }
170         }
171
172         if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
173                 return -EBUSY;
174
175         if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
176                 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
177                         piix4_smba);
178                 return -EBUSY;
179         }
180
181         pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
182
183         /* If force_addr is set, we program the new address here. Just to make
184            sure, we disable the PIIX4 first. */
185         if (force_addr) {
186                 pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp & 0xfe);
187                 pci_write_config_word(PIIX4_dev, SMBBA, piix4_smba);
188                 pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp | 0x01);
189                 dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to "
190                         "new address %04x!\n", piix4_smba);
191         } else if ((temp & 1) == 0) {
192                 if (force) {
193                         /* This should never need to be done, but has been
194                          * noted that many Dell machines have the SMBus
195                          * interface on the PIIX4 disabled!? NOTE: This assumes
196                          * I/O space and other allocations WERE done by the
197                          * Bios!  Don't complain if your hardware does weird
198                          * things after enabling this. :') Check for Bios
199                          * updates before resorting to this.
200                          */
201                         pci_write_config_byte(PIIX4_dev, SMBHSTCFG,
202                                               temp | 1);
203                         dev_printk(KERN_NOTICE, &PIIX4_dev->dev,
204                                 "WARNING: SMBus interface has been "
205                                 "FORCEFULLY ENABLED!\n");
206                 } else {
207                         dev_err(&PIIX4_dev->dev,
208                                 "Host SMBus controller not enabled!\n");
209                         release_region(piix4_smba, SMBIOSIZE);
210                         piix4_smba = 0;
211                         return -ENODEV;
212                 }
213         }
214
215         if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
216                 dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
217         else if ((temp & 0x0E) == 0)
218                 dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
219         else
220                 dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
221                         "(or code out of date)!\n");
222
223         pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
224         dev_info(&PIIX4_dev->dev,
225                  "SMBus Host Controller at 0x%x, revision %d\n",
226                  piix4_smba, temp);
227
228         return 0;
229 }
230
231 static int piix4_transaction(void)
232 {
233         int temp;
234         int result = 0;
235         int timeout = 0;
236
237         dev_dbg(&piix4_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
238                 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
239                 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
240                 inb_p(SMBHSTDAT1));
241
242         /* Make sure the SMBus host is ready to start transmitting */
243         if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
244                 dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). "
245                         "Resetting...\n", temp);
246                 outb_p(temp, SMBHSTSTS);
247                 if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
248                         dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
249                         return -EBUSY;
250                 } else {
251                         dev_dbg(&piix4_adapter.dev, "Successful!\n");
252                 }
253         }
254
255         /* start the transaction by setting bit 6 */
256         outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
257
258         /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
259         if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
260                 msleep(2);
261         else
262                 msleep(1);
263
264         while ((timeout++ < MAX_TIMEOUT) &&
265                ((temp = inb_p(SMBHSTSTS)) & 0x01))
266                 msleep(1);
267
268         /* If the SMBus is still busy, we give up */
269         if (timeout >= MAX_TIMEOUT) {
270                 dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
271                 result = -ETIMEDOUT;
272         }
273
274         if (temp & 0x10) {
275                 result = -EIO;
276                 dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n");
277         }
278
279         if (temp & 0x08) {
280                 result = -EIO;
281                 dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be "
282                         "locked until next hard reset. (sorry!)\n");
283                 /* Clock stops and slave is stuck in mid-transmission */
284         }
285
286         if (temp & 0x04) {
287                 result = -ENXIO;
288                 dev_dbg(&piix4_adapter.dev, "Error: no response!\n");
289         }
290
291         if (inb_p(SMBHSTSTS) != 0x00)
292                 outb_p(inb(SMBHSTSTS), SMBHSTSTS);
293
294         if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
295                 dev_err(&piix4_adapter.dev, "Failed reset at end of "
296                         "transaction (%02x)\n", temp);
297         }
298         dev_dbg(&piix4_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
299                 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
300                 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
301                 inb_p(SMBHSTDAT1));
302         return result;
303 }
304
305 /* Return negative errno on error. */
306 static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
307                  unsigned short flags, char read_write,
308                  u8 command, int size, union i2c_smbus_data * data)
309 {
310         int i, len;
311         int status;
312
313         switch (size) {
314         case I2C_SMBUS_QUICK:
315                 outb_p((addr << 1) | read_write,
316                        SMBHSTADD);
317                 size = PIIX4_QUICK;
318                 break;
319         case I2C_SMBUS_BYTE:
320                 outb_p((addr << 1) | read_write,
321                        SMBHSTADD);
322                 if (read_write == I2C_SMBUS_WRITE)
323                         outb_p(command, SMBHSTCMD);
324                 size = PIIX4_BYTE;
325                 break;
326         case I2C_SMBUS_BYTE_DATA:
327                 outb_p((addr << 1) | read_write,
328                        SMBHSTADD);
329                 outb_p(command, SMBHSTCMD);
330                 if (read_write == I2C_SMBUS_WRITE)
331                         outb_p(data->byte, SMBHSTDAT0);
332                 size = PIIX4_BYTE_DATA;
333                 break;
334         case I2C_SMBUS_WORD_DATA:
335                 outb_p((addr << 1) | read_write,
336                        SMBHSTADD);
337                 outb_p(command, SMBHSTCMD);
338                 if (read_write == I2C_SMBUS_WRITE) {
339                         outb_p(data->word & 0xff, SMBHSTDAT0);
340                         outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
341                 }
342                 size = PIIX4_WORD_DATA;
343                 break;
344         case I2C_SMBUS_BLOCK_DATA:
345                 outb_p((addr << 1) | read_write,
346                        SMBHSTADD);
347                 outb_p(command, SMBHSTCMD);
348                 if (read_write == I2C_SMBUS_WRITE) {
349                         len = data->block[0];
350                         if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
351                                 return -EINVAL;
352                         outb_p(len, SMBHSTDAT0);
353                         i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
354                         for (i = 1; i <= len; i++)
355                                 outb_p(data->block[i], SMBBLKDAT);
356                 }
357                 size = PIIX4_BLOCK_DATA;
358                 break;
359         default:
360                 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
361                 return -EOPNOTSUPP;
362         }
363
364         outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
365
366         status = piix4_transaction();
367         if (status)
368                 return status;
369
370         if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK))
371                 return 0;
372
373
374         switch (size) {
375         case PIIX4_BYTE:
376         case PIIX4_BYTE_DATA:
377                 data->byte = inb_p(SMBHSTDAT0);
378                 break;
379         case PIIX4_WORD_DATA:
380                 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
381                 break;
382         case PIIX4_BLOCK_DATA:
383                 data->block[0] = inb_p(SMBHSTDAT0);
384                 if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
385                         return -EPROTO;
386                 i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
387                 for (i = 1; i <= data->block[0]; i++)
388                         data->block[i] = inb_p(SMBBLKDAT);
389                 break;
390         }
391         return 0;
392 }
393
394 static u32 piix4_func(struct i2c_adapter *adapter)
395 {
396         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
397             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
398             I2C_FUNC_SMBUS_BLOCK_DATA;
399 }
400
401 static const struct i2c_algorithm smbus_algorithm = {
402         .smbus_xfer     = piix4_access,
403         .functionality  = piix4_func,
404 };
405
406 static struct i2c_adapter piix4_adapter = {
407         .owner          = THIS_MODULE,
408         .id             = I2C_HW_SMBUS_PIIX4,
409         .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
410         .algo           = &smbus_algorithm,
411 };
412
413 static struct pci_device_id piix4_ids[] = {
414         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
415         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
416         { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
417         { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS) },
418         { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
419         { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
420         { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
421         { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
422                      PCI_DEVICE_ID_SERVERWORKS_OSB4) },
423         { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
424                      PCI_DEVICE_ID_SERVERWORKS_CSB5) },
425         { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
426                      PCI_DEVICE_ID_SERVERWORKS_CSB6) },
427         { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
428                      PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
429         { 0, }
430 };
431
432 MODULE_DEVICE_TABLE (pci, piix4_ids);
433
434 static int __devinit piix4_probe(struct pci_dev *dev,
435                                 const struct pci_device_id *id)
436 {
437         int retval;
438
439         retval = piix4_setup(dev, id);
440         if (retval)
441                 return retval;
442
443         /* set up the sysfs linkage to our parent device */
444         piix4_adapter.dev.parent = &dev->dev;
445
446         snprintf(piix4_adapter.name, sizeof(piix4_adapter.name),
447                 "SMBus PIIX4 adapter at %04x", piix4_smba);
448
449         if ((retval = i2c_add_adapter(&piix4_adapter))) {
450                 dev_err(&dev->dev, "Couldn't register adapter!\n");
451                 release_region(piix4_smba, SMBIOSIZE);
452                 piix4_smba = 0;
453         }
454
455         return retval;
456 }
457
458 static void __devexit piix4_remove(struct pci_dev *dev)
459 {
460         if (piix4_smba) {
461                 i2c_del_adapter(&piix4_adapter);
462                 release_region(piix4_smba, SMBIOSIZE);
463                 piix4_smba = 0;
464         }
465 }
466
467 static struct pci_driver piix4_driver = {
468         .name           = "piix4_smbus",
469         .id_table       = piix4_ids,
470         .probe          = piix4_probe,
471         .remove         = __devexit_p(piix4_remove),
472 };
473
474 static int __init i2c_piix4_init(void)
475 {
476         return pci_register_driver(&piix4_driver);
477 }
478
479 static void __exit i2c_piix4_exit(void)
480 {
481         pci_unregister_driver(&piix4_driver);
482 }
483
484 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
485                 "Philip Edelbrock <phil@netroedge.com>");
486 MODULE_DESCRIPTION("PIIX4 SMBus driver");
487 MODULE_LICENSE("GPL");
488
489 module_init(i2c_piix4_init);
490 module_exit(i2c_piix4_exit);