0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include <linux/module.h>
0050 #include <linux/pci.h>
0051 #include <linux/kernel.h>
0052 #include <linux/stddef.h>
0053 #include <linux/ioport.h>
0054 #include <linux/delay.h>
0055 #include <linux/i2c.h>
0056 #include <linux/acpi.h>
0057 #include <linux/io.h>
0058
0059
0060 #define SMBHSTSTS (0 + ali15x3_smba)
0061 #define SMBHSTCNT (1 + ali15x3_smba)
0062 #define SMBHSTSTART (2 + ali15x3_smba)
0063 #define SMBHSTCMD (7 + ali15x3_smba)
0064 #define SMBHSTADD (3 + ali15x3_smba)
0065 #define SMBHSTDAT0 (4 + ali15x3_smba)
0066 #define SMBHSTDAT1 (5 + ali15x3_smba)
0067 #define SMBBLKDAT (6 + ali15x3_smba)
0068
0069
0070 #define SMBCOM 0x004
0071 #define SMBBA 0x014
0072 #define SMBATPC 0x05B
0073 #define SMBHSTCFG 0x0E0
0074 #define SMBSLVC 0x0E1
0075 #define SMBCLK 0x0E2
0076 #define SMBREV 0x008
0077
0078
0079 #define MAX_TIMEOUT 200
0080 #define ALI15X3_SMB_IOSIZE 32
0081
0082
0083
0084
0085
0086 #define ALI15X3_SMB_DEFAULTBASE 0xE800
0087
0088
0089 #define ALI15X3_LOCK 0x06
0090
0091
0092 #define ALI15X3_ABORT 0x02
0093 #define ALI15X3_T_OUT 0x04
0094 #define ALI15X3_QUICK 0x00
0095 #define ALI15X3_BYTE 0x10
0096 #define ALI15X3_BYTE_DATA 0x20
0097 #define ALI15X3_WORD_DATA 0x30
0098 #define ALI15X3_BLOCK_DATA 0x40
0099 #define ALI15X3_BLOCK_CLR 0x80
0100
0101
0102 #define ALI15X3_STS_IDLE 0x04
0103 #define ALI15X3_STS_BUSY 0x08
0104 #define ALI15X3_STS_DONE 0x10
0105 #define ALI15X3_STS_DEV 0x20
0106 #define ALI15X3_STS_COLL 0x40
0107 #define ALI15X3_STS_TERM 0x80
0108 #define ALI15X3_STS_ERR 0xE0
0109
0110
0111
0112
0113 static u16 force_addr;
0114 module_param_hw(force_addr, ushort, ioport, 0);
0115 MODULE_PARM_DESC(force_addr,
0116 "Initialize the base address of the i2c controller");
0117
0118 static struct pci_driver ali15x3_driver;
0119 static unsigned short ali15x3_smba;
0120
0121 static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
0122 {
0123 u16 a;
0124 unsigned char temp;
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 pci_read_config_byte(ALI15X3_dev, SMBATPC, &temp);
0138 if (temp & ALI15X3_LOCK) {
0139 temp &= ~ALI15X3_LOCK;
0140 pci_write_config_byte(ALI15X3_dev, SMBATPC, temp);
0141 }
0142
0143
0144 pci_read_config_word(ALI15X3_dev, SMBBA, &ali15x3_smba);
0145 ali15x3_smba &= (0xffff & ~(ALI15X3_SMB_IOSIZE - 1));
0146 if (ali15x3_smba == 0 && force_addr == 0) {
0147 dev_err(&ALI15X3_dev->dev, "ALI15X3_smb region uninitialized "
0148 "- upgrade BIOS or use force_addr=0xaddr\n");
0149 return -ENODEV;
0150 }
0151
0152 if(force_addr)
0153 ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);
0154
0155 if (acpi_check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
0156 ali15x3_driver.name))
0157 return -EBUSY;
0158
0159 if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
0160 ali15x3_driver.name)) {
0161 dev_err(&ALI15X3_dev->dev,
0162 "ALI15X3_smb region 0x%x already in use!\n",
0163 ali15x3_smba);
0164 return -ENODEV;
0165 }
0166
0167 if(force_addr) {
0168 dev_info(&ALI15X3_dev->dev, "forcing ISA address 0x%04X\n",
0169 ali15x3_smba);
0170 if (PCIBIOS_SUCCESSFUL != pci_write_config_word(ALI15X3_dev,
0171 SMBBA,
0172 ali15x3_smba))
0173 goto error;
0174 if (PCIBIOS_SUCCESSFUL != pci_read_config_word(ALI15X3_dev,
0175 SMBBA, &a))
0176 goto error;
0177 if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) {
0178
0179 dev_err(&ALI15X3_dev->dev,
0180 "force address failed - not supported?\n");
0181 goto error;
0182 }
0183 }
0184
0185 pci_read_config_byte(ALI15X3_dev, SMBCOM, &temp);
0186 if ((temp & 1) == 0) {
0187 dev_info(&ALI15X3_dev->dev, "enabling SMBus device\n");
0188 pci_write_config_byte(ALI15X3_dev, SMBCOM, temp | 0x01);
0189 }
0190
0191
0192 pci_read_config_byte(ALI15X3_dev, SMBHSTCFG, &temp);
0193 if ((temp & 1) == 0) {
0194 dev_info(&ALI15X3_dev->dev, "enabling SMBus controller\n");
0195 pci_write_config_byte(ALI15X3_dev, SMBHSTCFG, temp | 0x01);
0196 }
0197
0198
0199 pci_write_config_byte(ALI15X3_dev, SMBCLK, 0x20);
0200
0201
0202
0203
0204
0205
0206
0207
0208 pci_read_config_byte(ALI15X3_dev, SMBREV, &temp);
0209 dev_dbg(&ALI15X3_dev->dev, "SMBREV = 0x%X\n", temp);
0210 dev_dbg(&ALI15X3_dev->dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba);
0211
0212 return 0;
0213 error:
0214 release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
0215 return -ENODEV;
0216 }
0217
0218
0219 static int ali15x3_transaction(struct i2c_adapter *adap)
0220 {
0221 int temp;
0222 int result = 0;
0223 int timeout = 0;
0224
0225 dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, CNT=%02x, CMD=%02x, "
0226 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
0227 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
0228 inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0229
0230
0231 temp = inb_p(SMBHSTSTS);
0232
0233
0234
0235 if (temp & ALI15X3_STS_BUSY) {
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 dev_info(&adap->dev, "Resetting entire SMB Bus to "
0258 "clear busy condition (%02x)\n", temp);
0259 outb_p(ALI15X3_T_OUT, SMBHSTCNT);
0260 temp = inb_p(SMBHSTSTS);
0261 }
0262
0263
0264 if (temp & (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
0265
0266 outb_p(0xFF, SMBHSTSTS);
0267 if ((temp = inb_p(SMBHSTSTS)) &
0268 (ALI15X3_STS_ERR | ALI15X3_STS_BUSY)) {
0269
0270
0271
0272 dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - "
0273 "controller or device on bus is probably hung\n",
0274 temp);
0275 return -EBUSY;
0276 }
0277 } else {
0278
0279 if (temp & ALI15X3_STS_DONE) {
0280 outb_p(temp, SMBHSTSTS);
0281 }
0282 }
0283
0284
0285 outb_p(0xFF, SMBHSTSTART);
0286
0287
0288 timeout = 0;
0289 do {
0290 msleep(1);
0291 temp = inb_p(SMBHSTSTS);
0292 } while ((!(temp & (ALI15X3_STS_ERR | ALI15X3_STS_DONE)))
0293 && (timeout++ < MAX_TIMEOUT));
0294
0295
0296 if (timeout > MAX_TIMEOUT) {
0297 result = -ETIMEDOUT;
0298 dev_err(&adap->dev, "SMBus Timeout!\n");
0299 }
0300
0301 if (temp & ALI15X3_STS_TERM) {
0302 result = -EIO;
0303 dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 if (temp & ALI15X3_STS_COLL) {
0313 result = -ENXIO;
0314 dev_dbg(&adap->dev,
0315 "Error: no response or bus collision ADD=%02x\n",
0316 inb_p(SMBHSTADD));
0317 }
0318
0319
0320 if (temp & ALI15X3_STS_DEV) {
0321 result = -EIO;
0322 dev_err(&adap->dev, "Error: device error\n");
0323 }
0324 dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
0325 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTSTS),
0326 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
0327 inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0328 return result;
0329 }
0330
0331
0332 static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
0333 unsigned short flags, char read_write, u8 command,
0334 int size, union i2c_smbus_data * data)
0335 {
0336 int i, len;
0337 int temp;
0338 int timeout;
0339
0340
0341 outb_p(0xFF, SMBHSTSTS);
0342
0343 temp = inb_p(SMBHSTSTS);
0344 for (timeout = 0;
0345 (timeout < MAX_TIMEOUT) && !(temp & ALI15X3_STS_IDLE);
0346 timeout++) {
0347 msleep(1);
0348 temp = inb_p(SMBHSTSTS);
0349 }
0350 if (timeout >= MAX_TIMEOUT) {
0351 dev_err(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
0352 }
0353
0354 switch (size) {
0355 case I2C_SMBUS_QUICK:
0356 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0357 SMBHSTADD);
0358 size = ALI15X3_QUICK;
0359 break;
0360 case I2C_SMBUS_BYTE:
0361 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0362 SMBHSTADD);
0363 if (read_write == I2C_SMBUS_WRITE)
0364 outb_p(command, SMBHSTCMD);
0365 size = ALI15X3_BYTE;
0366 break;
0367 case I2C_SMBUS_BYTE_DATA:
0368 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0369 SMBHSTADD);
0370 outb_p(command, SMBHSTCMD);
0371 if (read_write == I2C_SMBUS_WRITE)
0372 outb_p(data->byte, SMBHSTDAT0);
0373 size = ALI15X3_BYTE_DATA;
0374 break;
0375 case I2C_SMBUS_WORD_DATA:
0376 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0377 SMBHSTADD);
0378 outb_p(command, SMBHSTCMD);
0379 if (read_write == I2C_SMBUS_WRITE) {
0380 outb_p(data->word & 0xff, SMBHSTDAT0);
0381 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
0382 }
0383 size = ALI15X3_WORD_DATA;
0384 break;
0385 case I2C_SMBUS_BLOCK_DATA:
0386 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0387 SMBHSTADD);
0388 outb_p(command, SMBHSTCMD);
0389 if (read_write == I2C_SMBUS_WRITE) {
0390 len = data->block[0];
0391 if (len < 0) {
0392 len = 0;
0393 data->block[0] = len;
0394 }
0395 if (len > 32) {
0396 len = 32;
0397 data->block[0] = len;
0398 }
0399 outb_p(len, SMBHSTDAT0);
0400
0401 outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
0402 for (i = 1; i <= len; i++)
0403 outb_p(data->block[i], SMBBLKDAT);
0404 }
0405 size = ALI15X3_BLOCK_DATA;
0406 break;
0407 default:
0408 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
0409 return -EOPNOTSUPP;
0410 }
0411
0412 outb_p(size, SMBHSTCNT);
0413
0414 temp = ali15x3_transaction(adap);
0415 if (temp)
0416 return temp;
0417
0418 if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK))
0419 return 0;
0420
0421
0422 switch (size) {
0423 case ALI15X3_BYTE:
0424 data->byte = inb_p(SMBHSTDAT0);
0425 break;
0426 case ALI15X3_BYTE_DATA:
0427 data->byte = inb_p(SMBHSTDAT0);
0428 break;
0429 case ALI15X3_WORD_DATA:
0430 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
0431 break;
0432 case ALI15X3_BLOCK_DATA:
0433 len = inb_p(SMBHSTDAT0);
0434 if (len > 32)
0435 len = 32;
0436 data->block[0] = len;
0437
0438 outb_p(inb_p(SMBHSTCNT) | ALI15X3_BLOCK_CLR, SMBHSTCNT);
0439 for (i = 1; i <= data->block[0]; i++) {
0440 data->block[i] = inb_p(SMBBLKDAT);
0441 dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
0442 len, i, data->block[i]);
0443 }
0444 break;
0445 }
0446 return 0;
0447 }
0448
0449 static u32 ali15x3_func(struct i2c_adapter *adapter)
0450 {
0451 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
0452 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
0453 I2C_FUNC_SMBUS_BLOCK_DATA;
0454 }
0455
0456 static const struct i2c_algorithm smbus_algorithm = {
0457 .smbus_xfer = ali15x3_access,
0458 .functionality = ali15x3_func,
0459 };
0460
0461 static struct i2c_adapter ali15x3_adapter = {
0462 .owner = THIS_MODULE,
0463 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
0464 .algo = &smbus_algorithm,
0465 };
0466
0467 static const struct pci_device_id ali15x3_ids[] = {
0468 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
0469 { 0, }
0470 };
0471
0472 MODULE_DEVICE_TABLE (pci, ali15x3_ids);
0473
0474 static int ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
0475 {
0476 if (ali15x3_setup(dev)) {
0477 dev_err(&dev->dev,
0478 "ALI15X3 not detected, module not inserted.\n");
0479 return -ENODEV;
0480 }
0481
0482
0483 ali15x3_adapter.dev.parent = &dev->dev;
0484
0485 snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name),
0486 "SMBus ALI15X3 adapter at %04x", ali15x3_smba);
0487 return i2c_add_adapter(&ali15x3_adapter);
0488 }
0489
0490 static void ali15x3_remove(struct pci_dev *dev)
0491 {
0492 i2c_del_adapter(&ali15x3_adapter);
0493 release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
0494 }
0495
0496 static struct pci_driver ali15x3_driver = {
0497 .name = "ali15x3_smbus",
0498 .id_table = ali15x3_ids,
0499 .probe = ali15x3_probe,
0500 .remove = ali15x3_remove,
0501 };
0502
0503 module_pci_driver(ali15x3_driver);
0504
0505 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
0506 MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
0507 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
0508 MODULE_DESCRIPTION("ALI15X3 SMBus driver");
0509 MODULE_LICENSE("GPL");