32 #include <linux/module.h>
34 #include <linux/pci.h>
35 #include <linux/kernel.h>
37 #include <linux/stddef.h>
39 #include <linux/i2c.h>
40 #include <linux/slab.h>
48 #define SMBHSTSTS (0 + piix4_smba)
49 #define SMBHSLVSTS (1 + piix4_smba)
50 #define SMBHSTCNT (2 + piix4_smba)
51 #define SMBHSTCMD (3 + piix4_smba)
52 #define SMBHSTADD (4 + piix4_smba)
53 #define SMBHSTDAT0 (5 + piix4_smba)
54 #define SMBHSTDAT1 (6 + piix4_smba)
55 #define SMBBLKDAT (7 + piix4_smba)
56 #define SMBSLVCNT (8 + piix4_smba)
57 #define SMBSHDWCMD (9 + piix4_smba)
58 #define SMBSLVEVT (0xA + piix4_smba)
59 #define SMBSLVDAT (0xC + piix4_smba)
66 #define SMBHSTCFG 0x0D2
68 #define SMBSHDW1 0x0D4
69 #define SMBSHDW2 0x0D5
73 #define MAX_TIMEOUT 500
77 #define PIIX4_QUICK 0x00
78 #define PIIX4_BYTE 0x04
79 #define PIIX4_BYTE_DATA 0x08
80 #define PIIX4_WORD_DATA 0x0C
81 #define PIIX4_BLOCK_DATA 0x14
93 static int force_addr;
96 "Forcibly enable the PIIX4 at the given address. "
97 "EXTREMELY DANGEROUS!");
99 static int srvrworks_csb5_delay;
104 .ident =
"Sapphire AM2RD790",
111 .ident =
"DFI Lanparty UT 790FX",
138 unsigned short piix4_smba;
142 srvrworks_csb5_delay = 1;
148 "Accessing the SMBus on this system is unsafe!\n");
155 dev_err(&PIIX4_dev->
dev,
"IBM system detected; this module "
156 "may corrupt your serial eeprom! Refusing to load "
163 piix4_smba = force_addr & 0xfff0;
166 pci_read_config_word(PIIX4_dev,
SMBBA, &piix4_smba);
167 piix4_smba &= 0xfff0;
168 if(piix4_smba == 0) {
169 dev_err(&PIIX4_dev->
dev,
"SMBus base address "
170 "uninitialized - upgrade BIOS or use "
171 "force_addr=0xaddr\n");
180 dev_err(&PIIX4_dev->
dev,
"SMBus region 0x%x already in use!\n",
185 pci_read_config_byte(PIIX4_dev,
SMBHSTCFG, &temp);
190 pci_write_config_byte(PIIX4_dev,
SMBHSTCFG, temp & 0xfe);
191 pci_write_config_word(PIIX4_dev,
SMBBA, piix4_smba);
192 pci_write_config_byte(PIIX4_dev,
SMBHSTCFG, temp | 0x01);
193 dev_info(&PIIX4_dev->
dev,
"WARNING: SMBus interface set to "
194 "new address %04x!\n", piix4_smba);
195 }
else if ((temp & 1) == 0) {
205 pci_write_config_byte(PIIX4_dev,
SMBHSTCFG,
208 "WARNING: SMBus interface has been "
209 "FORCEFULLY ENABLED!\n");
212 "Host SMBus controller not enabled!\n");
218 if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
219 dev_dbg(&PIIX4_dev->
dev,
"Using Interrupt 9 for SMBus.\n");
220 else if ((temp & 0x0E) == 0)
221 dev_dbg(&PIIX4_dev->
dev,
"Using Interrupt SMI# for SMBus.\n");
223 dev_err(&PIIX4_dev->
dev,
"Illegal Interrupt configuration "
224 "(or code out of date)!\n");
226 pci_read_config_byte(PIIX4_dev,
SMBREV, &temp);
228 "SMBus Host Controller at 0x%x, revision %d\n",
237 unsigned short piix4_smba;
238 unsigned short smba_idx = 0xcd6;
239 u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
242 if (
force || force_addr) {
243 dev_err(&PIIX4_dev->
dev,
"SMBus does not support "
244 "forcing address!\n");
250 dev_err(&PIIX4_dev->
dev,
"SMBus base address index region "
251 "0x%x already in use!\n", smba_idx);
255 smba_en_lo =
inb_p(smba_idx + 1);
256 outb_p(smb_en + 1, smba_idx);
257 smba_en_hi =
inb_p(smba_idx + 1);
260 if ((smba_en_lo & 1) == 0) {
262 "Host SMBus controller not enabled!\n");
266 piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
271 dev_err(&PIIX4_dev->
dev,
"SMBus region 0x%x already in use!\n",
278 dev_err(&PIIX4_dev->
dev,
"SMBus I2C bus config region "
279 "0x%x already in use!\n", piix4_smba + i2ccfg_offset);
283 i2ccfg =
inb_p(piix4_smba + i2ccfg_offset);
287 dev_dbg(&PIIX4_dev->
dev,
"Using IRQ for SMBus.\n");
289 dev_dbg(&PIIX4_dev->
dev,
"Using SMI# for SMBus.\n");
292 "SMBus Host Controller at 0x%x, revision %d\n",
293 piix4_smba, i2ccfg >> 4);
300 unsigned short base_reg_addr)
305 unsigned short piix4_smba;
308 pci_read_config_word(PIIX4_dev, base_reg_addr, &piix4_smba);
309 if ((piix4_smba & 1) == 0) {
311 "Auxiliary SMBus controller not enabled\n");
315 piix4_smba &= 0xfff0;
316 if (piix4_smba == 0) {
318 "Auxiliary SMBus base address uninitialized\n");
326 dev_err(&PIIX4_dev->
dev,
"Auxiliary SMBus region 0x%x "
327 "already in use!\n", piix4_smba);
332 "Auxiliary SMBus Host Controller at 0x%x\n",
338 static int piix4_transaction(
struct i2c_adapter *piix4_adapter)
341 unsigned short piix4_smba = adapdata->
smba;
346 dev_dbg(&piix4_adapter->
dev,
"Transaction (pre): CNT=%02x, CMD=%02x, "
353 dev_dbg(&piix4_adapter->
dev,
"SMBus busy (%02x). "
354 "Resetting...\n", temp);
357 dev_err(&piix4_adapter->
dev,
"Failed! (%02x)\n", temp);
360 dev_dbg(&piix4_adapter->
dev,
"Successful!\n");
368 if (srvrworks_csb5_delay)
379 dev_err(&piix4_adapter->
dev,
"SMBus Timeout!\n");
385 dev_err(&piix4_adapter->
dev,
"Error: Failed bus transaction\n");
390 dev_dbg(&piix4_adapter->
dev,
"Bus collision! SMBus may be "
391 "locked until next hard reset. (sorry!)\n");
397 dev_dbg(&piix4_adapter->
dev,
"Error: no response!\n");
404 dev_err(&piix4_adapter->
dev,
"Failed reset at end of "
405 "transaction (%02x)\n", temp);
407 dev_dbg(&piix4_adapter->
dev,
"Transaction (post): CNT=%02x, CMD=%02x, "
416 unsigned short flags,
char read_write,
420 unsigned short piix4_smba = adapdata->
smba;
426 outb_p((addr << 1) | read_write,
431 outb_p((addr << 1) | read_write,
438 outb_p((addr << 1) | read_write,
446 outb_p((addr << 1) | read_write,
456 outb_p((addr << 1) | read_write,
460 len = data->
block[0];
465 for (i = 1; i <= len; i++)
471 dev_warn(&adap->
dev,
"Unsupported transaction %d\n", size);
477 status = piix4_transaction(adap);
498 for (i = 1; i <= data->
block[0]; i++)
513 .smbus_xfer = piix4_access,
514 .functionality = piix4_func,
560 adap->
algo = &smbus_algorithm;
562 adapdata = kzalloc(
sizeof(*adapdata),
GFP_KERNEL);
563 if (adapdata ==
NULL) {
572 adap->
dev.parent = &dev->
dev;
575 "SMBus PIIX4 adapter at %04x", smba);
577 i2c_set_adapdata(adap, adapdata);
581 dev_err(&dev->
dev,
"Couldn't register adapter!\n");
602 retval = piix4_setup_sb800(dev,
id);
604 retval = piix4_setup(dev,
id);
611 retval = piix4_add_adapter(dev, retval, &piix4_main_adapter);
619 retval = piix4_setup_aux(dev,
id, 0x58);
623 piix4_add_adapter(dev, retval, &piix4_aux_adapter);
634 if (adapdata->
smba) {
644 if (piix4_main_adapter) {
645 piix4_adap_remove(piix4_main_adapter);
646 piix4_main_adapter =
NULL;
649 if (piix4_aux_adapter) {
650 piix4_adap_remove(piix4_aux_adapter);
651 piix4_aux_adapter =
NULL;
656 .name =
"piix4_smbus",
657 .id_table = piix4_ids,
658 .probe = piix4_probe,