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