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 15/* 16 Status: beta 17 18 Supports: 19 SIS 630 20 SIS 730 21 SIS 964 22 23 Notable differences between chips: 24 +------------------------+--------------------+-------------------+ 25 | | SIS630/730 | SIS964 | 26 +------------------------+--------------------+-------------------+ 27 | Clock | 14kHz/56kHz | 55.56kHz/27.78kHz | 28 | SMBus registers offset | 0x80 | 0xE0 | 29 | SMB_CNT | Bit 1 = Slave Busy | Bit 1 = Bus probe | 30 | (not used yet) | Bit 3 is reserved | Bit 3 = Last byte | 31 | SMB_PCOUNT | Offset + 0x06 | Offset + 0x14 | 32 | SMB_COUNT | 4:0 bits | 5:0 bits | 33 +------------------------+--------------------+-------------------+ 34 (Other differences don't affect the functions provided by the driver) 35 36 Note: we assume there can only be one device, with one SMBus interface. 37*/ 38 39#include <linux/kernel.h> 40#include <linux/module.h> 41#include <linux/delay.h> 42#include <linux/pci.h> 43#include <linux/ioport.h> 44#include <linux/i2c.h> 45#include <linux/acpi.h> 46#include <linux/io.h> 47 48/* SIS964 id is defined here as we are the only file using it */ 49#define PCI_DEVICE_ID_SI_964 0x0964 50 51/* SIS630/730/964 SMBus registers */ 52#define SMB_STS 0x00 /* status */ 53#define SMB_CNT 0x02 /* control */ 54#define SMBHOST_CNT 0x03 /* host control */ 55#define SMB_ADDR 0x04 /* address */ 56#define SMB_CMD 0x05 /* command */ 57#define SMB_COUNT 0x07 /* byte count */ 58#define SMB_BYTE 0x08 /* ~0x8F data byte field */ 59 60/* SMB_STS register */ 61#define BYTE_DONE_STS 0x10 /* Byte Done Status / Block Array */ 62#define SMBCOL_STS 0x04 /* Collision */ 63#define SMBERR_STS 0x02 /* Device error */ 64 65/* SMB_CNT register */ 66#define MSTO_EN 0x40 /* Host Master Timeout Enable */ 67#define SMBCLK_SEL 0x20 /* Host master clock selection */ 68#define SMB_PROBE 0x02 /* Bus Probe/Slave busy */ 69#define SMB_HOSTBUSY 0x01 /* Host Busy */ 70 71/* SMBHOST_CNT register */ 72#define SMB_KILL 0x20 /* Kill */ 73#define SMB_START 0x10 /* Start */ 74 75/* register count for request_region 76 * As we don't use SMB_PCOUNT, 20 is ok for SiS630 and SiS964 77 */ 78#define SIS630_SMB_IOREGION 20 79 80/* PCI address constants */ 81/* acpi base address register */ 82#define SIS630_ACPI_BASE_REG 0x74 83/* bios control register */ 84#define SIS630_BIOS_CTL_REG 0x40 85 86/* Other settings */ 87#define MAX_TIMEOUT 500 88 89/* SIS630 constants */ 90#define SIS630_QUICK 0x00 91#define SIS630_BYTE 0x01 92#define SIS630_BYTE_DATA 0x02 93#define SIS630_WORD_DATA 0x03 94#define SIS630_PCALL 0x04 95#define SIS630_BLOCK_DATA 0x05 96 97static struct pci_driver sis630_driver; 98 99/* insmod parameters */ 100static bool high_clock; 101static bool force; 102module_param(high_clock, bool, 0); 103MODULE_PARM_DESC(high_clock, 104 "Set Host Master Clock to 56KHz (default 14KHz) (SIS630/730 only)."); 105module_param(force, bool, 0); 106MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!"); 107 108/* SMBus base adress */ 109static unsigned short smbus_base; 110 111/* supported chips */ 112static int supported[] = { 113 PCI_DEVICE_ID_SI_630, 114 PCI_DEVICE_ID_SI_730, 115 PCI_DEVICE_ID_SI_760, 116 0 /* terminates the list */ 117}; 118 119static inline u8 sis630_read(u8 reg) 120{ 121 return inb(smbus_base + reg); 122} 123 124static inline void sis630_write(u8 reg, u8 data) 125{ 126 outb(data, smbus_base + reg); 127} 128 129static int sis630_transaction_start(struct i2c_adapter *adap, int size, 130 u8 *oldclock) 131{ 132 int temp; 133 134 /* Make sure the SMBus host is ready to start transmitting. */ 135 temp = sis630_read(SMB_CNT); 136 if ((temp & (SMB_PROBE | SMB_HOSTBUSY)) != 0x00) { 137 dev_dbg(&adap->dev, "SMBus busy (%02x). Resetting...\n", temp); 138 /* kill smbus transaction */ 139 sis630_write(SMBHOST_CNT, SMB_KILL); 140 141 temp = sis630_read(SMB_CNT); 142 if (temp & (SMB_PROBE | SMB_HOSTBUSY)) { 143 dev_dbg(&adap->dev, "Failed! (%02x)\n", temp); 144 return -EBUSY; 145 } else { 146 dev_dbg(&adap->dev, "Successful!\n"); 147 } 148 } 149 150 /* save old clock, so we can prevent machine for hung */ 151 *oldclock = sis630_read(SMB_CNT); 152 153 dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock); 154 155 /* disable timeout interrupt, 156 * set Host Master Clock to 56KHz if requested */ 157 if (high_clock) 158 sis630_write(SMB_CNT, SMBCLK_SEL); 159 else 160 sis630_write(SMB_CNT, (*oldclock & ~MSTO_EN)); 161 162 /* clear all sticky bits */ 163 temp = sis630_read(SMB_STS); 164 sis630_write(SMB_STS, temp & 0x1e); 165 166 /* start the transaction by setting bit 4 and size */ 167 sis630_write(SMBHOST_CNT, SMB_START | (size & 0x07)); 168 169 return 0; 170} 171 172static int sis630_transaction_wait(struct i2c_adapter *adap, int size) 173{ 174 int temp, result = 0, timeout = 0; 175 176 /* We will always wait for a fraction of a second! */ 177 do { 178 msleep(1); 179 temp = sis630_read(SMB_STS); 180 /* check if block transmitted */ 181 if (size == SIS630_BLOCK_DATA && (temp & BYTE_DONE_STS)) 182 break; 183 } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT)); 184 185 /* If the SMBus is still busy, we give up */ 186 if (timeout > MAX_TIMEOUT) { 187 dev_dbg(&adap->dev, "SMBus Timeout!\n"); 188 result = -ETIMEDOUT; 189 } 190 191 if (temp & SMBERR_STS) { 192 dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); 193 result = -ENXIO; 194 } 195 196 if (temp & SMBCOL_STS) { 197 dev_err(&adap->dev, "Bus collision!\n"); 198 result = -EAGAIN; 199 } 200 201 return result; 202} 203 204static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock) 205{ 206 /* clear all status "sticky" bits */ 207 sis630_write(SMB_STS, 0xFF); 208 209 dev_dbg(&adap->dev, 210 "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT)); 211 212 /* 213 * restore old Host Master Clock if high_clock is set 214 * and oldclock was not 56KHz 215 */ 216 if (high_clock && !(oldclock & SMBCLK_SEL)) 217 sis630_write(SMB_CNT, sis630_read(SMB_CNT) & ~SMBCLK_SEL); 218 219 dev_dbg(&adap->dev, 220 "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT)); 221} 222 223static int sis630_transaction(struct i2c_adapter *adap, int size) 224{ 225 int result = 0; 226 u8 oldclock = 0; 227 228 result = sis630_transaction_start(adap, size, &oldclock); 229 if (!result) { 230 result = sis630_transaction_wait(adap, size); 231 sis630_transaction_end(adap, oldclock); 232 } 233 234 return result; 235} 236 237static int sis630_block_data(struct i2c_adapter *adap, 238 union i2c_smbus_data *data, int read_write) 239{ 240 int i, len = 0, rc = 0; 241 u8 oldclock = 0; 242 243 if (read_write == I2C_SMBUS_WRITE) { 244 len = data->block[0]; 245 if (len < 0) 246 len = 0; 247 else if (len > 32) 248 len = 32; 249 sis630_write(SMB_COUNT, len); 250 for (i = 1; i <= len; i++) { 251 dev_dbg(&adap->dev, 252 "set data 0x%02x\n", data->block[i]); 253 /* set data */ 254 sis630_write(SMB_BYTE + (i - 1) % 8, data->block[i]); 255 if (i == 8 || (len < 8 && i == len)) { 256 dev_dbg(&adap->dev, 257 "start trans len=%d i=%d\n", len, i); 258 /* first transaction */ 259 rc = sis630_transaction_start(adap, 260 SIS630_BLOCK_DATA, &oldclock); 261 if (rc) 262 return rc; 263 } else if ((i - 1) % 8 == 7 || i == len) { 264 dev_dbg(&adap->dev, 265 "trans_wait len=%d i=%d\n", len, i); 266 if (i > 8) { 267 dev_dbg(&adap->dev, 268 "clear smbary_sts" 269 " len=%d i=%d\n", len, i); 270 /* 271 If this is not first transaction, 272 we must clear sticky bit. 273 clear SMBARY_STS 274 */ 275 sis630_write(SMB_STS, BYTE_DONE_STS); 276 } 277 rc = sis630_transaction_wait(adap, 278 SIS630_BLOCK_DATA); 279 if (rc) { 280 dev_dbg(&adap->dev, 281 "trans_wait failed\n"); 282 break; 283 } 284 } 285 } 286 } else { 287 /* read request */ 288 data->block[0] = len = 0; 289 rc = sis630_transaction_start(adap, 290 SIS630_BLOCK_DATA, &oldclock); 291 if (rc) 292 return rc; 293 do { 294 rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA); 295 if (rc) { 296 dev_dbg(&adap->dev, "trans_wait failed\n"); 297 break; 298 } 299 /* if this first transaction then read byte count */ 300 if (len == 0) 301 data->block[0] = sis630_read(SMB_COUNT); 302 303 /* just to be sure */ 304 if (data->block[0] > 32) 305 data->block[0] = 32; 306 307 dev_dbg(&adap->dev, 308 "block data read len=0x%x\n", data->block[0]); 309 310 for (i = 0; i < 8 && len < data->block[0]; i++, len++) { 311 dev_dbg(&adap->dev, 312 "read i=%d len=%d\n", i, len); 313 data->block[len + 1] = sis630_read(SMB_BYTE + 314 i); 315 } 316 317 dev_dbg(&adap->dev, 318 "clear smbary_sts len=%d i=%d\n", len, i); 319 320 /* clear SMBARY_STS */ 321 sis630_write(SMB_STS, BYTE_DONE_STS); 322 } while (len < data->block[0]); 323 } 324 325 sis630_transaction_end(adap, oldclock); 326 327 return rc; 328} 329 330/* Return negative errno on error. */ 331static s32 sis630_access(struct i2c_adapter *adap, u16 addr, 332 unsigned short flags, char read_write, 333 u8 command, int size, union i2c_smbus_data *data) 334{ 335 int status; 336 337 switch (size) { 338 case I2C_SMBUS_QUICK: 339 sis630_write(SMB_ADDR, 340 ((addr & 0x7f) << 1) | (read_write & 0x01)); 341 size = SIS630_QUICK; 342 break; 343 case I2C_SMBUS_BYTE: 344 sis630_write(SMB_ADDR, 345 ((addr & 0x7f) << 1) | (read_write & 0x01)); 346 if (read_write == I2C_SMBUS_WRITE) 347 sis630_write(SMB_CMD, command); 348 size = SIS630_BYTE; 349 break; 350 case I2C_SMBUS_BYTE_DATA: 351 sis630_write(SMB_ADDR, 352 ((addr & 0x7f) << 1) | (read_write & 0x01)); 353 sis630_write(SMB_CMD, command); 354 if (read_write == I2C_SMBUS_WRITE) 355 sis630_write(SMB_BYTE, data->byte); 356 size = SIS630_BYTE_DATA; 357 break; 358 case I2C_SMBUS_PROC_CALL: 359 case I2C_SMBUS_WORD_DATA: 360 sis630_write(SMB_ADDR, 361 ((addr & 0x7f) << 1) | (read_write & 0x01)); 362 sis630_write(SMB_CMD, command); 363 if (read_write == I2C_SMBUS_WRITE) { 364 sis630_write(SMB_BYTE, data->word & 0xff); 365 sis630_write(SMB_BYTE + 1, (data->word & 0xff00) >> 8); 366 } 367 size = (size == I2C_SMBUS_PROC_CALL ? 368 SIS630_PCALL : SIS630_WORD_DATA); 369 break; 370 case I2C_SMBUS_BLOCK_DATA: 371 sis630_write(SMB_ADDR, 372 ((addr & 0x7f) << 1) | (read_write & 0x01)); 373 sis630_write(SMB_CMD, command); 374 size = SIS630_BLOCK_DATA; 375 return sis630_block_data(adap, data, read_write); 376 default: 377 dev_warn(&adap->dev, "Unsupported transaction %d\n", size); 378 return -EOPNOTSUPP; 379 } 380 381 status = sis630_transaction(adap, size); 382 if (status) 383 return status; 384 385 if ((size != SIS630_PCALL) && 386 ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) { 387 return 0; 388 } 389 390 switch (size) { 391 case SIS630_BYTE: 392 case SIS630_BYTE_DATA: 393 data->byte = sis630_read(SMB_BYTE); 394 break; 395 case SIS630_PCALL: 396 case SIS630_WORD_DATA: 397 data->word = sis630_read(SMB_BYTE) + 398 (sis630_read(SMB_BYTE + 1) << 8); 399 break; 400 } 401 402 return 0; 403} 404 405static u32 sis630_func(struct i2c_adapter *adapter) 406{ 407 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 408 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 409 I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA; 410} 411 412static int sis630_setup(struct pci_dev *sis630_dev) 413{ 414 unsigned char b; 415 struct pci_dev *dummy = NULL; 416 int retval, i; 417 /* acpi base address */ 418 unsigned short acpi_base; 419 420 /* check for supported SiS devices */ 421 for (i = 0; supported[i] > 0; i++) { 422 dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy); 423 if (dummy) 424 break; /* found */ 425 } 426 427 if (dummy) { 428 pci_dev_put(dummy); 429 } else if (force) { 430 dev_err(&sis630_dev->dev, 431 "WARNING: Can't detect SIS630 compatible device, but " 432 "loading because of force option enabled\n"); 433 } else { 434 return -ENODEV; 435 } 436 437 /* 438 Enable ACPI first , so we can accsess reg 74-75 439 in acpi io space and read acpi base addr 440 */ 441 if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, &b)) { 442 dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); 443 retval = -ENODEV; 444 goto exit; 445 } 446 /* if ACPI already enabled , do nothing */ 447 if (!(b & 0x80) && 448 pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { 449 dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); 450 retval = -ENODEV; 451 goto exit; 452 } 453 454 /* Determine the ACPI base address */ 455 if (pci_read_config_word(sis630_dev, 456 SIS630_ACPI_BASE_REG, &acpi_base)) { 457 dev_err(&sis630_dev->dev, 458 "Error: Can't determine ACPI base address\n"); 459 retval = -ENODEV; 460 goto exit; 461 } 462 463 dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04hx\n", acpi_base); 464 465 if (supported[i] == PCI_DEVICE_ID_SI_760) 466 smbus_base = acpi_base + 0xE0; 467 else 468 smbus_base = acpi_base + 0x80; 469 470 dev_dbg(&sis630_dev->dev, "SMBus base at 0x%04hx\n", smbus_base); 471 472 retval = acpi_check_region(smbus_base + SMB_STS, SIS630_SMB_IOREGION, 473 sis630_driver.name); 474 if (retval) 475 goto exit; 476 477 /* Everything is happy, let's grab the memory and set things up. */ 478 if (!request_region(smbus_base + SMB_STS, SIS630_SMB_IOREGION, 479 sis630_driver.name)) { 480 dev_err(&sis630_dev->dev, 481 "I/O Region 0x%04hx-0x%04hx for SMBus already in use.\n", 482 smbus_base + SMB_STS, 483 smbus_base + SMB_STS + SIS630_SMB_IOREGION - 1); 484 retval = -EBUSY; 485 goto exit; 486 } 487 488 retval = 0; 489 490exit: 491 if (retval) 492 smbus_base = 0; 493 return retval; 494} 495 496 497static const struct i2c_algorithm smbus_algorithm = { 498 .smbus_xfer = sis630_access, 499 .functionality = sis630_func, 500}; 501 502static struct i2c_adapter sis630_adapter = { 503 .owner = THIS_MODULE, 504 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 505 .algo = &smbus_algorithm, 506 .retries = 3 507}; 508 509static const struct pci_device_id sis630_ids[] = { 510 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 511 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, 512 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_964) }, 513 { 0, } 514}; 515 516MODULE_DEVICE_TABLE(pci, sis630_ids); 517 518static int sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) 519{ 520 if (sis630_setup(dev)) { 521 dev_err(&dev->dev, 522 "SIS630 compatible bus not detected, " 523 "module not inserted.\n"); 524 return -ENODEV; 525 } 526 527 /* set up the sysfs linkage to our parent device */ 528 sis630_adapter.dev.parent = &dev->dev; 529 530 snprintf(sis630_adapter.name, sizeof(sis630_adapter.name), 531 "SMBus SIS630 adapter at %04hx", smbus_base + SMB_STS); 532 533 return i2c_add_adapter(&sis630_adapter); 534} 535 536static void sis630_remove(struct pci_dev *dev) 537{ 538 if (smbus_base) { 539 i2c_del_adapter(&sis630_adapter); 540 release_region(smbus_base + SMB_STS, SIS630_SMB_IOREGION); 541 smbus_base = 0; 542 } 543} 544 545 546static struct pci_driver sis630_driver = { 547 .name = "sis630_smbus", 548 .id_table = sis630_ids, 549 .probe = sis630_probe, 550 .remove = sis630_remove, 551}; 552 553module_pci_driver(sis630_driver); 554 555MODULE_LICENSE("GPL"); 556MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>"); 557MODULE_DESCRIPTION("SIS630 SMBus driver"); 558