1 /* 2 Copyright (c) 2002,2003 Alexander Malysh <amalysh@web.de> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 /* 20 Changes: 21 24.08.2002 22 Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) 23 Changed sis630_transaction.(Thanks to Mark M. Hoffman) 24 18.09.2002 25 Added SIS730 as supported. 26 21.09.2002 27 Added high_clock module option.If this option is set 28 used Host Master Clock 56KHz (default 14KHz).For now we save old Host 29 Master Clock and after transaction completed restore (otherwise 30 it's confuse BIOS and hung Machine). 31 24.09.2002 32 Fixed typo in sis630_access 33 Fixed logical error by restoring of Host Master Clock 34 31.07.2003 35 Added block data read/write support. 36 */ 37 38 /* 39 Status: beta 40 41 Supports: 42 SIS 630 43 SIS 730 44 45 Note: we assume there can only be one device, with one SMBus interface. 46 */ 47 48 #include <linux/kernel.h> 49 #include <linux/module.h> 50 #include <linux/delay.h> 51 #include <linux/pci.h> 52 #include <linux/ioport.h> 53 #include <linux/init.h> 54 #include <linux/i2c.h> 55 #include <linux/acpi.h> 56 #include <linux/io.h> 57 58 /* SIS630 SMBus registers */ 59 #define SMB_STS 0x80 /* status */ 60 #define SMB_EN 0x81 /* status enable */ 61 #define SMB_CNT 0x82 62 #define SMBHOST_CNT 0x83 63 #define SMB_ADDR 0x84 64 #define SMB_CMD 0x85 65 #define SMB_PCOUNT 0x86 /* processed count */ 66 #define SMB_COUNT 0x87 67 #define SMB_BYTE 0x88 /* ~0x8F data byte field */ 68 #define SMBDEV_ADDR 0x90 69 #define SMB_DB0 0x91 70 #define SMB_DB1 0x92 71 #define SMB_SAA 0x93 72 73 /* register count for request_region */ 74 #define SIS630_SMB_IOREGION 20 75 76 /* PCI address constants */ 77 /* acpi base address register */ 78 #define SIS630_ACPI_BASE_REG 0x74 79 /* bios control register */ 80 #define SIS630_BIOS_CTL_REG 0x40 81 82 /* Other settings */ 83 #define MAX_TIMEOUT 500 84 85 /* SIS630 constants */ 86 #define SIS630_QUICK 0x00 87 #define SIS630_BYTE 0x01 88 #define SIS630_BYTE_DATA 0x02 89 #define SIS630_WORD_DATA 0x03 90 #define SIS630_PCALL 0x04 91 #define SIS630_BLOCK_DATA 0x05 92 93 static struct pci_driver sis630_driver; 94 95 /* insmod parameters */ 96 static bool high_clock; 97 static bool force; 98 module_param(high_clock, bool, 0); 99 MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz)."); 100 module_param(force, bool, 0); 101 MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!"); 102 103 /* acpi base address */ 104 static unsigned short acpi_base; 105 106 /* supported chips */ 107 static int supported[] = { 108 PCI_DEVICE_ID_SI_630, 109 PCI_DEVICE_ID_SI_730, 110 0 /* terminates the list */ 111 }; 112 113 static inline u8 sis630_read(u8 reg) 114 { 115 return inb(acpi_base + reg); 116 } 117 118 static inline void sis630_write(u8 reg, u8 data) 119 { 120 outb(data, acpi_base + reg); 121 } 122 123 static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock) 124 { 125 int temp; 126 127 /* Make sure the SMBus host is ready to start transmitting. */ 128 if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { 129 dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp); 130 /* kill smbus transaction */ 131 sis630_write(SMBHOST_CNT, 0x20); 132 133 if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) { 134 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); 135 return -EBUSY; 136 } else { 137 dev_dbg(&adap->dev, "Successful!\n"); 138 } 139 } 140 141 /* save old clock, so we can prevent machine for hung */ 142 *oldclock = sis630_read(SMB_CNT); 143 144 dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock); 145 146 /* disable timeout interrupt , set Host Master Clock to 56KHz if requested */ 147 if (high_clock) 148 sis630_write(SMB_CNT, 0x20); 149 else 150 sis630_write(SMB_CNT, (*oldclock & ~0x40)); 151 152 /* clear all sticky bits */ 153 temp = sis630_read(SMB_STS); 154 sis630_write(SMB_STS, temp & 0x1e); 155 156 /* start the transaction by setting bit 4 and size */ 157 sis630_write(SMBHOST_CNT,0x10 | (size & 0x07)); 158 159 return 0; 160 } 161 162 static int sis630_transaction_wait(struct i2c_adapter *adap, int size) 163 { 164 int temp, result = 0, timeout = 0; 165 166 /* We will always wait for a fraction of a second! */ 167 do { 168 msleep(1); 169 temp = sis630_read(SMB_STS); 170 /* check if block transmitted */ 171 if (size == SIS630_BLOCK_DATA && (temp & 0x10)) 172 break; 173 } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); 174 175 /* If the SMBus is still busy, we give up */ 176 if (timeout > MAX_TIMEOUT) { 177 dev_dbg(&adap->dev, "SMBus Timeout!\n"); 178 result = -ETIMEDOUT; 179 } 180 181 if (temp & 0x02) { 182 dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); 183 result = -ENXIO; 184 } 185 186 if (temp & 0x04) { 187 dev_err(&adap->dev, "Bus collision!\n"); 188 result = -EIO; 189 /* 190 TBD: Datasheet say: 191 the software should clear this bit and restart SMBUS operation. 192 Should we do it or user start request again? 193 */ 194 } 195 196 return result; 197 } 198 199 static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) 200 { 201 int temp = 0; 202 203 /* clear all status "sticky" bits */ 204 sis630_write(SMB_STS, temp); 205 206 dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); 207 208 /* 209 * restore old Host Master Clock if high_clock is set 210 * and oldclock was not 56KHz 211 */ 212 if (high_clock && !(oldclock & 0x20)) 213 sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20)); 214 215 dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); 216 } 217 218 static int sis630_transaction(struct i2c_adapter *adap, int size) 219 { 220 int result = 0; 221 u8 oldclock = 0; 222 223 result = sis630_transaction_start(adap, size, &oldclock); 224 if (!result) { 225 result = sis630_transaction_wait(adap, size); 226 sis630_transaction_end(adap, oldclock); 227 } 228 229 return result; 230 } 231 232 static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write) 233 { 234 int i, len = 0, rc = 0; 235 u8 oldclock = 0; 236 237 if (read_write == I2C_SMBUS_WRITE) { 238 len = data->block[0]; 239 if (len < 0) 240 len = 0; 241 else if (len > 32) 242 len = 32; 243 sis630_write(SMB_COUNT, len); 244 for (i=1; i <= len; i++) { 245 dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]); 246 /* set data */ 247 sis630_write(SMB_BYTE+(i-1)%8, data->block[i]); 248 if (i==8 || (len<8 && i==len)) { 249 dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); 250 /* first transaction */ 251 rc = sis630_transaction_start(adap, 252 SIS630_BLOCK_DATA, &oldclock); 253 if (rc) 254 return rc; 255 } 256 else if ((i-1)%8 == 7 || i==len) { 257 dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i); 258 if (i>8) { 259 dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i); 260 /* 261 If this is not first transaction, 262 we must clear sticky bit. 263 clear SMBARY_STS 264 */ 265 sis630_write(SMB_STS,0x10); 266 } 267 rc = sis630_transaction_wait(adap, 268 SIS630_BLOCK_DATA); 269 if (rc) { 270 dev_dbg(&adap->dev, "trans_wait failed\n"); 271 break; 272 } 273 } 274 } 275 } 276 else { 277 /* read request */ 278 data->block[0] = len = 0; 279 rc = sis630_transaction_start(adap, 280 SIS630_BLOCK_DATA, &oldclock); 281 if (rc) 282 return rc; 283 do { 284 rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA); 285 if (rc) { 286 dev_dbg(&adap->dev, "trans_wait failed\n"); 287 break; 288 } 289 /* if this first transaction then read byte count */ 290 if (len == 0) 291 data->block[0] = sis630_read(SMB_COUNT); 292 293 /* just to be sure */ 294 if (data->block[0] > 32) 295 data->block[0] = 32; 296 297 dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]); 298 299 for (i=0; i < 8 && len < data->block[0]; i++,len++) { 300 dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len); 301 data->block[len+1] = sis630_read(SMB_BYTE+i); 302 } 303 304 dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i); 305 306 /* clear SMBARY_STS */ 307 sis630_write(SMB_STS,0x10); 308 } while(len < data->block[0]); 309 } 310 311 sis630_transaction_end(adap, oldclock); 312 313 return rc; 314 } 315 316 /* Return negative errno on error. */ 317 static s32 sis630_access(struct i2c_adapter *adap, u16 addr, 318 unsigned short flags, char read_write, 319 u8 command, int size, union i2c_smbus_data *data) 320 { 321 int status; 322 323 switch (size) { 324 case I2C_SMBUS_QUICK: 325 sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); 326 size = SIS630_QUICK; 327 break; 328 case I2C_SMBUS_BYTE: 329 sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); 330 if (read_write == I2C_SMBUS_WRITE) 331 sis630_write(SMB_CMD, command); 332 size = SIS630_BYTE; 333 break; 334 case I2C_SMBUS_BYTE_DATA: 335 sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01)); 336 sis630_write(SMB_CMD, command); 337 if (read_write == I2C_SMBUS_WRITE) 338 sis630_write(SMB_BYTE, data->byte); 339 size = SIS630_BYTE_DATA; 340 break; 341 case I2C_SMBUS_PROC_CALL: 342 case I2C_SMBUS_WORD_DATA: 343 sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01)); 344 sis630_write(SMB_CMD, command); 345 if (read_write == I2C_SMBUS_WRITE) { 346 sis630_write(SMB_BYTE, data->word & 0xff); 347 sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8); 348 } 349 size = (size == I2C_SMBUS_PROC_CALL ? SIS630_PCALL : SIS630_WORD_DATA); 350 break; 351 case I2C_SMBUS_BLOCK_DATA: 352 sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01)); 353 sis630_write(SMB_CMD, command); 354 size = SIS630_BLOCK_DATA; 355 return sis630_block_data(adap, data, read_write); 356 default: 357 dev_warn(&adap->dev, "Unsupported transaction %d\n", 358 size); 359 return -EOPNOTSUPP; 360 } 361 362 status = sis630_transaction(adap, size); 363 if (status) 364 return status; 365 366 if ((size != SIS630_PCALL) && 367 ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { 368 return 0; 369 } 370 371 switch(size) { 372 case SIS630_BYTE: 373 case SIS630_BYTE_DATA: 374 data->byte = sis630_read(SMB_BYTE); 375 break; 376 case SIS630_PCALL: 377 case SIS630_WORD_DATA: 378 data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8); 379 break; 380 } 381 382 return 0; 383 } 384 385 static u32 sis630_func(struct i2c_adapter *adapter) 386 { 387 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | 388 I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL | 389 I2C_FUNC_SMBUS_BLOCK_DATA; 390 } 391 392 static int sis630_setup(struct pci_dev *sis630_dev) 393 { 394 unsigned char b; 395 struct pci_dev *dummy = NULL; 396 int retval, i; 397 398 /* check for supported SiS devices */ 399 for (i=0; supported[i] > 0 ; i++) { 400 if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy))) 401 break; /* found */ 402 } 403 404 if (dummy) { 405 pci_dev_put(dummy); 406 } 407 else if (force) { 408 dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but " 409 "loading because of force option enabled\n"); 410 } 411 else { 412 return -ENODEV; 413 } 414 415 /* 416 Enable ACPI first , so we can accsess reg 74-75 417 in acpi io space and read acpi base addr 418 */ 419 if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { 420 dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); 421 retval = -ENODEV; 422 goto exit; 423 } 424 /* if ACPI already enabled , do nothing */ 425 if (!(b & 0x80) && 426 pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { 427 dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); 428 retval = -ENODEV; 429 goto exit; 430 } 431 432 /* Determine the ACPI base address */ 433 if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { 434 dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); 435 retval = -ENODEV; 436 goto exit; 437 } 438 439 dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base); 440 441 retval = acpi_check_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, 442 sis630_driver.name); 443 if (retval) 444 goto exit; 445 446 /* Everything is happy, let's grab the memory and set things up. */ 447 if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, 448 sis630_driver.name)) { 449 dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already " 450 "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA); 451 retval = -EBUSY; 452 goto exit; 453 } 454 455 retval = 0; 456 457 exit: 458 if (retval) 459 acpi_base = 0; 460 return retval; 461 } 462 463 464 static const struct i2c_algorithm smbus_algorithm = { 465 .smbus_xfer = sis630_access, 466 .functionality = sis630_func, 467 }; 468 469 static struct i2c_adapter sis630_adapter = { 470 .owner = THIS_MODULE, 471 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 472 .algo = &smbus_algorithm, 473 }; 474 475 static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = { 476 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 477 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, 478 { 0, } 479 }; 480 481 MODULE_DEVICE_TABLE (pci, sis630_ids); 482 483 static int sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) 484 { 485 if (sis630_setup(dev)) { 486 dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n"); 487 return -ENODEV; 488 } 489 490 /* set up the sysfs linkage to our parent device */ 491 sis630_adapter.dev.parent = &dev->dev; 492 493 snprintf(sis630_adapter.name, sizeof(sis630_adapter.name), 494 "SMBus SIS630 adapter at %04x", acpi_base + SMB_STS); 495 496 return i2c_add_adapter(&sis630_adapter); 497 } 498 499 static void sis630_remove(struct pci_dev *dev) 500 { 501 if (acpi_base) { 502 i2c_del_adapter(&sis630_adapter); 503 release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION); 504 acpi_base = 0; 505 } 506 } 507 508 509 static struct pci_driver sis630_driver = { 510 .name = "sis630_smbus", 511 .id_table = sis630_ids, 512 .probe = sis630_probe, 513 .remove = sis630_remove, 514 }; 515 516 module_pci_driver(sis630_driver); 517 518 MODULE_LICENSE("GPL"); 519 MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>"); 520 MODULE_DESCRIPTION("SIS630 SMBus driver"); 521