linux/drivers/i2c/busses/i2c-isch.c
<<
>>
Prefs
   1/*
   2    i2c-isch.c - Linux kernel driver for Intel SCH chipset SMBus
   3    - Based on i2c-piix4.c
   4    Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
   5    Philip Edelbrock <phil@netroedge.com>
   6    - Intel SCH support
   7    Copyright (c) 2007 - 2008 Jacob Jun Pan <jacob.jun.pan@intel.com>
   8
   9    This program is free software; you can redistribute it and/or modify
  10    it under the terms of the GNU General Public License version 2 as
  11    published by the Free Software Foundation.
  12
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17
  18    You should have received a copy of the GNU General Public License
  19    along with this program; if not, write to the Free Software
  20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21*/
  22
  23/*
  24   Supports:
  25        Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L)
  26   Note: we assume there can only be one device, with one SMBus interface.
  27*/
  28
  29#include <linux/module.h>
  30#include <linux/platform_device.h>
  31#include <linux/kernel.h>
  32#include <linux/delay.h>
  33#include <linux/stddef.h>
  34#include <linux/ioport.h>
  35#include <linux/i2c.h>
  36#include <linux/init.h>
  37#include <linux/io.h>
  38#include <linux/acpi.h>
  39
  40/* SCH SMBus address offsets */
  41#define SMBHSTCNT       (0 + sch_smba)
  42#define SMBHSTSTS       (1 + sch_smba)
  43#define SMBHSTCLK       (2 + sch_smba)
  44#define SMBHSTADD       (4 + sch_smba) /* TSA */
  45#define SMBHSTCMD       (5 + sch_smba)
  46#define SMBHSTDAT0      (6 + sch_smba)
  47#define SMBHSTDAT1      (7 + sch_smba)
  48#define SMBBLKDAT       (0x20 + sch_smba)
  49
  50/* Other settings */
  51#define MAX_RETRIES     5000
  52
  53/* I2C constants */
  54#define SCH_QUICK               0x00
  55#define SCH_BYTE                0x01
  56#define SCH_BYTE_DATA           0x02
  57#define SCH_WORD_DATA           0x03
  58#define SCH_BLOCK_DATA          0x05
  59
  60static unsigned short sch_smba;
  61static struct i2c_adapter sch_adapter;
  62static int backbone_speed = 33000; /* backbone speed in kHz */
  63module_param(backbone_speed, int, S_IRUSR | S_IWUSR);
  64MODULE_PARM_DESC(backbone_speed, "Backbone speed in kHz, (default = 33000)");
  65
  66/*
  67 * Start the i2c transaction -- the i2c_access will prepare the transaction
  68 * and this function will execute it.
  69 * return 0 for success and others for failure.
  70 */
  71static int sch_transaction(void)
  72{
  73        int temp;
  74        int result = 0;
  75        int retries = 0;
  76
  77        dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
  78                "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
  79                inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
  80                inb(SMBHSTDAT1));
  81
  82        /* Make sure the SMBus host is ready to start transmitting */
  83        temp = inb(SMBHSTSTS) & 0x0f;
  84        if (temp) {
  85                /* Can not be busy since we checked it in sch_access */
  86                if (temp & 0x01) {
  87                        dev_dbg(&sch_adapter.dev, "Completion (%02x). "
  88                                "Clear...\n", temp);
  89                }
  90                if (temp & 0x06) {
  91                        dev_dbg(&sch_adapter.dev, "SMBus error (%02x). "
  92                                "Resetting...\n", temp);
  93                }
  94                outb(temp, SMBHSTSTS);
  95                temp = inb(SMBHSTSTS) & 0x0f;
  96                if (temp) {
  97                        dev_err(&sch_adapter.dev,
  98                                "SMBus is not ready: (%02x)\n", temp);
  99                        return -EAGAIN;
 100                }
 101        }
 102
 103        /* start the transaction by setting bit 4 */
 104        outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT);
 105
 106        do {
 107                usleep_range(100, 200);
 108                temp = inb(SMBHSTSTS) & 0x0f;
 109        } while ((temp & 0x08) && (retries++ < MAX_RETRIES));
 110
 111        /* If the SMBus is still busy, we give up */
 112        if (retries > MAX_RETRIES) {
 113                dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
 114                result = -ETIMEDOUT;
 115        }
 116        if (temp & 0x04) {
 117                result = -EIO;
 118                dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
 119                        "locked until next hard reset. (sorry!)\n");
 120                /* Clock stops and slave is stuck in mid-transmission */
 121        } else if (temp & 0x02) {
 122                result = -EIO;
 123                dev_err(&sch_adapter.dev, "Error: no response!\n");
 124        } else if (temp & 0x01) {
 125                dev_dbg(&sch_adapter.dev, "Post complete!\n");
 126                outb(temp, SMBHSTSTS);
 127                temp = inb(SMBHSTSTS) & 0x07;
 128                if (temp & 0x06) {
 129                        /* Completion clear failed */
 130                        dev_dbg(&sch_adapter.dev, "Failed reset at end of "
 131                                "transaction (%02x), Bus error!\n", temp);
 132                }
 133        } else {
 134                result = -ENXIO;
 135                dev_dbg(&sch_adapter.dev, "No such address.\n");
 136        }
 137        dev_dbg(&sch_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
 138                "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
 139                inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
 140                inb(SMBHSTDAT1));
 141        return result;
 142}
 143
 144/*
 145 * This is the main access entry for i2c-sch access
 146 * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write
 147 * (0 for read and 1 for write), size is i2c transaction type and data is the
 148 * union of transaction for data to be transferred or data read from bus.
 149 * return 0 for success and others for failure.
 150 */
 151static s32 sch_access(struct i2c_adapter *adap, u16 addr,
 152                 unsigned short flags, char read_write,
 153                 u8 command, int size, union i2c_smbus_data *data)
 154{
 155        int i, len, temp, rc;
 156
 157        /* Make sure the SMBus host is not busy */
 158        temp = inb(SMBHSTSTS) & 0x0f;
 159        if (temp & 0x08) {
 160                dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp);
 161                return -EAGAIN;
 162        }
 163        temp = inw(SMBHSTCLK);
 164        if (!temp) {
 165                /*
 166                 * We can't determine if we have 33 or 25 MHz clock for
 167                 * SMBus, so expect 33 MHz and calculate a bus clock of
 168                 * 100 kHz. If we actually run at 25 MHz the bus will be
 169                 * run ~75 kHz instead which should do no harm.
 170                 */
 171                dev_notice(&sch_adapter.dev,
 172                        "Clock divider unitialized. Setting defaults\n");
 173                outw(backbone_speed / (4 * 100), SMBHSTCLK);
 174        }
 175
 176        dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size,
 177                (read_write)?"READ":"WRITE");
 178        switch (size) {
 179        case I2C_SMBUS_QUICK:
 180                outb((addr << 1) | read_write, SMBHSTADD);
 181                size = SCH_QUICK;
 182                break;
 183        case I2C_SMBUS_BYTE:
 184                outb((addr << 1) | read_write, SMBHSTADD);
 185                if (read_write == I2C_SMBUS_WRITE)
 186                        outb(command, SMBHSTCMD);
 187                size = SCH_BYTE;
 188                break;
 189        case I2C_SMBUS_BYTE_DATA:
 190                outb((addr << 1) | read_write, SMBHSTADD);
 191                outb(command, SMBHSTCMD);
 192                if (read_write == I2C_SMBUS_WRITE)
 193                        outb(data->byte, SMBHSTDAT0);
 194                size = SCH_BYTE_DATA;
 195                break;
 196        case I2C_SMBUS_WORD_DATA:
 197                outb((addr << 1) | read_write, SMBHSTADD);
 198                outb(command, SMBHSTCMD);
 199                if (read_write == I2C_SMBUS_WRITE) {
 200                        outb(data->word & 0xff, SMBHSTDAT0);
 201                        outb((data->word & 0xff00) >> 8, SMBHSTDAT1);
 202                }
 203                size = SCH_WORD_DATA;
 204                break;
 205        case I2C_SMBUS_BLOCK_DATA:
 206                outb((addr << 1) | read_write, SMBHSTADD);
 207                outb(command, SMBHSTCMD);
 208                if (read_write == I2C_SMBUS_WRITE) {
 209                        len = data->block[0];
 210                        if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
 211                                return -EINVAL;
 212                        outb(len, SMBHSTDAT0);
 213                        for (i = 1; i <= len; i++)
 214                                outb(data->block[i], SMBBLKDAT+i-1);
 215                }
 216                size = SCH_BLOCK_DATA;
 217                break;
 218        default:
 219                dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
 220                return -EOPNOTSUPP;
 221        }
 222        dev_dbg(&sch_adapter.dev, "write size %d to 0x%04x\n", size, SMBHSTCNT);
 223        outb((inb(SMBHSTCNT) & 0xb0) | (size & 0x7), SMBHSTCNT);
 224
 225        rc = sch_transaction();
 226        if (rc) /* Error in transaction */
 227                return rc;
 228
 229        if ((read_write == I2C_SMBUS_WRITE) || (size == SCH_QUICK))
 230                return 0;
 231
 232        switch (size) {
 233        case SCH_BYTE:
 234        case SCH_BYTE_DATA:
 235                data->byte = inb(SMBHSTDAT0);
 236                break;
 237        case SCH_WORD_DATA:
 238                data->word = inb(SMBHSTDAT0) + (inb(SMBHSTDAT1) << 8);
 239                break;
 240        case SCH_BLOCK_DATA:
 241                data->block[0] = inb(SMBHSTDAT0);
 242                if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
 243                        return -EPROTO;
 244                for (i = 1; i <= data->block[0]; i++)
 245                        data->block[i] = inb(SMBBLKDAT+i-1);
 246                break;
 247        }
 248        return 0;
 249}
 250
 251static u32 sch_func(struct i2c_adapter *adapter)
 252{
 253        return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 254            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
 255            I2C_FUNC_SMBUS_BLOCK_DATA;
 256}
 257
 258static const struct i2c_algorithm smbus_algorithm = {
 259        .smbus_xfer     = sch_access,
 260        .functionality  = sch_func,
 261};
 262
 263static struct i2c_adapter sch_adapter = {
 264        .owner          = THIS_MODULE,
 265        .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
 266        .algo           = &smbus_algorithm,
 267};
 268
 269static int smbus_sch_probe(struct platform_device *dev)
 270{
 271        struct resource *res;
 272        int retval;
 273
 274        res = platform_get_resource(dev, IORESOURCE_IO, 0);
 275        if (!res)
 276                return -EBUSY;
 277
 278        if (!request_region(res->start, resource_size(res), dev->name)) {
 279                dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
 280                        sch_smba);
 281                return -EBUSY;
 282        }
 283
 284        sch_smba = res->start;
 285
 286        dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
 287
 288        /* set up the sysfs linkage to our parent device */
 289        sch_adapter.dev.parent = &dev->dev;
 290
 291        snprintf(sch_adapter.name, sizeof(sch_adapter.name),
 292                "SMBus SCH adapter at %04x", sch_smba);
 293
 294        retval = i2c_add_adapter(&sch_adapter);
 295        if (retval) {
 296                dev_err(&dev->dev, "Couldn't register adapter!\n");
 297                release_region(res->start, resource_size(res));
 298                sch_smba = 0;
 299        }
 300
 301        return retval;
 302}
 303
 304static int smbus_sch_remove(struct platform_device *pdev)
 305{
 306        struct resource *res;
 307        if (sch_smba) {
 308                i2c_del_adapter(&sch_adapter);
 309                res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 310                release_region(res->start, resource_size(res));
 311                sch_smba = 0;
 312        }
 313
 314        return 0;
 315}
 316
 317static struct platform_driver smbus_sch_driver = {
 318        .driver = {
 319                .name = "isch_smbus",
 320                .owner = THIS_MODULE,
 321        },
 322        .probe          = smbus_sch_probe,
 323        .remove         = smbus_sch_remove,
 324};
 325
 326module_platform_driver(smbus_sch_driver);
 327
 328MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
 329MODULE_DESCRIPTION("Intel SCH SMBus driver");
 330MODULE_LICENSE("GPL");
 331MODULE_ALIAS("platform:isch_smbus");
 332