This source file includes following definitions.
- sis5595_read
- sis5595_write
- sis5595_setup
- sis5595_transaction
- sis5595_access
- sis5595_func
- sis5595_probe
- i2c_sis5595_init
- i2c_sis5595_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 #include <linux/kernel.h>
  45 #include <linux/module.h>
  46 #include <linux/delay.h>
  47 #include <linux/pci.h>
  48 #include <linux/ioport.h>
  49 #include <linux/init.h>
  50 #include <linux/i2c.h>
  51 #include <linux/acpi.h>
  52 #include <linux/io.h>
  53 
  54 static int blacklist[] = {
  55         PCI_DEVICE_ID_SI_540,
  56         PCI_DEVICE_ID_SI_550,
  57         PCI_DEVICE_ID_SI_630,
  58         PCI_DEVICE_ID_SI_645,
  59         PCI_DEVICE_ID_SI_646,
  60         PCI_DEVICE_ID_SI_648,
  61         PCI_DEVICE_ID_SI_650,
  62         PCI_DEVICE_ID_SI_651,
  63         PCI_DEVICE_ID_SI_730,
  64         PCI_DEVICE_ID_SI_735,
  65         PCI_DEVICE_ID_SI_745,
  66         PCI_DEVICE_ID_SI_746,
  67         PCI_DEVICE_ID_SI_5511,  
  68 
  69 
  70         PCI_DEVICE_ID_SI_5597,
  71         PCI_DEVICE_ID_SI_5598,
  72         0,                      
  73 };
  74 
  75 
  76 #define SIS5595_EXTENT          8
  77 
  78 #define SMB_STS_LO              0x00
  79 #define SMB_STS_HI              0x01
  80 #define SMB_CTL_LO              0x02
  81 #define SMB_CTL_HI              0x03
  82 #define SMB_ADDR                0x04
  83 #define SMB_CMD                 0x05
  84 #define SMB_PCNT                0x06
  85 #define SMB_CNT                 0x07
  86 #define SMB_BYTE                0x08
  87 #define SMB_DEV                 0x10
  88 #define SMB_DB0                 0x11
  89 #define SMB_DB1                 0x12
  90 #define SMB_HAA                 0x13
  91 
  92 
  93 #define SMB_INDEX               0x38
  94 #define SMB_DAT                 0x39
  95 #define SIS5595_ENABLE_REG      0x40
  96 #define ACPI_BASE               0x90
  97 
  98 
  99 #define MAX_TIMEOUT             500
 100 
 101 
 102 #define SIS5595_QUICK           0x00
 103 #define SIS5595_BYTE            0x02
 104 #define SIS5595_BYTE_DATA       0x04
 105 #define SIS5595_WORD_DATA       0x06
 106 #define SIS5595_PROC_CALL       0x08
 107 #define SIS5595_BLOCK_DATA      0x0A
 108 
 109 
 110 
 111 
 112 
 113 static u16 force_addr;
 114 module_param_hw(force_addr, ushort, ioport, 0);
 115 MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
 116 
 117 static struct pci_driver sis5595_driver;
 118 static unsigned short sis5595_base;
 119 static struct pci_dev *sis5595_pdev;
 120 
 121 static u8 sis5595_read(u8 reg)
 122 {
 123         outb(reg, sis5595_base + SMB_INDEX);
 124         return inb(sis5595_base + SMB_DAT);
 125 }
 126 
 127 static void sis5595_write(u8 reg, u8 data)
 128 {
 129         outb(reg, sis5595_base + SMB_INDEX);
 130         outb(data, sis5595_base + SMB_DAT);
 131 }
 132 
 133 static int sis5595_setup(struct pci_dev *SIS5595_dev)
 134 {
 135         u16 a;
 136         u8 val;
 137         int *i;
 138         int retval;
 139 
 140         
 141         for (i = blacklist; *i != 0; i++) {
 142                 struct pci_dev *dev;
 143                 dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
 144                 if (dev) {
 145                         dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
 146                         pci_dev_put(dev);
 147                         return -ENODEV;
 148                 }
 149         }
 150 
 151         
 152         pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
 153         if (sis5595_base == 0 && force_addr == 0) {
 154                 dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
 155                 return -ENODEV;
 156         }
 157 
 158         if (force_addr)
 159                 sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
 160         dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
 161 
 162         
 163 
 164         retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
 165                                    sis5595_driver.name);
 166         if (retval)
 167                 return retval;
 168 
 169         if (!request_region(sis5595_base + SMB_INDEX, 2,
 170                             sis5595_driver.name)) {
 171                 dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
 172                         sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
 173                 return -ENODEV;
 174         }
 175 
 176         if (force_addr) {
 177                 dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
 178                 if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base)
 179                     != PCIBIOS_SUCCESSFUL)
 180                         goto error;
 181                 if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a)
 182                     != PCIBIOS_SUCCESSFUL)
 183                         goto error;
 184                 if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
 185                         
 186                         dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
 187                         goto error;
 188                 }
 189         }
 190 
 191         if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
 192             != PCIBIOS_SUCCESSFUL)
 193                 goto error;
 194         if ((val & 0x80) == 0) {
 195                 dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
 196                 if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80)
 197                     != PCIBIOS_SUCCESSFUL)
 198                         goto error;
 199                 if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val)
 200                     != PCIBIOS_SUCCESSFUL)
 201                         goto error;
 202                 if ((val & 0x80) == 0) {
 203                         
 204                         dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
 205                         goto error;
 206                 }
 207         }
 208 
 209         
 210         return 0;
 211 
 212 error:
 213         release_region(sis5595_base + SMB_INDEX, 2);
 214         return -ENODEV;
 215 }
 216 
 217 static int sis5595_transaction(struct i2c_adapter *adap)
 218 {
 219         int temp;
 220         int result = 0;
 221         int timeout = 0;
 222 
 223         
 224         temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
 225         if (temp != 0x00) {
 226                 dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
 227                 sis5595_write(SMB_STS_LO, temp & 0xff);
 228                 sis5595_write(SMB_STS_HI, temp >> 8);
 229                 if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
 230                         dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
 231                         return -EBUSY;
 232                 } else {
 233                         dev_dbg(&adap->dev, "Successful!\n");
 234                 }
 235         }
 236 
 237         
 238         sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
 239 
 240         
 241         do {
 242                 msleep(1);
 243                 temp = sis5595_read(SMB_STS_LO);
 244         } while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
 245 
 246         
 247         if (timeout > MAX_TIMEOUT) {
 248                 dev_dbg(&adap->dev, "SMBus Timeout!\n");
 249                 result = -ETIMEDOUT;
 250         }
 251 
 252         if (temp & 0x10) {
 253                 dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
 254                 result = -ENXIO;
 255         }
 256 
 257         if (temp & 0x20) {
 258                 dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
 259                         "next hard reset (or not...)\n");
 260                 
 261                 result = -EIO;
 262         }
 263 
 264         temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
 265         if (temp != 0x00) {
 266                 sis5595_write(SMB_STS_LO, temp & 0xff);
 267                 sis5595_write(SMB_STS_HI, temp >> 8);
 268         }
 269 
 270         temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
 271         if (temp != 0x00)
 272                 dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
 273 
 274         return result;
 275 }
 276 
 277 
 278 static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
 279                           unsigned short flags, char read_write,
 280                           u8 command, int size, union i2c_smbus_data *data)
 281 {
 282         int status;
 283 
 284         switch (size) {
 285         case I2C_SMBUS_QUICK:
 286                 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
 287                 size = SIS5595_QUICK;
 288                 break;
 289         case I2C_SMBUS_BYTE:
 290                 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
 291                 if (read_write == I2C_SMBUS_WRITE)
 292                         sis5595_write(SMB_CMD, command);
 293                 size = SIS5595_BYTE;
 294                 break;
 295         case I2C_SMBUS_BYTE_DATA:
 296                 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
 297                 sis5595_write(SMB_CMD, command);
 298                 if (read_write == I2C_SMBUS_WRITE)
 299                         sis5595_write(SMB_BYTE, data->byte);
 300                 size = SIS5595_BYTE_DATA;
 301                 break;
 302         case I2C_SMBUS_PROC_CALL:
 303         case I2C_SMBUS_WORD_DATA:
 304                 sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
 305                 sis5595_write(SMB_CMD, command);
 306                 if (read_write == I2C_SMBUS_WRITE) {
 307                         sis5595_write(SMB_BYTE, data->word & 0xff);
 308                         sis5595_write(SMB_BYTE + 1,
 309                                       (data->word & 0xff00) >> 8);
 310                 }
 311                 size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
 312                 break;
 313         default:
 314                 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
 315                 return -EOPNOTSUPP;
 316         }
 317 
 318         sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
 319 
 320         status = sis5595_transaction(adap);
 321         if (status)
 322                 return status;
 323 
 324         if ((size != SIS5595_PROC_CALL) &&
 325             ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
 326                 return 0;
 327 
 328 
 329         switch (size) {
 330         case SIS5595_BYTE:
 331         case SIS5595_BYTE_DATA:
 332                 data->byte = sis5595_read(SMB_BYTE);
 333                 break;
 334         case SIS5595_WORD_DATA:
 335         case SIS5595_PROC_CALL:
 336                 data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
 337                 break;
 338         }
 339         return 0;
 340 }
 341 
 342 static u32 sis5595_func(struct i2c_adapter *adapter)
 343 {
 344         return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 345             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
 346             I2C_FUNC_SMBUS_PROC_CALL;
 347 }
 348 
 349 static const struct i2c_algorithm smbus_algorithm = {
 350         .smbus_xfer     = sis5595_access,
 351         .functionality  = sis5595_func,
 352 };
 353 
 354 static struct i2c_adapter sis5595_adapter = {
 355         .owner          = THIS_MODULE,
 356         .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
 357         .algo           = &smbus_algorithm,
 358 };
 359 
 360 static const struct pci_device_id sis5595_ids[] = {
 361         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 
 362         { 0, }
 363 };
 364 
 365 MODULE_DEVICE_TABLE (pci, sis5595_ids);
 366 
 367 static int sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
 368 {
 369         int err;
 370 
 371         if (sis5595_setup(dev)) {
 372                 dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
 373                 return -ENODEV;
 374         }
 375 
 376         
 377         sis5595_adapter.dev.parent = &dev->dev;
 378 
 379         snprintf(sis5595_adapter.name, sizeof(sis5595_adapter.name),
 380                  "SMBus SIS5595 adapter at %04x", sis5595_base + SMB_INDEX);
 381         err = i2c_add_adapter(&sis5595_adapter);
 382         if (err) {
 383                 release_region(sis5595_base + SMB_INDEX, 2);
 384                 return err;
 385         }
 386 
 387         
 388 
 389 
 390 
 391         sis5595_pdev =  pci_dev_get(dev);
 392         return -ENODEV;
 393 }
 394 
 395 static struct pci_driver sis5595_driver = {
 396         .name           = "sis5595_smbus",
 397         .id_table       = sis5595_ids,
 398         .probe          = sis5595_probe,
 399 };
 400 
 401 static int __init i2c_sis5595_init(void)
 402 {
 403         return pci_register_driver(&sis5595_driver);
 404 }
 405 
 406 static void __exit i2c_sis5595_exit(void)
 407 {
 408         pci_unregister_driver(&sis5595_driver);
 409         if (sis5595_pdev) {
 410                 i2c_del_adapter(&sis5595_adapter);
 411                 release_region(sis5595_base + SMB_INDEX, 2);
 412                 pci_dev_put(sis5595_pdev);
 413                 sis5595_pdev = NULL;
 414         }
 415 }
 416 
 417 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
 418 MODULE_DESCRIPTION("SIS5595 SMBus driver");
 419 MODULE_LICENSE("GPL");
 420 
 421 module_init(i2c_sis5595_init);
 422 module_exit(i2c_sis5595_exit);