linux/drivers/i2c/busses/i2c-xlr.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011, Netlogic Microsystems Inc.
   3 * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
   4 *
   5 * This file is licensed under the terms of the GNU General Public
   6 * License version 2.  This program is licensed "as is" without any
   7 * warranty of any kind, whether express or implied.
   8 */
   9
  10#include <linux/err.h>
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/slab.h>
  14#include <linux/ioport.h>
  15#include <linux/delay.h>
  16#include <linux/errno.h>
  17#include <linux/i2c.h>
  18#include <linux/io.h>
  19#include <linux/platform_device.h>
  20#include <linux/of_device.h>
  21#include <linux/clk.h>
  22#include <linux/interrupt.h>
  23#include <linux/wait.h>
  24
  25/* XLR I2C REGISTERS */
  26#define XLR_I2C_CFG             0x00
  27#define XLR_I2C_CLKDIV          0x01
  28#define XLR_I2C_DEVADDR         0x02
  29#define XLR_I2C_ADDR            0x03
  30#define XLR_I2C_DATAOUT         0x04
  31#define XLR_I2C_DATAIN          0x05
  32#define XLR_I2C_STATUS          0x06
  33#define XLR_I2C_STARTXFR        0x07
  34#define XLR_I2C_BYTECNT         0x08
  35#define XLR_I2C_HDSTATIM        0x09
  36
  37/* Sigma Designs additional registers */
  38#define XLR_I2C_INT_EN          0x09
  39#define XLR_I2C_INT_STAT        0x0a
  40
  41/* XLR I2C REGISTERS FLAGS */
  42#define XLR_I2C_BUS_BUSY        0x01
  43#define XLR_I2C_SDOEMPTY        0x02
  44#define XLR_I2C_RXRDY           0x04
  45#define XLR_I2C_ACK_ERR         0x08
  46#define XLR_I2C_ARB_STARTERR    0x30
  47
  48/* Register Values */
  49#define XLR_I2C_CFG_ADDR        0xF8
  50#define XLR_I2C_CFG_NOADDR      0xFA
  51#define XLR_I2C_STARTXFR_ND     0x02    /* No Data */
  52#define XLR_I2C_STARTXFR_RD     0x01    /* Read */
  53#define XLR_I2C_STARTXFR_WR     0x00    /* Write */
  54
  55#define XLR_I2C_TIMEOUT         10      /* timeout per byte in msec */
  56
  57/*
  58 * On XLR/XLS, we need to use __raw_ IO to read the I2C registers
  59 * because they are in the big-endian MMIO area on the SoC.
  60 *
  61 * The readl/writel implementation on XLR/XLS byteswaps, because
  62 * those are for its little-endian PCI space (see arch/mips/Kconfig).
  63 */
  64static inline void xlr_i2c_wreg(u32 __iomem *base, unsigned int reg, u32 val)
  65{
  66        __raw_writel(val, base + reg);
  67}
  68
  69static inline u32 xlr_i2c_rdreg(u32 __iomem *base, unsigned int reg)
  70{
  71        return __raw_readl(base + reg);
  72}
  73
  74#define XLR_I2C_FLAG_IRQ        1
  75
  76struct xlr_i2c_config {
  77        u32 flags;              /* optional feature support */
  78        u32 status_busy;        /* value of STATUS[0] when busy */
  79        u32 cfg_extra;          /* extra CFG bits to set */
  80};
  81
  82struct xlr_i2c_private {
  83        struct i2c_adapter adap;
  84        u32 __iomem *iobase;
  85        int irq;
  86        int pos;
  87        struct i2c_msg *msg;
  88        const struct xlr_i2c_config *cfg;
  89        wait_queue_head_t wait;
  90        struct clk *clk;
  91};
  92
  93static int xlr_i2c_busy(struct xlr_i2c_private *priv, u32 status)
  94{
  95        return (status & XLR_I2C_BUS_BUSY) == priv->cfg->status_busy;
  96}
  97
  98static int xlr_i2c_idle(struct xlr_i2c_private *priv)
  99{
 100        return !xlr_i2c_busy(priv, xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS));
 101}
 102
 103static int xlr_i2c_wait(struct xlr_i2c_private *priv, unsigned long timeout)
 104{
 105        int status;
 106        int t;
 107
 108        t = wait_event_timeout(priv->wait, xlr_i2c_idle(priv),
 109                                msecs_to_jiffies(timeout));
 110        if (!t)
 111                return -ETIMEDOUT;
 112
 113        status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
 114
 115        return status & XLR_I2C_ACK_ERR ? -EIO : 0;
 116}
 117
 118static void xlr_i2c_tx_irq(struct xlr_i2c_private *priv, u32 status)
 119{
 120        struct i2c_msg *msg = priv->msg;
 121
 122        if (status & XLR_I2C_SDOEMPTY)
 123                xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT,
 124                                msg->buf[priv->pos++]);
 125}
 126
 127static void xlr_i2c_rx_irq(struct xlr_i2c_private *priv, u32 status)
 128{
 129        struct i2c_msg *msg = priv->msg;
 130
 131        if (status & XLR_I2C_RXRDY)
 132                msg->buf[priv->pos++] =
 133                        xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN);
 134}
 135
 136static irqreturn_t xlr_i2c_irq(int irq, void *dev_id)
 137{
 138        struct xlr_i2c_private *priv = dev_id;
 139        struct i2c_msg *msg = priv->msg;
 140        u32 int_stat, status;
 141
 142        int_stat = xlr_i2c_rdreg(priv->iobase, XLR_I2C_INT_STAT);
 143        if (!int_stat)
 144                return IRQ_NONE;
 145
 146        xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, int_stat);
 147
 148        if (!msg)
 149                return IRQ_HANDLED;
 150
 151        status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
 152
 153        if (priv->pos < msg->len) {
 154                if (msg->flags & I2C_M_RD)
 155                        xlr_i2c_rx_irq(priv, status);
 156                else
 157                        xlr_i2c_tx_irq(priv, status);
 158        }
 159
 160        if (!xlr_i2c_busy(priv, status))
 161                wake_up(&priv->wait);
 162
 163        return IRQ_HANDLED;
 164}
 165
 166static int xlr_i2c_tx(struct xlr_i2c_private *priv,  u16 len,
 167        u8 *buf, u16 addr)
 168{
 169        struct i2c_adapter *adap = &priv->adap;
 170        unsigned long timeout, stoptime, checktime;
 171        u32 i2c_status;
 172        int pos, timedout;
 173        u8 offset;
 174        u32 xfer;
 175
 176        if (!len)
 177                return -EOPNOTSUPP;
 178
 179        offset = buf[0];
 180        xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset);
 181        xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr);
 182        xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG,
 183                        XLR_I2C_CFG_ADDR | priv->cfg->cfg_extra);
 184
 185        timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT);
 186        stoptime = jiffies + timeout;
 187        timedout = 0;
 188
 189        if (len == 1) {
 190                xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1);
 191                xfer = XLR_I2C_STARTXFR_ND;
 192                pos = 1;
 193        } else {
 194                xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 2);
 195                xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[1]);
 196                xfer = XLR_I2C_STARTXFR_WR;
 197                pos = 2;
 198        }
 199
 200        priv->pos = pos;
 201
 202retry:
 203        /* retry can only happen on the first byte */
 204        xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, xfer);
 205
 206        if (priv->irq > 0)
 207                return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len);
 208
 209        while (!timedout) {
 210                checktime = jiffies;
 211                i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
 212
 213                if ((i2c_status & XLR_I2C_SDOEMPTY) && pos < len) {
 214                        xlr_i2c_wreg(priv->iobase, XLR_I2C_DATAOUT, buf[pos++]);
 215
 216                        /* reset timeout on successful xmit */
 217                        stoptime = jiffies + timeout;
 218                }
 219                timedout = time_after(checktime, stoptime);
 220
 221                if (i2c_status & XLR_I2C_ARB_STARTERR) {
 222                        if (timedout)
 223                                break;
 224                        goto retry;
 225                }
 226
 227                if (i2c_status & XLR_I2C_ACK_ERR)
 228                        return -EIO;
 229
 230                if (!xlr_i2c_busy(priv, i2c_status) && pos >= len)
 231                        return 0;
 232        }
 233        dev_err(&adap->dev, "I2C transmit timeout\n");
 234        return -ETIMEDOUT;
 235}
 236
 237static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr)
 238{
 239        struct i2c_adapter *adap = &priv->adap;
 240        u32 i2c_status;
 241        unsigned long timeout, stoptime, checktime;
 242        int nbytes, timedout;
 243
 244        if (!len)
 245                return -EOPNOTSUPP;
 246
 247        xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG,
 248                        XLR_I2C_CFG_NOADDR | priv->cfg->cfg_extra);
 249        xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1);
 250        xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr);
 251
 252        priv->pos = 0;
 253
 254        timeout = msecs_to_jiffies(XLR_I2C_TIMEOUT);
 255        stoptime = jiffies + timeout;
 256        timedout = 0;
 257        nbytes = 0;
 258retry:
 259        xlr_i2c_wreg(priv->iobase, XLR_I2C_STARTXFR, XLR_I2C_STARTXFR_RD);
 260
 261        if (priv->irq > 0)
 262                return xlr_i2c_wait(priv, XLR_I2C_TIMEOUT * len);
 263
 264        while (!timedout) {
 265                checktime = jiffies;
 266                i2c_status = xlr_i2c_rdreg(priv->iobase, XLR_I2C_STATUS);
 267                if (i2c_status & XLR_I2C_RXRDY) {
 268                        if (nbytes >= len)
 269                                return -EIO;    /* should not happen */
 270
 271                        buf[nbytes++] =
 272                                xlr_i2c_rdreg(priv->iobase, XLR_I2C_DATAIN);
 273
 274                        /* reset timeout on successful read */
 275                        stoptime = jiffies + timeout;
 276                }
 277
 278                timedout = time_after(checktime, stoptime);
 279                if (i2c_status & XLR_I2C_ARB_STARTERR) {
 280                        if (timedout)
 281                                break;
 282                        goto retry;
 283                }
 284
 285                if (i2c_status & XLR_I2C_ACK_ERR)
 286                        return -EIO;
 287
 288                if (!xlr_i2c_busy(priv, i2c_status))
 289                        return 0;
 290        }
 291
 292        dev_err(&adap->dev, "I2C receive timeout\n");
 293        return -ETIMEDOUT;
 294}
 295
 296static int xlr_i2c_xfer(struct i2c_adapter *adap,
 297        struct i2c_msg *msgs, int num)
 298{
 299        struct i2c_msg *msg;
 300        int i;
 301        int ret = 0;
 302        struct xlr_i2c_private *priv = i2c_get_adapdata(adap);
 303
 304        ret = clk_enable(priv->clk);
 305        if (ret)
 306                return ret;
 307
 308        if (priv->irq)
 309                xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0xf);
 310
 311
 312        for (i = 0; ret == 0 && i < num; i++) {
 313                msg = &msgs[i];
 314                priv->msg = msg;
 315                if (msg->flags & I2C_M_RD)
 316                        ret = xlr_i2c_rx(priv, msg->len, &msg->buf[0],
 317                                        msg->addr);
 318                else
 319                        ret = xlr_i2c_tx(priv, msg->len, &msg->buf[0],
 320                                        msg->addr);
 321        }
 322
 323        if (priv->irq)
 324                xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0);
 325
 326        clk_disable(priv->clk);
 327        priv->msg = NULL;
 328
 329        return (ret != 0) ? ret : num;
 330}
 331
 332static u32 xlr_func(struct i2c_adapter *adap)
 333{
 334        /* Emulate SMBUS over I2C */
 335        return (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) | I2C_FUNC_I2C;
 336}
 337
 338static struct i2c_algorithm xlr_i2c_algo = {
 339        .master_xfer    = xlr_i2c_xfer,
 340        .functionality  = xlr_func,
 341};
 342
 343static const struct xlr_i2c_config xlr_i2c_config_default = {
 344        .status_busy    = XLR_I2C_BUS_BUSY,
 345        .cfg_extra      = 0,
 346};
 347
 348static const struct xlr_i2c_config xlr_i2c_config_tangox = {
 349        .flags          = XLR_I2C_FLAG_IRQ,
 350        .status_busy    = 0,
 351        .cfg_extra      = 1 << 8,
 352};
 353
 354static const struct of_device_id xlr_i2c_dt_ids[] = {
 355        {
 356                .compatible     = "sigma,smp8642-i2c",
 357                .data           = &xlr_i2c_config_tangox,
 358        },
 359        { }
 360};
 361
 362static int xlr_i2c_probe(struct platform_device *pdev)
 363{
 364        const struct of_device_id *match;
 365        struct xlr_i2c_private  *priv;
 366        struct resource *res;
 367        struct clk *clk;
 368        unsigned long clk_rate;
 369        unsigned long clk_div;
 370        u32 busfreq;
 371        int irq;
 372        int ret;
 373
 374        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 375        if (!priv)
 376                return -ENOMEM;
 377
 378        match = of_match_device(xlr_i2c_dt_ids, &pdev->dev);
 379        if (match)
 380                priv->cfg = match->data;
 381        else
 382                priv->cfg = &xlr_i2c_config_default;
 383
 384        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 385        priv->iobase = devm_ioremap_resource(&pdev->dev, res);
 386        if (IS_ERR(priv->iobase))
 387                return PTR_ERR(priv->iobase);
 388
 389        irq = platform_get_irq(pdev, 0);
 390
 391        if (irq > 0 && (priv->cfg->flags & XLR_I2C_FLAG_IRQ)) {
 392                priv->irq = irq;
 393
 394                xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_EN, 0);
 395                xlr_i2c_wreg(priv->iobase, XLR_I2C_INT_STAT, 0xf);
 396
 397                ret = devm_request_irq(&pdev->dev, priv->irq, xlr_i2c_irq,
 398                                        IRQF_SHARED, dev_name(&pdev->dev),
 399                                        priv);
 400                if (ret)
 401                        return ret;
 402
 403                init_waitqueue_head(&priv->wait);
 404        }
 405
 406        if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
 407                                 &busfreq))
 408                busfreq = 100000;
 409
 410        clk = devm_clk_get(&pdev->dev, NULL);
 411        if (!IS_ERR(clk)) {
 412                ret = clk_prepare_enable(clk);
 413                if (ret)
 414                        return ret;
 415
 416                clk_rate = clk_get_rate(clk);
 417                clk_div = DIV_ROUND_UP(clk_rate, 2 * busfreq);
 418                xlr_i2c_wreg(priv->iobase, XLR_I2C_CLKDIV, clk_div);
 419
 420                clk_disable(clk);
 421                priv->clk = clk;
 422        }
 423
 424        priv->adap.dev.parent = &pdev->dev;
 425        priv->adap.dev.of_node  = pdev->dev.of_node;
 426        priv->adap.owner        = THIS_MODULE;
 427        priv->adap.algo_data    = priv;
 428        priv->adap.algo         = &xlr_i2c_algo;
 429        priv->adap.nr           = pdev->id;
 430        priv->adap.class        = I2C_CLASS_HWMON;
 431        snprintf(priv->adap.name, sizeof(priv->adap.name), "xlr-i2c");
 432
 433        i2c_set_adapdata(&priv->adap, priv);
 434        ret = i2c_add_numbered_adapter(&priv->adap);
 435        if (ret < 0) {
 436                dev_err(&priv->adap.dev, "Failed to add i2c bus.\n");
 437                return ret;
 438        }
 439
 440        platform_set_drvdata(pdev, priv);
 441        dev_info(&priv->adap.dev, "Added I2C Bus.\n");
 442        return 0;
 443}
 444
 445static int xlr_i2c_remove(struct platform_device *pdev)
 446{
 447        struct xlr_i2c_private *priv;
 448
 449        priv = platform_get_drvdata(pdev);
 450        i2c_del_adapter(&priv->adap);
 451        clk_unprepare(priv->clk);
 452
 453        return 0;
 454}
 455
 456static struct platform_driver xlr_i2c_driver = {
 457        .probe  = xlr_i2c_probe,
 458        .remove = xlr_i2c_remove,
 459        .driver = {
 460                .name   = "xlr-i2cbus",
 461                .of_match_table = xlr_i2c_dt_ids,
 462        },
 463};
 464
 465module_platform_driver(xlr_i2c_driver);
 466
 467MODULE_AUTHOR("Ganesan Ramalingam <ganesanr@netlogicmicro.com>");
 468MODULE_DESCRIPTION("XLR/XLS SoC I2C Controller driver");
 469MODULE_LICENSE("GPL v2");
 470MODULE_ALIAS("platform:xlr-i2cbus");
 471