1 /* 2 Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org> 3 4 Shamelessly ripped from i2c-piix4.c: 5 6 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and 7 Philip Edelbrock <phil@netroedge.com> 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 */ 19 20 /* 21 2002-04-08: Added nForce support. (Csaba Halasz) 22 2002-10-03: Fixed nForce PnP I/O port. (Michael Steil) 23 2002-12-28: Rewritten into something that resembles a Linux driver (hch) 24 2003-11-29: Added back AMD8111 removed by the previous rewrite. 25 (Philip Pokorny) 26 */ 27 28 /* 29 Supports AMD756, AMD766, AMD768, AMD8111 and nVidia nForce 30 Note: we assume there can only be one device, with one SMBus interface. 31 */ 32 33 #include <linux/module.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/acpi.h> 41 #include <linux/io.h> 42 43 /* AMD756 SMBus address offsets */ 44 #define SMB_ADDR_OFFSET 0xE0 45 #define SMB_IOSIZE 16 46 #define SMB_GLOBAL_STATUS (0x0 + amd756_ioport) 47 #define SMB_GLOBAL_ENABLE (0x2 + amd756_ioport) 48 #define SMB_HOST_ADDRESS (0x4 + amd756_ioport) 49 #define SMB_HOST_DATA (0x6 + amd756_ioport) 50 #define SMB_HOST_COMMAND (0x8 + amd756_ioport) 51 #define SMB_HOST_BLOCK_DATA (0x9 + amd756_ioport) 52 #define SMB_HAS_DATA (0xA + amd756_ioport) 53 #define SMB_HAS_DEVICE_ADDRESS (0xC + amd756_ioport) 54 #define SMB_HAS_HOST_ADDRESS (0xE + amd756_ioport) 55 #define SMB_SNOOP_ADDRESS (0xF + amd756_ioport) 56 57 /* PCI Address Constants */ 58 59 /* address of I/O space */ 60 #define SMBBA 0x058 /* mh */ 61 #define SMBBANFORCE 0x014 62 63 /* general configuration */ 64 #define SMBGCFG 0x041 /* mh */ 65 66 /* silicon revision code */ 67 #define SMBREV 0x008 68 69 /* Other settings */ 70 #define MAX_TIMEOUT 500 71 72 /* AMD756 constants */ 73 #define AMD756_QUICK 0x00 74 #define AMD756_BYTE 0x01 75 #define AMD756_BYTE_DATA 0x02 76 #define AMD756_WORD_DATA 0x03 77 #define AMD756_PROCESS_CALL 0x04 78 #define AMD756_BLOCK_DATA 0x05 79 80 static struct pci_driver amd756_driver; 81 static unsigned short amd756_ioport; 82 83 /* 84 SMBUS event = I/O 28-29 bit 11 85 see E0 for the status bits and enabled in E2 86 87 */ 88 #define GS_ABRT_STS (1 << 0) 89 #define GS_COL_STS (1 << 1) 90 #define GS_PRERR_STS (1 << 2) 91 #define GS_HST_STS (1 << 3) 92 #define GS_HCYC_STS (1 << 4) 93 #define GS_TO_STS (1 << 5) 94 #define GS_SMB_STS (1 << 11) 95 96 #define GS_CLEAR_STS (GS_ABRT_STS | GS_COL_STS | GS_PRERR_STS | \ 97 GS_HCYC_STS | GS_TO_STS ) 98 99 #define GE_CYC_TYPE_MASK (7) 100 #define GE_HOST_STC (1 << 3) 101 #define GE_ABORT (1 << 5) 102 103 104 static int amd756_transaction(struct i2c_adapter *adap) 105 { 106 int temp; 107 int result = 0; 108 int timeout = 0; 109 110 dev_dbg(&adap->dev, "Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, " 111 "DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS), 112 inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS), 113 inb_p(SMB_HOST_DATA)); 114 115 /* Make sure the SMBus host is ready to start transmitting */ 116 if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) { 117 dev_dbg(&adap->dev, "SMBus busy (%04x). Waiting...\n", temp); 118 do { 119 msleep(1); 120 temp = inw_p(SMB_GLOBAL_STATUS); 121 } while ((temp & (GS_HST_STS | GS_SMB_STS)) && 122 (timeout++ < MAX_TIMEOUT)); 123 /* If the SMBus is still busy, we give up */ 124 if (timeout > MAX_TIMEOUT) { 125 dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp); 126 goto abort; 127 } 128 timeout = 0; 129 } 130 131 /* start the transaction by setting the start bit */ 132 outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC, SMB_GLOBAL_ENABLE); 133 134 /* We will always wait for a fraction of a second! */ 135 do { 136 msleep(1); 137 temp = inw_p(SMB_GLOBAL_STATUS); 138 } while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT)); 139 140 /* If the SMBus is still busy, we give up */ 141 if (timeout > MAX_TIMEOUT) { 142 dev_dbg(&adap->dev, "Completion timeout!\n"); 143 goto abort; 144 } 145 146 if (temp & GS_PRERR_STS) { 147 result = -ENXIO; 148 dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); 149 } 150 151 if (temp & GS_COL_STS) { 152 result = -EIO; 153 dev_warn(&adap->dev, "SMBus collision!\n"); 154 } 155 156 if (temp & GS_TO_STS) { 157 result = -ETIMEDOUT; 158 dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); 159 } 160 161 if (temp & GS_HCYC_STS) 162 dev_dbg(&adap->dev, "SMBus protocol success!\n"); 163 164 outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); 165 166 #ifdef DEBUG 167 if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) { 168 dev_dbg(&adap->dev, 169 "Failed reset at end of transaction (%04x)\n", temp); 170 } 171 #endif 172 173 dev_dbg(&adap->dev, 174 "Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n", 175 inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE), 176 inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA)); 177 178 return result; 179 180 abort: 181 dev_warn(&adap->dev, "Sending abort\n"); 182 outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); 183 msleep(100); 184 outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); 185 return -EIO; 186 } 187 188 /* Return negative errno on error. */ 189 static s32 amd756_access(struct i2c_adapter * adap, u16 addr, 190 unsigned short flags, char read_write, 191 u8 command, int size, union i2c_smbus_data * data) 192 { 193 int i, len; 194 int status; 195 196 switch (size) { 197 case I2C_SMBUS_QUICK: 198 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 199 SMB_HOST_ADDRESS); 200 size = AMD756_QUICK; 201 break; 202 case I2C_SMBUS_BYTE: 203 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 204 SMB_HOST_ADDRESS); 205 if (read_write == I2C_SMBUS_WRITE) 206 outb_p(command, SMB_HOST_DATA); 207 size = AMD756_BYTE; 208 break; 209 case I2C_SMBUS_BYTE_DATA: 210 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 211 SMB_HOST_ADDRESS); 212 outb_p(command, SMB_HOST_COMMAND); 213 if (read_write == I2C_SMBUS_WRITE) 214 outw_p(data->byte, SMB_HOST_DATA); 215 size = AMD756_BYTE_DATA; 216 break; 217 case I2C_SMBUS_WORD_DATA: 218 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 219 SMB_HOST_ADDRESS); 220 outb_p(command, SMB_HOST_COMMAND); 221 if (read_write == I2C_SMBUS_WRITE) 222 outw_p(data->word, SMB_HOST_DATA); /* TODO: endian???? */ 223 size = AMD756_WORD_DATA; 224 break; 225 case I2C_SMBUS_BLOCK_DATA: 226 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 227 SMB_HOST_ADDRESS); 228 outb_p(command, SMB_HOST_COMMAND); 229 if (read_write == I2C_SMBUS_WRITE) { 230 len = data->block[0]; 231 if (len < 0) 232 len = 0; 233 if (len > 32) 234 len = 32; 235 outw_p(len, SMB_HOST_DATA); 236 /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ 237 for (i = 1; i <= len; i++) 238 outb_p(data->block[i], 239 SMB_HOST_BLOCK_DATA); 240 } 241 size = AMD756_BLOCK_DATA; 242 break; 243 default: 244 dev_warn(&adap->dev, "Unsupported transaction %d\n", size); 245 return -EOPNOTSUPP; 246 } 247 248 /* How about enabling interrupts... */ 249 outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); 250 251 status = amd756_transaction(adap); 252 if (status) 253 return status; 254 255 if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) 256 return 0; 257 258 259 switch (size) { 260 case AMD756_BYTE: 261 data->byte = inw_p(SMB_HOST_DATA); 262 break; 263 case AMD756_BYTE_DATA: 264 data->byte = inw_p(SMB_HOST_DATA); 265 break; 266 case AMD756_WORD_DATA: 267 data->word = inw_p(SMB_HOST_DATA); /* TODO: endian???? */ 268 break; 269 case AMD756_BLOCK_DATA: 270 data->block[0] = inw_p(SMB_HOST_DATA) & 0x3f; 271 if(data->block[0] > 32) 272 data->block[0] = 32; 273 /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ 274 for (i = 1; i <= data->block[0]; i++) 275 data->block[i] = inb_p(SMB_HOST_BLOCK_DATA); 276 break; 277 } 278 279 return 0; 280 } 281 282 static u32 amd756_func(struct i2c_adapter *adapter) 283 { 284 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 285 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 286 I2C_FUNC_SMBUS_BLOCK_DATA; 287 } 288 289 static const struct i2c_algorithm smbus_algorithm = { 290 .smbus_xfer = amd756_access, 291 .functionality = amd756_func, 292 }; 293 294 struct i2c_adapter amd756_smbus = { 295 .owner = THIS_MODULE, 296 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 297 .algo = &smbus_algorithm, 298 }; 299 300 enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 }; 301 static const char* chipname[] = { 302 "AMD756", "AMD766", "AMD768", 303 "nVidia nForce", "AMD8111", 304 }; 305 306 static const struct pci_device_id amd756_ids[] = { 307 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B), 308 .driver_data = AMD756 }, 309 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413), 310 .driver_data = AMD766 }, 311 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443), 312 .driver_data = AMD768 }, 313 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS), 314 .driver_data = AMD8111 }, 315 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS), 316 .driver_data = NFORCE }, 317 { 0, } 318 }; 319 320 MODULE_DEVICE_TABLE (pci, amd756_ids); 321 322 static int amd756_probe(struct pci_dev *pdev, const struct pci_device_id *id) 323 { 324 int nforce = (id->driver_data == NFORCE); 325 int error; 326 u8 temp; 327 328 if (amd756_ioport) { 329 dev_err(&pdev->dev, "Only one device supported " 330 "(you have a strange motherboard, btw)\n"); 331 return -ENODEV; 332 } 333 334 if (nforce) { 335 if (PCI_FUNC(pdev->devfn) != 1) 336 return -ENODEV; 337 338 pci_read_config_word(pdev, SMBBANFORCE, &amd756_ioport); 339 amd756_ioport &= 0xfffc; 340 } else { /* amd */ 341 if (PCI_FUNC(pdev->devfn) != 3) 342 return -ENODEV; 343 344 pci_read_config_byte(pdev, SMBGCFG, &temp); 345 if ((temp & 128) == 0) { 346 dev_err(&pdev->dev, 347 "Error: SMBus controller I/O not enabled!\n"); 348 return -ENODEV; 349 } 350 351 /* Determine the address of the SMBus areas */ 352 /* Technically it is a dword but... */ 353 pci_read_config_word(pdev, SMBBA, &amd756_ioport); 354 amd756_ioport &= 0xff00; 355 amd756_ioport += SMB_ADDR_OFFSET; 356 } 357 358 error = acpi_check_region(amd756_ioport, SMB_IOSIZE, 359 amd756_driver.name); 360 if (error) 361 return -ENODEV; 362 363 if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { 364 dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", 365 amd756_ioport); 366 return -ENODEV; 367 } 368 369 pci_read_config_byte(pdev, SMBREV, &temp); 370 dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp); 371 dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport); 372 373 /* set up the sysfs linkage to our parent device */ 374 amd756_smbus.dev.parent = &pdev->dev; 375 376 snprintf(amd756_smbus.name, sizeof(amd756_smbus.name), 377 "SMBus %s adapter at %04x", chipname[id->driver_data], 378 amd756_ioport); 379 380 error = i2c_add_adapter(&amd756_smbus); 381 if (error) 382 goto out_err; 383 384 return 0; 385 386 out_err: 387 release_region(amd756_ioport, SMB_IOSIZE); 388 return error; 389 } 390 391 static void amd756_remove(struct pci_dev *dev) 392 { 393 i2c_del_adapter(&amd756_smbus); 394 release_region(amd756_ioport, SMB_IOSIZE); 395 } 396 397 static struct pci_driver amd756_driver = { 398 .name = "amd756_smbus", 399 .id_table = amd756_ids, 400 .probe = amd756_probe, 401 .remove = amd756_remove, 402 }; 403 404 module_pci_driver(amd756_driver); 405 406 MODULE_AUTHOR("Merlin Hughes <merlin@merlin.org>"); 407 MODULE_DESCRIPTION("AMD756/766/768/8111 and nVidia nForce SMBus driver"); 408 MODULE_LICENSE("GPL"); 409 410 EXPORT_SYMBOL(amd756_smbus); 411