linux/drivers/i2c/busses/i2c-xlp9xx.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2003-2015 Broadcom Corporation
   3 *
   4 * This file is licensed under the terms of the GNU General Public
   5 * License version 2. This program is licensed "as is" without any
   6 * warranty of any kind, whether express or implied.
   7 */
   8
   9#include <linux/completion.h>
  10#include <linux/i2c.h>
  11#include <linux/init.h>
  12#include <linux/interrupt.h>
  13#include <linux/io.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/platform_device.h>
  17
  18#define XLP9XX_I2C_DIV                  0x0
  19#define XLP9XX_I2C_CTRL                 0x1
  20#define XLP9XX_I2C_CMD                  0x2
  21#define XLP9XX_I2C_STATUS               0x3
  22#define XLP9XX_I2C_MTXFIFO              0x4
  23#define XLP9XX_I2C_MRXFIFO              0x5
  24#define XLP9XX_I2C_MFIFOCTRL            0x6
  25#define XLP9XX_I2C_STXFIFO              0x7
  26#define XLP9XX_I2C_SRXFIFO              0x8
  27#define XLP9XX_I2C_SFIFOCTRL            0x9
  28#define XLP9XX_I2C_SLAVEADDR            0xA
  29#define XLP9XX_I2C_OWNADDR              0xB
  30#define XLP9XX_I2C_FIFOWCNT             0xC
  31#define XLP9XX_I2C_INTEN                0xD
  32#define XLP9XX_I2C_INTST                0xE
  33#define XLP9XX_I2C_WAITCNT              0xF
  34#define XLP9XX_I2C_TIMEOUT              0X10
  35#define XLP9XX_I2C_GENCALLADDR          0x11
  36
  37#define XLP9XX_I2C_CMD_START            BIT(7)
  38#define XLP9XX_I2C_CMD_STOP             BIT(6)
  39#define XLP9XX_I2C_CMD_READ             BIT(5)
  40#define XLP9XX_I2C_CMD_WRITE            BIT(4)
  41#define XLP9XX_I2C_CMD_ACK              BIT(3)
  42
  43#define XLP9XX_I2C_CTRL_MCTLEN_SHIFT    16
  44#define XLP9XX_I2C_CTRL_MCTLEN_MASK     0xffff0000
  45#define XLP9XX_I2C_CTRL_RST             BIT(8)
  46#define XLP9XX_I2C_CTRL_EN              BIT(6)
  47#define XLP9XX_I2C_CTRL_MASTER          BIT(4)
  48#define XLP9XX_I2C_CTRL_FIFORD          BIT(1)
  49#define XLP9XX_I2C_CTRL_ADDMODE         BIT(0)
  50
  51#define XLP9XX_I2C_INTEN_NACKADDR       BIT(25)
  52#define XLP9XX_I2C_INTEN_SADDR          BIT(13)
  53#define XLP9XX_I2C_INTEN_DATADONE       BIT(12)
  54#define XLP9XX_I2C_INTEN_ARLOST         BIT(11)
  55#define XLP9XX_I2C_INTEN_MFIFOFULL      BIT(4)
  56#define XLP9XX_I2C_INTEN_MFIFOEMTY      BIT(3)
  57#define XLP9XX_I2C_INTEN_MFIFOHI        BIT(2)
  58#define XLP9XX_I2C_INTEN_BUSERR         BIT(0)
  59
  60#define XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT         8
  61#define XLP9XX_I2C_MFIFOCTRL_LOTH_SHIFT         0
  62#define XLP9XX_I2C_MFIFOCTRL_RST                BIT(16)
  63
  64#define XLP9XX_I2C_SLAVEADDR_RW                 BIT(0)
  65#define XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT         1
  66
  67#define XLP9XX_I2C_IP_CLK_FREQ          133000000UL
  68#define XLP9XX_I2C_DEFAULT_FREQ         100000
  69#define XLP9XX_I2C_HIGH_FREQ            400000
  70#define XLP9XX_I2C_FIFO_SIZE            0x80U
  71#define XLP9XX_I2C_TIMEOUT_MS           1000
  72
  73#define XLP9XX_I2C_FIFO_WCNT_MASK       0xff
  74#define XLP9XX_I2C_STATUS_ERRMASK       (XLP9XX_I2C_INTEN_ARLOST | \
  75                        XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_BUSERR)
  76
  77struct xlp9xx_i2c_dev {
  78        struct device *dev;
  79        struct i2c_adapter adapter;
  80        struct completion msg_complete;
  81        int irq;
  82        bool msg_read;
  83        u32 __iomem *base;
  84        u32 msg_buf_remaining;
  85        u32 msg_len;
  86        u32 clk_hz;
  87        u32 msg_err;
  88        u8 *msg_buf;
  89};
  90
  91static inline void xlp9xx_write_i2c_reg(struct xlp9xx_i2c_dev *priv,
  92                                        unsigned long reg, u32 val)
  93{
  94        writel(val, priv->base + reg);
  95}
  96
  97static inline u32 xlp9xx_read_i2c_reg(struct xlp9xx_i2c_dev *priv,
  98                                      unsigned long reg)
  99{
 100        return readl(priv->base + reg);
 101}
 102
 103static void xlp9xx_i2c_mask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
 104{
 105        u32 inten;
 106
 107        inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) & ~mask;
 108        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
 109}
 110
 111static void xlp9xx_i2c_unmask_irq(struct xlp9xx_i2c_dev *priv, u32 mask)
 112{
 113        u32 inten;
 114
 115        inten = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTEN) | mask;
 116        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, inten);
 117}
 118
 119static void xlp9xx_i2c_update_rx_fifo_thres(struct xlp9xx_i2c_dev *priv)
 120{
 121        u32 thres;
 122
 123        thres = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
 124        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
 125                             thres << XLP9XX_I2C_MFIFOCTRL_HITH_SHIFT);
 126}
 127
 128static void xlp9xx_i2c_fill_tx_fifo(struct xlp9xx_i2c_dev *priv)
 129{
 130        u32 len, i;
 131        u8 *buf = priv->msg_buf;
 132
 133        len = min(priv->msg_buf_remaining, XLP9XX_I2C_FIFO_SIZE);
 134        for (i = 0; i < len; i++)
 135                xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MTXFIFO, buf[i]);
 136        priv->msg_buf_remaining -= len;
 137        priv->msg_buf += len;
 138}
 139
 140static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
 141{
 142        u32 len, i;
 143        u8 *buf = priv->msg_buf;
 144
 145        len = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_FIFOWCNT) &
 146                                  XLP9XX_I2C_FIFO_WCNT_MASK;
 147        len = min(priv->msg_buf_remaining, len);
 148        for (i = 0; i < len; i++, buf++)
 149                *buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);
 150
 151        priv->msg_buf_remaining -= len;
 152        priv->msg_buf = buf;
 153
 154        if (priv->msg_buf_remaining)
 155                xlp9xx_i2c_update_rx_fifo_thres(priv);
 156}
 157
 158static irqreturn_t xlp9xx_i2c_isr(int irq, void *dev_id)
 159{
 160        struct xlp9xx_i2c_dev *priv = dev_id;
 161        u32 status;
 162
 163        status = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_INTST);
 164        if (status == 0)
 165                return IRQ_NONE;
 166
 167        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTST, status);
 168        if (status & XLP9XX_I2C_STATUS_ERRMASK) {
 169                priv->msg_err = status;
 170                goto xfer_done;
 171        }
 172
 173        /* SADDR ACK for SMBUS_QUICK */
 174        if ((status & XLP9XX_I2C_INTEN_SADDR) && (priv->msg_len == 0))
 175                goto xfer_done;
 176
 177        if (!priv->msg_read) {
 178                if (status & XLP9XX_I2C_INTEN_MFIFOEMTY) {
 179                        /* TX FIFO got empty, fill it up again */
 180                        if (priv->msg_buf_remaining)
 181                                xlp9xx_i2c_fill_tx_fifo(priv);
 182                        else
 183                                xlp9xx_i2c_mask_irq(priv,
 184                                                    XLP9XX_I2C_INTEN_MFIFOEMTY);
 185                }
 186        } else {
 187                if (status & (XLP9XX_I2C_INTEN_DATADONE |
 188                              XLP9XX_I2C_INTEN_MFIFOHI)) {
 189                        /* data is in FIFO, read it */
 190                        if (priv->msg_buf_remaining)
 191                                xlp9xx_i2c_drain_rx_fifo(priv);
 192                }
 193        }
 194
 195        /* Transfer complete */
 196        if (status & XLP9XX_I2C_INTEN_DATADONE)
 197                goto xfer_done;
 198
 199        return IRQ_HANDLED;
 200
 201xfer_done:
 202        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
 203        complete(&priv->msg_complete);
 204        return IRQ_HANDLED;
 205}
 206
 207static int xlp9xx_i2c_init(struct xlp9xx_i2c_dev *priv)
 208{
 209        u32 prescale;
 210
 211        /*
 212         * The controller uses 5 * SCL clock internally.
 213         * So prescale value should be divided by 5.
 214         */
 215        prescale = DIV_ROUND_UP(XLP9XX_I2C_IP_CLK_FREQ, priv->clk_hz);
 216        prescale = ((prescale - 8) / 5) - 1;
 217        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_RST);
 218        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, XLP9XX_I2C_CTRL_EN |
 219                             XLP9XX_I2C_CTRL_MASTER);
 220        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_DIV, prescale);
 221        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
 222
 223        return 0;
 224}
 225
 226static int xlp9xx_i2c_xfer_msg(struct xlp9xx_i2c_dev *priv, struct i2c_msg *msg,
 227                               int last_msg)
 228{
 229        unsigned long timeleft;
 230        u32 intr_mask, cmd, val;
 231
 232        priv->msg_buf = msg->buf;
 233        priv->msg_buf_remaining = priv->msg_len = msg->len;
 234        priv->msg_err = 0;
 235        priv->msg_read = (msg->flags & I2C_M_RD);
 236        reinit_completion(&priv->msg_complete);
 237
 238        /* Reset FIFO */
 239        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_MFIFOCTRL,
 240                             XLP9XX_I2C_MFIFOCTRL_RST);
 241
 242        /* set FIFO threshold if reading */
 243        if (priv->msg_read)
 244                xlp9xx_i2c_update_rx_fifo_thres(priv);
 245
 246        /* set slave addr */
 247        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_SLAVEADDR,
 248                             (msg->addr << XLP9XX_I2C_SLAVEADDR_ADDR_SHIFT) |
 249                             (priv->msg_read ? XLP9XX_I2C_SLAVEADDR_RW : 0));
 250
 251        /* Build control word for transfer */
 252        val = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_CTRL);
 253        if (!priv->msg_read)
 254                val &= ~XLP9XX_I2C_CTRL_FIFORD;
 255        else
 256                val |= XLP9XX_I2C_CTRL_FIFORD;  /* read */
 257
 258        if (msg->flags & I2C_M_TEN)
 259                val |= XLP9XX_I2C_CTRL_ADDMODE; /* 10-bit address mode*/
 260        else
 261                val &= ~XLP9XX_I2C_CTRL_ADDMODE;
 262
 263        /* set data length to be transferred */
 264        val = (val & ~XLP9XX_I2C_CTRL_MCTLEN_MASK) |
 265              (msg->len << XLP9XX_I2C_CTRL_MCTLEN_SHIFT);
 266        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, val);
 267
 268        /* fill fifo during tx */
 269        if (!priv->msg_read)
 270                xlp9xx_i2c_fill_tx_fifo(priv);
 271
 272        /* set interrupt mask */
 273        intr_mask = (XLP9XX_I2C_INTEN_ARLOST | XLP9XX_I2C_INTEN_BUSERR |
 274                     XLP9XX_I2C_INTEN_NACKADDR | XLP9XX_I2C_INTEN_DATADONE);
 275
 276        if (priv->msg_read) {
 277                intr_mask |= XLP9XX_I2C_INTEN_MFIFOHI;
 278                if (msg->len == 0)
 279                        intr_mask |= XLP9XX_I2C_INTEN_SADDR;
 280        } else {
 281                if (msg->len == 0)
 282                        intr_mask |= XLP9XX_I2C_INTEN_SADDR;
 283                else
 284                        intr_mask |= XLP9XX_I2C_INTEN_MFIFOEMTY;
 285        }
 286        xlp9xx_i2c_unmask_irq(priv, intr_mask);
 287
 288        /* set cmd reg */
 289        cmd = XLP9XX_I2C_CMD_START;
 290        cmd |= (priv->msg_read ? XLP9XX_I2C_CMD_READ : XLP9XX_I2C_CMD_WRITE);
 291        if (last_msg)
 292                cmd |= XLP9XX_I2C_CMD_STOP;
 293
 294        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CMD, cmd);
 295
 296        timeleft = msecs_to_jiffies(XLP9XX_I2C_TIMEOUT_MS);
 297        timeleft = wait_for_completion_timeout(&priv->msg_complete, timeleft);
 298
 299        if (priv->msg_err) {
 300                dev_dbg(priv->dev, "transfer error %x!\n", priv->msg_err);
 301                if (priv->msg_err & XLP9XX_I2C_INTEN_BUSERR)
 302                        xlp9xx_i2c_init(priv);
 303                return -EIO;
 304        }
 305
 306        if (timeleft == 0) {
 307                dev_dbg(priv->dev, "i2c transfer timed out!\n");
 308                xlp9xx_i2c_init(priv);
 309                return -ETIMEDOUT;
 310        }
 311
 312        return 0;
 313}
 314
 315static int xlp9xx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 316                           int num)
 317{
 318        int i, ret;
 319        struct xlp9xx_i2c_dev *priv = i2c_get_adapdata(adap);
 320
 321        for (i = 0; i < num; i++) {
 322                ret = xlp9xx_i2c_xfer_msg(priv, &msgs[i], i == num - 1);
 323                if (ret != 0)
 324                        return ret;
 325        }
 326
 327        return num;
 328}
 329
 330static u32 xlp9xx_i2c_functionality(struct i2c_adapter *adapter)
 331{
 332        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C |
 333                I2C_FUNC_10BIT_ADDR;
 334}
 335
 336static struct i2c_algorithm xlp9xx_i2c_algo = {
 337        .master_xfer = xlp9xx_i2c_xfer,
 338        .functionality = xlp9xx_i2c_functionality,
 339};
 340
 341static int xlp9xx_i2c_get_frequency(struct platform_device *pdev,
 342                                    struct xlp9xx_i2c_dev *priv)
 343{
 344        struct device_node *np = pdev->dev.of_node;
 345        u32 freq;
 346        int err;
 347
 348        err = of_property_read_u32(np, "clock-frequency", &freq);
 349        if (err) {
 350                freq = XLP9XX_I2C_DEFAULT_FREQ;
 351                dev_dbg(&pdev->dev, "using default frequency %u\n", freq);
 352        } else if (freq == 0 || freq > XLP9XX_I2C_HIGH_FREQ) {
 353                dev_warn(&pdev->dev, "invalid frequency %u, using default\n",
 354                         freq);
 355                freq = XLP9XX_I2C_DEFAULT_FREQ;
 356        }
 357        priv->clk_hz = freq;
 358
 359        return 0;
 360}
 361
 362static int xlp9xx_i2c_probe(struct platform_device *pdev)
 363{
 364        struct xlp9xx_i2c_dev *priv;
 365        struct resource *res;
 366        int err = 0;
 367
 368        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 369        if (!priv)
 370                return -ENOMEM;
 371
 372        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 373        priv->base = devm_ioremap_resource(&pdev->dev, res);
 374        if (IS_ERR(priv->base))
 375                return PTR_ERR(priv->base);
 376
 377        priv->irq = platform_get_irq(pdev, 0);
 378        if (priv->irq <= 0) {
 379                dev_err(&pdev->dev, "invalid irq!\n");
 380                return priv->irq;
 381        }
 382
 383        xlp9xx_i2c_get_frequency(pdev, priv);
 384        xlp9xx_i2c_init(priv);
 385
 386        err = devm_request_irq(&pdev->dev, priv->irq, xlp9xx_i2c_isr, 0,
 387                               pdev->name, priv);
 388        if (err) {
 389                dev_err(&pdev->dev, "IRQ request failed!\n");
 390                return err;
 391        }
 392
 393        init_completion(&priv->msg_complete);
 394        priv->adapter.dev.parent = &pdev->dev;
 395        priv->adapter.algo = &xlp9xx_i2c_algo;
 396        priv->adapter.dev.of_node = pdev->dev.of_node;
 397        priv->dev = &pdev->dev;
 398
 399        snprintf(priv->adapter.name, sizeof(priv->adapter.name), "xlp9xx-i2c");
 400        i2c_set_adapdata(&priv->adapter, priv);
 401
 402        err = i2c_add_adapter(&priv->adapter);
 403        if (err) {
 404                dev_err(&pdev->dev, "failed to add I2C adapter!\n");
 405                return err;
 406        }
 407
 408        platform_set_drvdata(pdev, priv);
 409        dev_dbg(&pdev->dev, "I2C bus:%d added\n", priv->adapter.nr);
 410
 411        return 0;
 412}
 413
 414static int xlp9xx_i2c_remove(struct platform_device *pdev)
 415{
 416        struct xlp9xx_i2c_dev *priv;
 417
 418        priv = platform_get_drvdata(pdev);
 419        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_INTEN, 0);
 420        synchronize_irq(priv->irq);
 421        i2c_del_adapter(&priv->adapter);
 422        xlp9xx_write_i2c_reg(priv, XLP9XX_I2C_CTRL, 0);
 423
 424        return 0;
 425}
 426
 427static const struct of_device_id xlp9xx_i2c_of_match[] = {
 428        { .compatible = "netlogic,xlp980-i2c", },
 429        { /* sentinel */ },
 430};
 431
 432static struct platform_driver xlp9xx_i2c_driver = {
 433        .probe = xlp9xx_i2c_probe,
 434        .remove = xlp9xx_i2c_remove,
 435        .driver = {
 436                .name = "xlp9xx-i2c",
 437                .of_match_table = xlp9xx_i2c_of_match,
 438        },
 439};
 440
 441module_platform_driver(xlp9xx_i2c_driver);
 442
 443MODULE_AUTHOR("Subhendu Sekhar Behera <sbehera@broadcom.com>");
 444MODULE_DESCRIPTION("XLP9XX/5XX I2C Bus Controller Driver");
 445MODULE_LICENSE("GPL v2");
 446