linux/drivers/i2c/busses/i2c-amd8111.c
<<
>>
Prefs
   1/*
   2 * SMBus 2.0 driver for AMD-8111 IO-Hub.
   3 *
   4 * Copyright (c) 2002 Vojtech Pavlik
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation version 2.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/pci.h>
  13#include <linux/kernel.h>
  14#include <linux/stddef.h>
  15#include <linux/ioport.h>
  16#include <linux/i2c.h>
  17#include <linux/delay.h>
  18#include <linux/acpi.h>
  19#include <linux/slab.h>
  20#include <linux/io.h>
  21
  22MODULE_LICENSE("GPL");
  23MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
  24MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver");
  25
  26struct amd_smbus {
  27        struct pci_dev *dev;
  28        struct i2c_adapter adapter;
  29        int base;
  30        int size;
  31};
  32
  33static struct pci_driver amd8111_driver;
  34
  35/*
  36 * AMD PCI control registers definitions.
  37 */
  38
  39#define AMD_PCI_MISC    0x48
  40
  41#define AMD_PCI_MISC_SCI        0x04    /* deliver SCI */
  42#define AMD_PCI_MISC_INT        0x02    /* deliver PCI IRQ */
  43#define AMD_PCI_MISC_SPEEDUP    0x01    /* 16x clock speedup */
  44
  45/*
  46 * ACPI 2.0 chapter 13 PCI interface definitions.
  47 */
  48
  49#define AMD_EC_DATA     0x00    /* data register */
  50#define AMD_EC_SC       0x04    /* status of controller */
  51#define AMD_EC_CMD      0x04    /* command register */
  52#define AMD_EC_ICR      0x08    /* interrupt control register */
  53
  54#define AMD_EC_SC_SMI   0x04    /* smi event pending */
  55#define AMD_EC_SC_SCI   0x02    /* sci event pending */
  56#define AMD_EC_SC_BURST 0x01    /* burst mode enabled */
  57#define AMD_EC_SC_CMD   0x08    /* byte in data reg is command */
  58#define AMD_EC_SC_IBF   0x02    /* data ready for embedded controller */
  59#define AMD_EC_SC_OBF   0x01    /* data ready for host */
  60
  61#define AMD_EC_CMD_RD   0x80    /* read EC */
  62#define AMD_EC_CMD_WR   0x81    /* write EC */
  63#define AMD_EC_CMD_BE   0x82    /* enable burst mode */
  64#define AMD_EC_CMD_BD   0x83    /* disable burst mode */
  65#define AMD_EC_CMD_QR   0x84    /* query EC */
  66
  67/*
  68 * ACPI 2.0 chapter 13 access of registers of the EC
  69 */
  70
  71static int amd_ec_wait_write(struct amd_smbus *smbus)
  72{
  73        int timeout = 500;
  74
  75        while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
  76                udelay(1);
  77
  78        if (!timeout) {
  79                dev_warn(&smbus->dev->dev,
  80                         "Timeout while waiting for IBF to clear\n");
  81                return -ETIMEDOUT;
  82        }
  83
  84        return 0;
  85}
  86
  87static int amd_ec_wait_read(struct amd_smbus *smbus)
  88{
  89        int timeout = 500;
  90
  91        while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
  92                udelay(1);
  93
  94        if (!timeout) {
  95                dev_warn(&smbus->dev->dev,
  96                         "Timeout while waiting for OBF to set\n");
  97                return -ETIMEDOUT;
  98        }
  99
 100        return 0;
 101}
 102
 103static int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
 104                unsigned char *data)
 105{
 106        int status;
 107
 108        status = amd_ec_wait_write(smbus);
 109        if (status)
 110                return status;
 111        outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
 112
 113        status = amd_ec_wait_write(smbus);
 114        if (status)
 115                return status;
 116        outb(address, smbus->base + AMD_EC_DATA);
 117
 118        status = amd_ec_wait_read(smbus);
 119        if (status)
 120                return status;
 121        *data = inb(smbus->base + AMD_EC_DATA);
 122
 123        return 0;
 124}
 125
 126static int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
 127                unsigned char data)
 128{
 129        int status;
 130
 131        status = amd_ec_wait_write(smbus);
 132        if (status)
 133                return status;
 134        outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
 135
 136        status = amd_ec_wait_write(smbus);
 137        if (status)
 138                return status;
 139        outb(address, smbus->base + AMD_EC_DATA);
 140
 141        status = amd_ec_wait_write(smbus);
 142        if (status)
 143                return status;
 144        outb(data, smbus->base + AMD_EC_DATA);
 145
 146        return 0;
 147}
 148
 149/*
 150 * ACPI 2.0 chapter 13 SMBus 2.0 EC register model
 151 */
 152
 153#define AMD_SMB_PRTCL   0x00    /* protocol, PEC */
 154#define AMD_SMB_STS     0x01    /* status */
 155#define AMD_SMB_ADDR    0x02    /* address */
 156#define AMD_SMB_CMD     0x03    /* command */
 157#define AMD_SMB_DATA    0x04    /* 32 data registers */
 158#define AMD_SMB_BCNT    0x24    /* number of data bytes */
 159#define AMD_SMB_ALRM_A  0x25    /* alarm address */
 160#define AMD_SMB_ALRM_D  0x26    /* 2 bytes alarm data */
 161
 162#define AMD_SMB_STS_DONE        0x80
 163#define AMD_SMB_STS_ALRM        0x40
 164#define AMD_SMB_STS_RES         0x20
 165#define AMD_SMB_STS_STATUS      0x1f
 166
 167#define AMD_SMB_STATUS_OK       0x00
 168#define AMD_SMB_STATUS_FAIL     0x07
 169#define AMD_SMB_STATUS_DNAK     0x10
 170#define AMD_SMB_STATUS_DERR     0x11
 171#define AMD_SMB_STATUS_CMD_DENY 0x12
 172#define AMD_SMB_STATUS_UNKNOWN  0x13
 173#define AMD_SMB_STATUS_ACC_DENY 0x17
 174#define AMD_SMB_STATUS_TIMEOUT  0x18
 175#define AMD_SMB_STATUS_NOTSUP   0x19
 176#define AMD_SMB_STATUS_BUSY     0x1A
 177#define AMD_SMB_STATUS_PEC      0x1F
 178
 179#define AMD_SMB_PRTCL_WRITE             0x00
 180#define AMD_SMB_PRTCL_READ              0x01
 181#define AMD_SMB_PRTCL_QUICK             0x02
 182#define AMD_SMB_PRTCL_BYTE              0x04
 183#define AMD_SMB_PRTCL_BYTE_DATA         0x06
 184#define AMD_SMB_PRTCL_WORD_DATA         0x08
 185#define AMD_SMB_PRTCL_BLOCK_DATA        0x0a
 186#define AMD_SMB_PRTCL_PROC_CALL         0x0c
 187#define AMD_SMB_PRTCL_BLOCK_PROC_CALL   0x0d
 188#define AMD_SMB_PRTCL_I2C_BLOCK_DATA    0x4a
 189#define AMD_SMB_PRTCL_PEC               0x80
 190
 191
 192static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
 193                unsigned short flags, char read_write, u8 command, int size,
 194                union i2c_smbus_data * data)
 195{
 196        struct amd_smbus *smbus = adap->algo_data;
 197        unsigned char protocol, len, pec, temp[2];
 198        int i, status;
 199
 200        protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
 201                                                  : AMD_SMB_PRTCL_WRITE;
 202        pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
 203
 204        switch (size) {
 205                case I2C_SMBUS_QUICK:
 206                        protocol |= AMD_SMB_PRTCL_QUICK;
 207                        read_write = I2C_SMBUS_WRITE;
 208                        break;
 209
 210                case I2C_SMBUS_BYTE:
 211                        if (read_write == I2C_SMBUS_WRITE) {
 212                                status = amd_ec_write(smbus, AMD_SMB_CMD,
 213                                                      command);
 214                                if (status)
 215                                        return status;
 216                        }
 217                        protocol |= AMD_SMB_PRTCL_BYTE;
 218                        break;
 219
 220                case I2C_SMBUS_BYTE_DATA:
 221                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 222                        if (status)
 223                                return status;
 224                        if (read_write == I2C_SMBUS_WRITE) {
 225                                status = amd_ec_write(smbus, AMD_SMB_DATA,
 226                                                      data->byte);
 227                                if (status)
 228                                        return status;
 229                        }
 230                        protocol |= AMD_SMB_PRTCL_BYTE_DATA;
 231                        break;
 232
 233                case I2C_SMBUS_WORD_DATA:
 234                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 235                        if (status)
 236                                return status;
 237                        if (read_write == I2C_SMBUS_WRITE) {
 238                                status = amd_ec_write(smbus, AMD_SMB_DATA,
 239                                                      data->word & 0xff);
 240                                if (status)
 241                                        return status;
 242                                status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
 243                                                      data->word >> 8);
 244                                if (status)
 245                                        return status;
 246                        }
 247                        protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
 248                        break;
 249
 250                case I2C_SMBUS_BLOCK_DATA:
 251                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 252                        if (status)
 253                                return status;
 254                        if (read_write == I2C_SMBUS_WRITE) {
 255                                len = min_t(u8, data->block[0],
 256                                            I2C_SMBUS_BLOCK_MAX);
 257                                status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
 258                                if (status)
 259                                        return status;
 260                                for (i = 0; i < len; i++) {
 261                                        status =
 262                                          amd_ec_write(smbus, AMD_SMB_DATA + i,
 263                                                       data->block[i + 1]);
 264                                        if (status)
 265                                                return status;
 266                                }
 267                        }
 268                        protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
 269                        break;
 270
 271                case I2C_SMBUS_I2C_BLOCK_DATA:
 272                        len = min_t(u8, data->block[0],
 273                                    I2C_SMBUS_BLOCK_MAX);
 274                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 275                        if (status)
 276                                return status;
 277                        status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
 278                        if (status)
 279                                return status;
 280                        if (read_write == I2C_SMBUS_WRITE)
 281                                for (i = 0; i < len; i++) {
 282                                        status =
 283                                          amd_ec_write(smbus, AMD_SMB_DATA + i,
 284                                                       data->block[i + 1]);
 285                                        if (status)
 286                                                return status;
 287                                }
 288                        protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
 289                        break;
 290
 291                case I2C_SMBUS_PROC_CALL:
 292                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 293                        if (status)
 294                                return status;
 295                        status = amd_ec_write(smbus, AMD_SMB_DATA,
 296                                              data->word & 0xff);
 297                        if (status)
 298                                return status;
 299                        status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
 300                                              data->word >> 8);
 301                        if (status)
 302                                return status;
 303                        protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
 304                        read_write = I2C_SMBUS_READ;
 305                        break;
 306
 307                case I2C_SMBUS_BLOCK_PROC_CALL:
 308                        len = min_t(u8, data->block[0],
 309                                    I2C_SMBUS_BLOCK_MAX - 1);
 310                        status = amd_ec_write(smbus, AMD_SMB_CMD, command);
 311                        if (status)
 312                                return status;
 313                        status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
 314                        if (status)
 315                                return status;
 316                        for (i = 0; i < len; i++) {
 317                                status = amd_ec_write(smbus, AMD_SMB_DATA + i,
 318                                                      data->block[i + 1]);
 319                                if (status)
 320                                        return status;
 321                        }
 322                        protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
 323                        read_write = I2C_SMBUS_READ;
 324                        break;
 325
 326                default:
 327                        dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
 328                        return -EOPNOTSUPP;
 329        }
 330
 331        status = amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
 332        if (status)
 333                return status;
 334        status = amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
 335        if (status)
 336                return status;
 337
 338        status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
 339        if (status)
 340                return status;
 341
 342        if (~temp[0] & AMD_SMB_STS_DONE) {
 343                udelay(500);
 344                status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
 345                if (status)
 346                        return status;
 347        }
 348
 349        if (~temp[0] & AMD_SMB_STS_DONE) {
 350                msleep(1);
 351                status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
 352                if (status)
 353                        return status;
 354        }
 355
 356        if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
 357                return -EIO;
 358
 359        if (read_write == I2C_SMBUS_WRITE)
 360                return 0;
 361
 362        switch (size) {
 363                case I2C_SMBUS_BYTE:
 364                case I2C_SMBUS_BYTE_DATA:
 365                        status = amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
 366                        if (status)
 367                                return status;
 368                        break;
 369
 370                case I2C_SMBUS_WORD_DATA:
 371                case I2C_SMBUS_PROC_CALL:
 372                        status = amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
 373                        if (status)
 374                                return status;
 375                        status = amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
 376                        if (status)
 377                                return status;
 378                        data->word = (temp[1] << 8) | temp[0];
 379                        break;
 380
 381                case I2C_SMBUS_BLOCK_DATA:
 382                case I2C_SMBUS_BLOCK_PROC_CALL:
 383                        status = amd_ec_read(smbus, AMD_SMB_BCNT, &len);
 384                        if (status)
 385                                return status;
 386                        len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
 387                case I2C_SMBUS_I2C_BLOCK_DATA:
 388                        for (i = 0; i < len; i++) {
 389                                status = amd_ec_read(smbus, AMD_SMB_DATA + i,
 390                                                     data->block + i + 1);
 391                                if (status)
 392                                        return status;
 393                        }
 394                        data->block[0] = len;
 395                        break;
 396        }
 397
 398        return 0;
 399}
 400
 401
 402static u32 amd8111_func(struct i2c_adapter *adapter)
 403{
 404        return  I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 405                I2C_FUNC_SMBUS_BYTE_DATA |
 406                I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
 407                I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
 408                I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_PEC;
 409}
 410
 411static const struct i2c_algorithm smbus_algorithm = {
 412        .smbus_xfer = amd8111_access,
 413        .functionality = amd8111_func,
 414};
 415
 416
 417static const struct pci_device_id amd8111_ids[] = {
 418        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
 419        { 0, }
 420};
 421
 422MODULE_DEVICE_TABLE (pci, amd8111_ids);
 423
 424static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
 425{
 426        struct amd_smbus *smbus;
 427        int error;
 428
 429        if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
 430                return -ENODEV;
 431
 432        smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
 433        if (!smbus)
 434                return -ENOMEM;
 435
 436        smbus->dev = dev;
 437        smbus->base = pci_resource_start(dev, 0);
 438        smbus->size = pci_resource_len(dev, 0);
 439
 440        error = acpi_check_resource_conflict(&dev->resource[0]);
 441        if (error) {
 442                error = -ENODEV;
 443                goto out_kfree;
 444        }
 445
 446        if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
 447                error = -EBUSY;
 448                goto out_kfree;
 449        }
 450
 451        smbus->adapter.owner = THIS_MODULE;
 452        snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
 453                "SMBus2 AMD8111 adapter at %04x", smbus->base);
 454        smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 455        smbus->adapter.algo = &smbus_algorithm;
 456        smbus->adapter.algo_data = smbus;
 457
 458        /* set up the sysfs linkage to our parent device */
 459        smbus->adapter.dev.parent = &dev->dev;
 460
 461        pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
 462        error = i2c_add_adapter(&smbus->adapter);
 463        if (error)
 464                goto out_release_region;
 465
 466        pci_set_drvdata(dev, smbus);
 467        return 0;
 468
 469 out_release_region:
 470        release_region(smbus->base, smbus->size);
 471 out_kfree:
 472        kfree(smbus);
 473        return error;
 474}
 475
 476static void amd8111_remove(struct pci_dev *dev)
 477{
 478        struct amd_smbus *smbus = pci_get_drvdata(dev);
 479
 480        i2c_del_adapter(&smbus->adapter);
 481        release_region(smbus->base, smbus->size);
 482        kfree(smbus);
 483}
 484
 485static struct pci_driver amd8111_driver = {
 486        .name           = "amd8111_smbus2",
 487        .id_table       = amd8111_ids,
 488        .probe          = amd8111_probe,
 489        .remove         = amd8111_remove,
 490};
 491
 492module_pci_driver(amd8111_driver);
 493