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 #include <linux/module.h>
0042 #include <linux/pci.h>
0043 #include <linux/kernel.h>
0044 #include <linux/stddef.h>
0045 #include <linux/delay.h>
0046 #include <linux/ioport.h>
0047 #include <linux/i2c.h>
0048 #include <linux/acpi.h>
0049 #include <linux/io.h>
0050
0051
0052
0053 #define SMBHSTSTS (0 + ali1535_smba)
0054 #define SMBHSTTYP (1 + ali1535_smba)
0055 #define SMBHSTPORT (2 + ali1535_smba)
0056 #define SMBHSTCMD (7 + ali1535_smba)
0057 #define SMBHSTADD (3 + ali1535_smba)
0058 #define SMBHSTDAT0 (4 + ali1535_smba)
0059 #define SMBHSTDAT1 (5 + ali1535_smba)
0060 #define SMBBLKDAT (6 + ali1535_smba)
0061
0062
0063 #define SMBCOM 0x004
0064 #define SMBREV 0x008
0065 #define SMBCFG 0x0D1
0066 #define SMBBA 0x0E2
0067 #define SMBHSTCFG 0x0F0
0068 #define SMBCLK 0x0F2
0069
0070
0071 #define MAX_TIMEOUT 500
0072 #define ALI1535_SMB_IOSIZE 32
0073
0074 #define ALI1535_SMB_DEFAULTBASE 0x8040
0075
0076
0077 #define ALI1535_LOCK 0x06
0078
0079
0080 #define ALI1535_QUICK 0x00
0081 #define ALI1535_BYTE 0x10
0082 #define ALI1535_BYTE_DATA 0x20
0083 #define ALI1535_WORD_DATA 0x30
0084 #define ALI1535_BLOCK_DATA 0x40
0085 #define ALI1535_I2C_READ 0x60
0086
0087 #define ALI1535_DEV10B_EN 0x80
0088
0089 #define ALI1535_T_OUT 0x08
0090 #define ALI1535_A_HIGH_BIT9 0x08
0091
0092
0093 #define ALI1535_KILL 0x04
0094 #define ALI1535_A_HIGH_BIT8 0x04
0095
0096
0097
0098 #define ALI1535_D_HI_MASK 0x03
0099
0100
0101
0102
0103 #define ALI1535_STS_IDLE 0x04
0104 #define ALI1535_STS_BUSY 0x08
0105 #define ALI1535_STS_DONE 0x10
0106 #define ALI1535_STS_DEV 0x20
0107 #define ALI1535_STS_BUSERR 0x40
0108 #define ALI1535_STS_FAIL 0x80
0109 #define ALI1535_STS_ERR 0xE0
0110
0111 #define ALI1535_BLOCK_CLR 0x04
0112
0113
0114 #define ALI1535_RD_ADDR 0x01
0115
0116
0117
0118 #define ALI1535_SMBIO_EN 0x04
0119
0120 static struct pci_driver ali1535_driver;
0121 static unsigned long ali1535_smba;
0122 static unsigned short ali1535_offset;
0123
0124
0125
0126
0127
0128 static int ali1535_setup(struct pci_dev *dev)
0129 {
0130 int retval;
0131 unsigned char temp;
0132
0133
0134
0135
0136
0137
0138
0139 retval = pci_enable_device(dev);
0140 if (retval) {
0141 dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
0142 goto exit;
0143 }
0144
0145
0146 pci_read_config_word(dev, SMBBA, &ali1535_offset);
0147 dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
0148 ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
0149 if (ali1535_offset == 0) {
0150 dev_warn(&dev->dev,
0151 "ALI1535_smb region uninitialized - upgrade BIOS?\n");
0152 retval = -ENODEV;
0153 goto exit;
0154 }
0155
0156 if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
0157 ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
0158 else
0159 ali1535_smba = ali1535_offset;
0160
0161 retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
0162 ali1535_driver.name);
0163 if (retval)
0164 goto exit;
0165
0166 if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
0167 ali1535_driver.name)) {
0168 dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
0169 ali1535_smba);
0170 retval = -EBUSY;
0171 goto exit;
0172 }
0173
0174
0175 pci_read_config_byte(dev, SMBCFG, &temp);
0176 if ((temp & ALI1535_SMBIO_EN) == 0) {
0177 dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
0178 retval = -ENODEV;
0179 goto exit_free;
0180 }
0181
0182
0183 pci_read_config_byte(dev, SMBHSTCFG, &temp);
0184 if ((temp & 1) == 0) {
0185 dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
0186 retval = -ENODEV;
0187 goto exit_free;
0188 }
0189
0190
0191 pci_write_config_byte(dev, SMBCLK, 0x20);
0192
0193
0194
0195
0196
0197
0198
0199
0200 pci_read_config_byte(dev, SMBREV, &temp);
0201 dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
0202 dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);
0203
0204 return 0;
0205
0206 exit_free:
0207 release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
0208 exit:
0209 return retval;
0210 }
0211
0212 static int ali1535_transaction(struct i2c_adapter *adap)
0213 {
0214 int temp;
0215 int result = 0;
0216 int timeout = 0;
0217
0218 dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
0219 "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
0220 inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
0221 inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0222
0223
0224 temp = inb_p(SMBHSTSTS);
0225
0226
0227
0228 if (temp & ALI1535_STS_BUSY) {
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 dev_info(&adap->dev,
0249 "Resetting entire SMB Bus to clear busy condition (%02x)\n",
0250 temp);
0251 outb_p(ALI1535_T_OUT, SMBHSTTYP);
0252 temp = inb_p(SMBHSTSTS);
0253 }
0254
0255
0256 if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
0257
0258 outb_p(0xFF, SMBHSTSTS);
0259 temp = inb_p(SMBHSTSTS);
0260 if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
0261
0262
0263
0264
0265 dev_err(&adap->dev,
0266 "SMBus reset failed! (0x%02x) - controller or "
0267 "device on bus is probably hung\n", temp);
0268 return -EBUSY;
0269 }
0270 } else {
0271
0272 if (temp & ALI1535_STS_DONE)
0273 outb_p(temp, SMBHSTSTS);
0274 }
0275
0276
0277 outb_p(0xFF, SMBHSTPORT);
0278
0279
0280 timeout = 0;
0281 do {
0282 usleep_range(1000, 2000);
0283 temp = inb_p(SMBHSTSTS);
0284 } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
0285 && (timeout++ < MAX_TIMEOUT));
0286
0287
0288 if (timeout > MAX_TIMEOUT) {
0289 result = -ETIMEDOUT;
0290 dev_err(&adap->dev, "SMBus Timeout!\n");
0291 }
0292
0293 if (temp & ALI1535_STS_FAIL) {
0294 result = -EIO;
0295 dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
0296 }
0297
0298
0299
0300
0301
0302 if (temp & ALI1535_STS_BUSERR) {
0303 result = -ENXIO;
0304 dev_dbg(&adap->dev,
0305 "Error: no response or bus collision ADD=%02x\n",
0306 inb_p(SMBHSTADD));
0307 }
0308
0309
0310 if (temp & ALI1535_STS_DEV) {
0311 result = -EIO;
0312 dev_err(&adap->dev, "Error: device error\n");
0313 }
0314
0315
0316 if (!(temp & ALI1535_STS_DONE)) {
0317 result = -ETIMEDOUT;
0318 dev_err(&adap->dev, "Error: command never completed\n");
0319 }
0320
0321 dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
0322 "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
0323 inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
0324 inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));
0325
0326
0327 if (!(temp & ALI1535_STS_DONE)) {
0328
0329 outb_p(ALI1535_KILL, SMBHSTTYP);
0330 outb_p(0xFF, SMBHSTSTS);
0331 } else if (temp & ALI1535_STS_ERR) {
0332
0333 outb_p(ALI1535_T_OUT, SMBHSTTYP);
0334 outb_p(0xFF, SMBHSTSTS);
0335 }
0336
0337 return result;
0338 }
0339
0340
0341 static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
0342 unsigned short flags, char read_write, u8 command,
0343 int size, union i2c_smbus_data *data)
0344 {
0345 int i, len;
0346 int temp;
0347 int timeout;
0348 s32 result = 0;
0349
0350
0351 temp = inb_p(SMBHSTSTS);
0352 for (timeout = 0;
0353 (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
0354 timeout++) {
0355 usleep_range(1000, 2000);
0356 temp = inb_p(SMBHSTSTS);
0357 }
0358 if (timeout >= MAX_TIMEOUT)
0359 dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);
0360
0361
0362 outb_p(0xFF, SMBHSTSTS);
0363
0364 switch (size) {
0365 case I2C_SMBUS_QUICK:
0366 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0367 SMBHSTADD);
0368 size = ALI1535_QUICK;
0369 outb_p(size, SMBHSTTYP);
0370 break;
0371 case I2C_SMBUS_BYTE:
0372 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0373 SMBHSTADD);
0374 size = ALI1535_BYTE;
0375 outb_p(size, SMBHSTTYP);
0376 if (read_write == I2C_SMBUS_WRITE)
0377 outb_p(command, SMBHSTCMD);
0378 break;
0379 case I2C_SMBUS_BYTE_DATA:
0380 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0381 SMBHSTADD);
0382 size = ALI1535_BYTE_DATA;
0383 outb_p(size, SMBHSTTYP);
0384 outb_p(command, SMBHSTCMD);
0385 if (read_write == I2C_SMBUS_WRITE)
0386 outb_p(data->byte, SMBHSTDAT0);
0387 break;
0388 case I2C_SMBUS_WORD_DATA:
0389 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0390 SMBHSTADD);
0391 size = ALI1535_WORD_DATA;
0392 outb_p(size, SMBHSTTYP);
0393 outb_p(command, SMBHSTCMD);
0394 if (read_write == I2C_SMBUS_WRITE) {
0395 outb_p(data->word & 0xff, SMBHSTDAT0);
0396 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
0397 }
0398 break;
0399 case I2C_SMBUS_BLOCK_DATA:
0400 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
0401 SMBHSTADD);
0402 size = ALI1535_BLOCK_DATA;
0403 outb_p(size, SMBHSTTYP);
0404 outb_p(command, SMBHSTCMD);
0405 if (read_write == I2C_SMBUS_WRITE) {
0406 len = data->block[0];
0407 if (len < 0) {
0408 len = 0;
0409 data->block[0] = len;
0410 }
0411 if (len > 32) {
0412 len = 32;
0413 data->block[0] = len;
0414 }
0415 outb_p(len, SMBHSTDAT0);
0416
0417 outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
0418 for (i = 1; i <= len; i++)
0419 outb_p(data->block[i], SMBBLKDAT);
0420 }
0421 break;
0422 default:
0423 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
0424 result = -EOPNOTSUPP;
0425 goto EXIT;
0426 }
0427
0428 result = ali1535_transaction(adap);
0429 if (result)
0430 goto EXIT;
0431
0432 if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
0433 result = 0;
0434 goto EXIT;
0435 }
0436
0437 switch (size) {
0438 case ALI1535_BYTE:
0439 data->byte = inb_p(SMBHSTDAT0);
0440 break;
0441 case ALI1535_BYTE_DATA:
0442 data->byte = inb_p(SMBHSTDAT0);
0443 break;
0444 case ALI1535_WORD_DATA:
0445 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
0446 break;
0447 case ALI1535_BLOCK_DATA:
0448 len = inb_p(SMBHSTDAT0);
0449 if (len > 32)
0450 len = 32;
0451 data->block[0] = len;
0452
0453 outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
0454 for (i = 1; i <= data->block[0]; i++) {
0455 data->block[i] = inb_p(SMBBLKDAT);
0456 dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n",
0457 len, i, data->block[i]);
0458 }
0459 break;
0460 }
0461 EXIT:
0462 return result;
0463 }
0464
0465
0466 static u32 ali1535_func(struct i2c_adapter *adapter)
0467 {
0468 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
0469 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
0470 I2C_FUNC_SMBUS_BLOCK_DATA;
0471 }
0472
0473 static const struct i2c_algorithm smbus_algorithm = {
0474 .smbus_xfer = ali1535_access,
0475 .functionality = ali1535_func,
0476 };
0477
0478 static struct i2c_adapter ali1535_adapter = {
0479 .owner = THIS_MODULE,
0480 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
0481 .algo = &smbus_algorithm,
0482 };
0483
0484 static const struct pci_device_id ali1535_ids[] = {
0485 { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
0486 { },
0487 };
0488
0489 MODULE_DEVICE_TABLE(pci, ali1535_ids);
0490
0491 static int ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
0492 {
0493 if (ali1535_setup(dev)) {
0494 dev_warn(&dev->dev,
0495 "ALI1535 not detected, module not inserted.\n");
0496 return -ENODEV;
0497 }
0498
0499
0500 ali1535_adapter.dev.parent = &dev->dev;
0501
0502 snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
0503 "SMBus ALI1535 adapter at %04x", ali1535_offset);
0504 return i2c_add_adapter(&ali1535_adapter);
0505 }
0506
0507 static void ali1535_remove(struct pci_dev *dev)
0508 {
0509 i2c_del_adapter(&ali1535_adapter);
0510 release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
0511
0512
0513
0514
0515
0516 }
0517
0518 static struct pci_driver ali1535_driver = {
0519 .name = "ali1535_smbus",
0520 .id_table = ali1535_ids,
0521 .probe = ali1535_probe,
0522 .remove = ali1535_remove,
0523 };
0524
0525 module_pci_driver(ali1535_driver);
0526
0527 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
0528 MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>");
0529 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
0530 MODULE_AUTHOR("Dan Eaton <dan.eaton@rocketlogix.com>");
0531 MODULE_DESCRIPTION("ALI1535 SMBus driver");
0532 MODULE_LICENSE("GPL");