61 #include <linux/module.h>
62 #include <linux/pci.h>
63 #include <linux/kernel.h>
64 #include <linux/stddef.h>
67 #include <linux/i2c.h>
73 #define SMBHSTSTS (0 + ali15x3_smba)
74 #define SMBHSTCNT (1 + ali15x3_smba)
75 #define SMBHSTSTART (2 + ali15x3_smba)
76 #define SMBHSTCMD (7 + ali15x3_smba)
77 #define SMBHSTADD (3 + ali15x3_smba)
78 #define SMBHSTDAT0 (4 + ali15x3_smba)
79 #define SMBHSTDAT1 (5 + ali15x3_smba)
80 #define SMBBLKDAT (6 + ali15x3_smba)
86 #define SMBHSTCFG 0x0E0
92 #define MAX_TIMEOUT 200
93 #define ALI15X3_SMB_IOSIZE 32
99 #define ALI15X3_SMB_DEFAULTBASE 0xE800
102 #define ALI15X3_LOCK 0x06
105 #define ALI15X3_ABORT 0x02
106 #define ALI15X3_T_OUT 0x04
107 #define ALI15X3_QUICK 0x00
108 #define ALI15X3_BYTE 0x10
109 #define ALI15X3_BYTE_DATA 0x20
110 #define ALI15X3_WORD_DATA 0x30
111 #define ALI15X3_BLOCK_DATA 0x40
112 #define ALI15X3_BLOCK_CLR 0x80
115 #define ALI15X3_STS_IDLE 0x04
116 #define ALI15X3_STS_BUSY 0x08
117 #define ALI15X3_STS_DONE 0x10
118 #define ALI15X3_STS_DEV 0x20
119 #define ALI15X3_STS_COLL 0x40
120 #define ALI15X3_STS_TERM 0x80
121 #define ALI15X3_STS_ERR 0xE0
126 static u16 force_addr;
129 "Initialize the base address of the i2c controller");
132 static unsigned short ali15x3_smba;
150 pci_read_config_byte(ALI15X3_dev,
SMBATPC, &temp);
152 temp &= ~ALI15X3_LOCK;
153 pci_write_config_byte(ALI15X3_dev,
SMBATPC, temp);
157 pci_read_config_word(ALI15X3_dev,
SMBBA, &ali15x3_smba);
159 if (ali15x3_smba == 0 && force_addr == 0) {
160 dev_err(&ALI15X3_dev->
dev,
"ALI15X3_smb region uninitialized "
161 "- upgrade BIOS or use force_addr=0xaddr\n");
169 ali15x3_driver.name))
173 ali15x3_driver.name)) {
175 "ALI15X3_smb region 0x%x already in use!\n",
181 dev_info(&ALI15X3_dev->
dev,
"forcing ISA address 0x%04X\n",
193 "force address failed - not supported?\n");
198 pci_read_config_byte(ALI15X3_dev,
SMBCOM, &temp);
199 if ((temp & 1) == 0) {
200 dev_info(&ALI15X3_dev->
dev,
"enabling SMBus device\n");
201 pci_write_config_byte(ALI15X3_dev,
SMBCOM, temp | 0x01);
205 pci_read_config_byte(ALI15X3_dev,
SMBHSTCFG, &temp);
206 if ((temp & 1) == 0) {
207 dev_info(&ALI15X3_dev->
dev,
"enabling SMBus controller\n");
208 pci_write_config_byte(ALI15X3_dev,
SMBHSTCFG, temp | 0x01);
212 pci_write_config_byte(ALI15X3_dev,
SMBCLK, 0x20);
221 pci_read_config_byte(ALI15X3_dev,
SMBREV, &temp);
222 dev_dbg(&ALI15X3_dev->
dev,
"SMBREV = 0x%X\n", temp);
223 dev_dbg(&ALI15X3_dev->
dev,
"iALI15X3_smba = 0x%X\n", ali15x3_smba);
232 static int ali15x3_transaction(
struct i2c_adapter *adap)
238 dev_dbg(&adap->
dev,
"Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, "
270 dev_info(&adap->
dev,
"Resetting entire SMB Bus to "
271 "clear busy condition (%02x)\n", temp);
285 dev_err(&adap->
dev,
"SMBus reset failed! (0x%02x) - "
286 "controller or device on bus is probably hung\n",
316 dev_dbg(&adap->
dev,
"Error: Failed bus transaction\n");
328 "Error: no response or bus collision ADD=%02x\n",
337 dev_dbg(&adap->
dev,
"Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
364 dev_err(&adap->
dev,
"Idle wait Timeout! STS=0x%02x\n", temp);
369 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
374 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
381 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
389 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
399 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
403 len = data->
block[0];
406 data->
block[0] = len;
410 data->
block[0] = len;
415 for (i = 1; i <= len; i++)
421 dev_warn(&adap->
dev,
"Unsupported transaction %d\n", size);
427 temp = ali15x3_transaction(adap);
449 data->
block[0] = len;
452 for (i = 1; i <= data->
block[0]; i++) {
454 dev_dbg(&adap->
dev,
"Blk: len=%d, i=%d, data=%02x\n",
455 len, i, data->
block[i]);
470 .smbus_xfer = ali15x3_access,
471 .functionality = ali15x3_func,
477 .algo = &smbus_algorithm,
489 if (ali15x3_setup(dev)) {
491 "ALI15X3 not detected, module not inserted.\n");
496 ali15x3_adapter.
dev.parent = &dev->
dev;
499 "SMBus ALI15X3 adapter at %04x", ali15x3_smba);
510 .name =
"ali15x3_smbus",
511 .id_table = ali15x3_ids,
512 .probe = ali15x3_probe,