linux/drivers/i2c/busses/i2c-nforce2.c
<<
>>
Prefs
   1/*
   2    SMBus driver for nVidia nForce2 MCP
   3
   4    Added nForce3 Pro 150  Thomas Leibold <thomas@plx.com>,
   5        Ported to 2.5 Patrick Dreker <patrick@dreker.de>,
   6    Copyright (c) 2003  Hans-Frieder Vogt <hfvogt@arcor.de>,
   7    Based on
   8    SMBus 2.0 driver for AMD-8111 IO-Hub
   9    Copyright (c) 2002 Vojtech Pavlik
  10
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 2 of the License, or
  14    (at your option) any later version.
  15
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20*/
  21
  22/*
  23    SUPPORTED DEVICES           PCI ID
  24    nForce2 MCP                 0064
  25    nForce2 Ultra 400 MCP       0084
  26    nForce3 Pro150 MCP          00D4
  27    nForce3 250Gb MCP           00E4
  28    nForce4 MCP                 0052
  29    nForce4 MCP-04              0034
  30    nForce MCP51                0264
  31    nForce MCP55                0368
  32    nForce MCP61                03EB
  33    nForce MCP65                0446
  34    nForce MCP67                0542
  35    nForce MCP73                07D8
  36    nForce MCP78S               0752
  37    nForce MCP79                0AA2
  38
  39    This driver supports the 2 SMBuses that are included in the MCP of the
  40    nForce2/3/4/5xx chipsets.
  41*/
  42
  43/* Note: we assume there can only be one nForce2, with two SMBus interfaces */
  44
  45#include <linux/module.h>
  46#include <linux/pci.h>
  47#include <linux/kernel.h>
  48#include <linux/stddef.h>
  49#include <linux/ioport.h>
  50#include <linux/i2c.h>
  51#include <linux/delay.h>
  52#include <linux/dmi.h>
  53#include <linux/acpi.h>
  54#include <linux/slab.h>
  55#include <linux/io.h>
  56
  57MODULE_LICENSE("GPL");
  58MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
  59MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
  60
  61
  62struct nforce2_smbus {
  63        struct i2c_adapter adapter;
  64        int base;
  65        int size;
  66        int blockops;
  67        int can_abort;
  68};
  69
  70
  71/*
  72 * nVidia nForce2 SMBus control register definitions
  73 * (Newer incarnations use standard BARs 4 and 5 instead)
  74 */
  75#define NFORCE_PCI_SMB1 0x50
  76#define NFORCE_PCI_SMB2 0x54
  77
  78
  79/*
  80 * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
  81 */
  82#define NVIDIA_SMB_PRTCL        (smbus->base + 0x00)    /* protocol, PEC */
  83#define NVIDIA_SMB_STS          (smbus->base + 0x01)    /* status */
  84#define NVIDIA_SMB_ADDR         (smbus->base + 0x02)    /* address */
  85#define NVIDIA_SMB_CMD          (smbus->base + 0x03)    /* command */
  86#define NVIDIA_SMB_DATA         (smbus->base + 0x04)    /* 32 data registers */
  87#define NVIDIA_SMB_BCNT         (smbus->base + 0x24)    /* number of data
  88                                                           bytes */
  89#define NVIDIA_SMB_STATUS_ABRT  (smbus->base + 0x3c)    /* register used to
  90                                                           check the status of
  91                                                           the abort command */
  92#define NVIDIA_SMB_CTRL         (smbus->base + 0x3e)    /* control register */
  93
  94#define NVIDIA_SMB_STATUS_ABRT_STS      0x01            /* Bit to notify that
  95                                                           abort succeeded */
  96#define NVIDIA_SMB_CTRL_ABORT   0x20
  97#define NVIDIA_SMB_STS_DONE     0x80
  98#define NVIDIA_SMB_STS_ALRM     0x40
  99#define NVIDIA_SMB_STS_RES      0x20
 100#define NVIDIA_SMB_STS_STATUS   0x1f
 101
 102#define NVIDIA_SMB_PRTCL_WRITE                  0x00
 103#define NVIDIA_SMB_PRTCL_READ                   0x01
 104#define NVIDIA_SMB_PRTCL_QUICK                  0x02
 105#define NVIDIA_SMB_PRTCL_BYTE                   0x04
 106#define NVIDIA_SMB_PRTCL_BYTE_DATA              0x06
 107#define NVIDIA_SMB_PRTCL_WORD_DATA              0x08
 108#define NVIDIA_SMB_PRTCL_BLOCK_DATA             0x0a
 109#define NVIDIA_SMB_PRTCL_PEC                    0x80
 110
 111/* Misc definitions */
 112#define MAX_TIMEOUT     100
 113
 114/* We disable the second SMBus channel on these boards */
 115static const struct dmi_system_id nforce2_dmi_blacklist2[] = {
 116        {
 117                .ident = "DFI Lanparty NF4 Expert",
 118                .matches = {
 119                        DMI_MATCH(DMI_BOARD_VENDOR, "DFI Corp,LTD"),
 120                        DMI_MATCH(DMI_BOARD_NAME, "LP UT NF4 Expert"),
 121                },
 122        },
 123        { }
 124};
 125
 126static struct pci_driver nforce2_driver;
 127
 128/* For multiplexing support, we need a global reference to the 1st
 129   SMBus channel */
 130#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE
 131struct i2c_adapter *nforce2_smbus;
 132EXPORT_SYMBOL_GPL(nforce2_smbus);
 133
 134static void nforce2_set_reference(struct i2c_adapter *adap)
 135{
 136        nforce2_smbus = adap;
 137}
 138#else
 139static inline void nforce2_set_reference(struct i2c_adapter *adap) { }
 140#endif
 141
 142static void nforce2_abort(struct i2c_adapter *adap)
 143{
 144        struct nforce2_smbus *smbus = adap->algo_data;
 145        int timeout = 0;
 146        unsigned char temp;
 147
 148        dev_dbg(&adap->dev, "Aborting current transaction\n");
 149
 150        outb_p(NVIDIA_SMB_CTRL_ABORT, NVIDIA_SMB_CTRL);
 151        do {
 152                msleep(1);
 153                temp = inb_p(NVIDIA_SMB_STATUS_ABRT);
 154        } while (!(temp & NVIDIA_SMB_STATUS_ABRT_STS) &&
 155                        (timeout++ < MAX_TIMEOUT));
 156        if (!(temp & NVIDIA_SMB_STATUS_ABRT_STS))
 157                dev_err(&adap->dev, "Can't reset the smbus\n");
 158        outb_p(NVIDIA_SMB_STATUS_ABRT_STS, NVIDIA_SMB_STATUS_ABRT);
 159}
 160
 161static int nforce2_check_status(struct i2c_adapter *adap)
 162{
 163        struct nforce2_smbus *smbus = adap->algo_data;
 164        int timeout = 0;
 165        unsigned char temp;
 166
 167        do {
 168                msleep(1);
 169                temp = inb_p(NVIDIA_SMB_STS);
 170        } while ((!temp) && (timeout++ < MAX_TIMEOUT));
 171
 172        if (timeout > MAX_TIMEOUT) {
 173                dev_dbg(&adap->dev, "SMBus Timeout!\n");
 174                if (smbus->can_abort)
 175                        nforce2_abort(adap);
 176                return -ETIMEDOUT;
 177        }
 178        if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
 179                dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp);
 180                return -EIO;
 181        }
 182        return 0;
 183}
 184
 185/* Return negative errno on error */
 186static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
 187                unsigned short flags, char read_write,
 188                u8 command, int size, union i2c_smbus_data *data)
 189{
 190        struct nforce2_smbus *smbus = adap->algo_data;
 191        unsigned char protocol, pec;
 192        u8 len;
 193        int i, status;
 194
 195        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
 196                NVIDIA_SMB_PRTCL_WRITE;
 197        pec = (flags & I2C_CLIENT_PEC) ? NVIDIA_SMB_PRTCL_PEC : 0;
 198
 199        switch (size) {
 200        case I2C_SMBUS_QUICK:
 201                protocol |= NVIDIA_SMB_PRTCL_QUICK;
 202                read_write = I2C_SMBUS_WRITE;
 203                break;
 204
 205        case I2C_SMBUS_BYTE:
 206                if (read_write == I2C_SMBUS_WRITE)
 207                        outb_p(command, NVIDIA_SMB_CMD);
 208                protocol |= NVIDIA_SMB_PRTCL_BYTE;
 209                break;
 210
 211        case I2C_SMBUS_BYTE_DATA:
 212                outb_p(command, NVIDIA_SMB_CMD);
 213                if (read_write == I2C_SMBUS_WRITE)
 214                        outb_p(data->byte, NVIDIA_SMB_DATA);
 215                protocol |= NVIDIA_SMB_PRTCL_BYTE_DATA;
 216                break;
 217
 218        case I2C_SMBUS_WORD_DATA:
 219                outb_p(command, NVIDIA_SMB_CMD);
 220                if (read_write == I2C_SMBUS_WRITE) {
 221                        outb_p(data->word, NVIDIA_SMB_DATA);
 222                        outb_p(data->word >> 8, NVIDIA_SMB_DATA + 1);
 223                }
 224                protocol |= NVIDIA_SMB_PRTCL_WORD_DATA | pec;
 225                break;
 226
 227        case I2C_SMBUS_BLOCK_DATA:
 228                outb_p(command, NVIDIA_SMB_CMD);
 229                if (read_write == I2C_SMBUS_WRITE) {
 230                        len = data->block[0];
 231                        if ((len == 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
 232                                dev_err(&adap->dev,
 233                                        "Transaction failed (requested block size: %d)\n",
 234                                        len);
 235                                return -EINVAL;
 236                        }
 237                        outb_p(len, NVIDIA_SMB_BCNT);
 238                        for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
 239                                outb_p(data->block[i + 1],
 240                                       NVIDIA_SMB_DATA + i);
 241                }
 242                protocol |= NVIDIA_SMB_PRTCL_BLOCK_DATA | pec;
 243                break;
 244
 245        default:
 246                dev_err(&adap->dev, "Unsupported transaction %d\n", size);
 247                return -EOPNOTSUPP;
 248        }
 249
 250        outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
 251        outb_p(protocol, NVIDIA_SMB_PRTCL);
 252
 253        status = nforce2_check_status(adap);
 254        if (status)
 255                return status;
 256
 257        if (read_write == I2C_SMBUS_WRITE)
 258                return 0;
 259
 260        switch (size) {
 261        case I2C_SMBUS_BYTE:
 262        case I2C_SMBUS_BYTE_DATA:
 263                data->byte = inb_p(NVIDIA_SMB_DATA);
 264                break;
 265
 266        case I2C_SMBUS_WORD_DATA:
 267                data->word = inb_p(NVIDIA_SMB_DATA) |
 268                             (inb_p(NVIDIA_SMB_DATA + 1) << 8);
 269                break;
 270
 271        case I2C_SMBUS_BLOCK_DATA:
 272                len = inb_p(NVIDIA_SMB_BCNT);
 273                if ((len <= 0) || (len > I2C_SMBUS_BLOCK_MAX)) {
 274                        dev_err(&adap->dev,
 275                                "Transaction failed (received block size: 0x%02x)\n",
 276                                len);
 277                        return -EPROTO;
 278                }
 279                for (i = 0; i < len; i++)
 280                        data->block[i + 1] = inb_p(NVIDIA_SMB_DATA + i);
 281                data->block[0] = len;
 282                break;
 283        }
 284
 285        return 0;
 286}
 287
 288
 289static u32 nforce2_func(struct i2c_adapter *adapter)
 290{
 291        /* other functionality might be possible, but is not tested */
 292        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 293               I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
 294               I2C_FUNC_SMBUS_PEC |
 295               (((struct nforce2_smbus *)adapter->algo_data)->blockops ?
 296                I2C_FUNC_SMBUS_BLOCK_DATA : 0);
 297}
 298
 299static struct i2c_algorithm smbus_algorithm = {
 300        .smbus_xfer     = nforce2_access,
 301        .functionality  = nforce2_func,
 302};
 303
 304
 305static const struct pci_device_id nforce2_ids[] = {
 306        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
 307        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
 308        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
 309        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
 310        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
 311        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
 312        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) },
 313        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
 314        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
 315        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
 316        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
 317        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
 318        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) },
 319        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
 320        { 0 }
 321};
 322
 323MODULE_DEVICE_TABLE(pci, nforce2_ids);
 324
 325
 326static int nforce2_probe_smb(struct pci_dev *dev, int bar, int alt_reg,
 327                             struct nforce2_smbus *smbus, const char *name)
 328{
 329        int error;
 330
 331        smbus->base = pci_resource_start(dev, bar);
 332        if (smbus->base) {
 333                smbus->size = pci_resource_len(dev, bar);
 334        } else {
 335                /* Older incarnations of the device used non-standard BARs */
 336                u16 iobase;
 337
 338                if (pci_read_config_word(dev, alt_reg, &iobase)
 339                    != PCIBIOS_SUCCESSFUL) {
 340                        dev_err(&dev->dev, "Error reading PCI config for %s\n",
 341                                name);
 342                        return -EIO;
 343                }
 344
 345                smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
 346                smbus->size = 64;
 347        }
 348
 349        error = acpi_check_region(smbus->base, smbus->size,
 350                                  nforce2_driver.name);
 351        if (error)
 352                return error;
 353
 354        if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
 355                dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
 356                        smbus->base, smbus->base+smbus->size-1, name);
 357                return -EBUSY;
 358        }
 359        smbus->adapter.owner = THIS_MODULE;
 360        smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 361        smbus->adapter.algo = &smbus_algorithm;
 362        smbus->adapter.algo_data = smbus;
 363        smbus->adapter.dev.parent = &dev->dev;
 364        snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
 365                "SMBus nForce2 adapter at %04x", smbus->base);
 366
 367        error = i2c_add_adapter(&smbus->adapter);
 368        if (error) {
 369                dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
 370                release_region(smbus->base, smbus->size);
 371                return error;
 372        }
 373        dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n",
 374                smbus->base);
 375        return 0;
 376}
 377
 378
 379static int nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id)
 380{
 381        struct nforce2_smbus *smbuses;
 382        int res1, res2;
 383
 384        /* we support 2 SMBus adapters */
 385        smbuses = kzalloc(2 * sizeof(struct nforce2_smbus), GFP_KERNEL);
 386        if (!smbuses)
 387                return -ENOMEM;
 388        pci_set_drvdata(dev, smbuses);
 389
 390        switch (dev->device) {
 391        case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS:
 392        case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
 393        case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
 394                smbuses[0].blockops = 1;
 395                smbuses[1].blockops = 1;
 396                smbuses[0].can_abort = 1;
 397                smbuses[1].can_abort = 1;
 398        }
 399
 400        /* SMBus adapter 1 */
 401        res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
 402        if (res1 < 0)
 403                smbuses[0].base = 0;    /* to have a check value */
 404
 405        /* SMBus adapter 2 */
 406        if (dmi_check_system(nforce2_dmi_blacklist2)) {
 407                dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n");
 408                res2 = -EPERM;
 409                smbuses[1].base = 0;
 410        } else {
 411                res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1],
 412                                         "SMB2");
 413                if (res2 < 0)
 414                        smbuses[1].base = 0;    /* to have a check value */
 415        }
 416
 417        if ((res1 < 0) && (res2 < 0)) {
 418                /* we did not find even one of the SMBuses, so we give up */
 419                kfree(smbuses);
 420                return -ENODEV;
 421        }
 422
 423        nforce2_set_reference(&smbuses[0].adapter);
 424        return 0;
 425}
 426
 427
 428static void nforce2_remove(struct pci_dev *dev)
 429{
 430        struct nforce2_smbus *smbuses = pci_get_drvdata(dev);
 431
 432        nforce2_set_reference(NULL);
 433        if (smbuses[0].base) {
 434                i2c_del_adapter(&smbuses[0].adapter);
 435                release_region(smbuses[0].base, smbuses[0].size);
 436        }
 437        if (smbuses[1].base) {
 438                i2c_del_adapter(&smbuses[1].adapter);
 439                release_region(smbuses[1].base, smbuses[1].size);
 440        }
 441        kfree(smbuses);
 442}
 443
 444static struct pci_driver nforce2_driver = {
 445        .name           = "nForce2_smbus",
 446        .id_table       = nforce2_ids,
 447        .probe          = nforce2_probe,
 448        .remove         = nforce2_remove,
 449};
 450
 451module_pci_driver(nforce2_driver);
 452