linux/drivers/i2c/busses/i2c-emev2.c
<<
>>
Prefs
   1/*
   2 * I2C driver for the Renesas EMEV2 SoC
   3 *
   4 * Copyright (C) 2015 Wolfram Sang <wsa@sang-engineering.com>
   5 * Copyright 2013 Codethink Ltd.
   6 * Copyright 2010-2015 Renesas Electronics Corporation
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2
  10 * as published by the Free Software Foundation.
  11 */
  12
  13#include <linux/clk.h>
  14#include <linux/completion.h>
  15#include <linux/device.h>
  16#include <linux/i2c.h>
  17#include <linux/init.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/kernel.h>
  21#include <linux/module.h>
  22#include <linux/of_device.h>
  23#include <linux/platform_device.h>
  24#include <linux/sched.h>
  25
  26/* I2C Registers */
  27#define I2C_OFS_IICACT0         0x00    /* start */
  28#define I2C_OFS_IIC0            0x04    /* shift */
  29#define I2C_OFS_IICC0           0x08    /* control */
  30#define I2C_OFS_SVA0            0x0c    /* slave address */
  31#define I2C_OFS_IICCL0          0x10    /* clock select */
  32#define I2C_OFS_IICX0           0x14    /* extension */
  33#define I2C_OFS_IICS0           0x18    /* status */
  34#define I2C_OFS_IICSE0          0x1c    /* status For emulation */
  35#define I2C_OFS_IICF0           0x20    /* IIC flag */
  36
  37/* I2C IICACT0 Masks */
  38#define I2C_BIT_IICE0           0x0001
  39
  40/* I2C IICC0 Masks */
  41#define I2C_BIT_LREL0           0x0040
  42#define I2C_BIT_WREL0           0x0020
  43#define I2C_BIT_SPIE0           0x0010
  44#define I2C_BIT_WTIM0           0x0008
  45#define I2C_BIT_ACKE0           0x0004
  46#define I2C_BIT_STT0            0x0002
  47#define I2C_BIT_SPT0            0x0001
  48
  49/* I2C IICCL0 Masks */
  50#define I2C_BIT_SMC0            0x0008
  51#define I2C_BIT_DFC0            0x0004
  52
  53/* I2C IICSE0 Masks */
  54#define I2C_BIT_MSTS0           0x0080
  55#define I2C_BIT_ALD0            0x0040
  56#define I2C_BIT_EXC0            0x0020
  57#define I2C_BIT_COI0            0x0010
  58#define I2C_BIT_TRC0            0x0008
  59#define I2C_BIT_ACKD0           0x0004
  60#define I2C_BIT_STD0            0x0002
  61#define I2C_BIT_SPD0            0x0001
  62
  63/* I2C IICF0 Masks */
  64#define I2C_BIT_STCF            0x0080
  65#define I2C_BIT_IICBSY          0x0040
  66#define I2C_BIT_STCEN           0x0002
  67#define I2C_BIT_IICRSV          0x0001
  68
  69struct em_i2c_device {
  70        void __iomem *base;
  71        struct i2c_adapter adap;
  72        struct completion msg_done;
  73        struct clk *sclk;
  74};
  75
  76static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg)
  77{
  78        writeb((readb(priv->base + reg) & ~clear) | set, priv->base + reg);
  79}
  80
  81static int em_i2c_wait_for_event(struct em_i2c_device *priv)
  82{
  83        unsigned long time_left;
  84        int status;
  85
  86        reinit_completion(&priv->msg_done);
  87
  88        time_left = wait_for_completion_timeout(&priv->msg_done, priv->adap.timeout);
  89
  90        if (!time_left)
  91                return -ETIMEDOUT;
  92
  93        status = readb(priv->base + I2C_OFS_IICSE0);
  94        return status & I2C_BIT_ALD0 ? -EAGAIN : status;
  95}
  96
  97static void em_i2c_stop(struct em_i2c_device *priv)
  98{
  99        /* Send Stop condition */
 100        em_clear_set_bit(priv, 0, I2C_BIT_SPT0 | I2C_BIT_SPIE0, I2C_OFS_IICC0);
 101
 102        /* Wait for stop condition */
 103        em_i2c_wait_for_event(priv);
 104}
 105
 106static void em_i2c_reset(struct i2c_adapter *adap)
 107{
 108        struct em_i2c_device *priv = i2c_get_adapdata(adap);
 109        int retr;
 110
 111        /* If I2C active */
 112        if (readb(priv->base + I2C_OFS_IICACT0) & I2C_BIT_IICE0) {
 113                /* Disable I2C operation */
 114                writeb(0, priv->base + I2C_OFS_IICACT0);
 115
 116                retr = 1000;
 117                while (readb(priv->base + I2C_OFS_IICACT0) == 1 && retr)
 118                        retr--;
 119                WARN_ON(retr == 0);
 120        }
 121
 122        /* Transfer mode set */
 123        writeb(I2C_BIT_DFC0, priv->base + I2C_OFS_IICCL0);
 124
 125        /* Can Issue start without detecting a stop, Reservation disabled. */
 126        writeb(I2C_BIT_STCEN | I2C_BIT_IICRSV, priv->base + I2C_OFS_IICF0);
 127
 128        /* I2C enable, 9 bit interrupt mode */
 129        writeb(I2C_BIT_WTIM0, priv->base + I2C_OFS_IICC0);
 130
 131        /* Enable I2C operation */
 132        writeb(I2C_BIT_IICE0, priv->base + I2C_OFS_IICACT0);
 133
 134        retr = 1000;
 135        while (readb(priv->base + I2C_OFS_IICACT0) == 0 && retr)
 136                retr--;
 137        WARN_ON(retr == 0);
 138}
 139
 140static int __em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
 141                                int stop)
 142{
 143        struct em_i2c_device *priv = i2c_get_adapdata(adap);
 144        int count, status, read = !!(msg->flags & I2C_M_RD);
 145
 146        /* Send start condition */
 147        em_clear_set_bit(priv, 0, I2C_BIT_ACKE0 | I2C_BIT_WTIM0, I2C_OFS_IICC0);
 148        em_clear_set_bit(priv, 0, I2C_BIT_STT0, I2C_OFS_IICC0);
 149
 150        /* Send slave address and R/W type */
 151        writeb((msg->addr << 1) | read, priv->base + I2C_OFS_IIC0);
 152
 153        /* Wait for transaction */
 154        status = em_i2c_wait_for_event(priv);
 155        if (status < 0)
 156                goto out_reset;
 157
 158        /* Received NACK (result of setting slave address and R/W) */
 159        if (!(status & I2C_BIT_ACKD0)) {
 160                em_i2c_stop(priv);
 161                goto out;
 162        }
 163
 164        /* Extra setup for read transactions */
 165        if (read) {
 166                /* 8 bit interrupt mode */
 167                em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_ACKE0, I2C_OFS_IICC0);
 168                em_clear_set_bit(priv, I2C_BIT_WTIM0, I2C_BIT_WREL0, I2C_OFS_IICC0);
 169
 170                /* Wait for transaction */
 171                status = em_i2c_wait_for_event(priv);
 172                if (status < 0)
 173                        goto out_reset;
 174        }
 175
 176        /* Send / receive data */
 177        for (count = 0; count < msg->len; count++) {
 178                if (read) { /* Read transaction */
 179                        msg->buf[count] = readb(priv->base + I2C_OFS_IIC0);
 180                        em_clear_set_bit(priv, 0, I2C_BIT_WREL0, I2C_OFS_IICC0);
 181
 182                } else { /* Write transaction */
 183                        /* Received NACK */
 184                        if (!(status & I2C_BIT_ACKD0)) {
 185                                em_i2c_stop(priv);
 186                                goto out;
 187                        }
 188
 189                        /* Write data */
 190                        writeb(msg->buf[count], priv->base + I2C_OFS_IIC0);
 191                }
 192
 193                /* Wait for R/W transaction */
 194                status = em_i2c_wait_for_event(priv);
 195                if (status < 0)
 196                        goto out_reset;
 197        }
 198
 199        if (stop)
 200                em_i2c_stop(priv);
 201
 202        return count;
 203
 204out_reset:
 205        em_i2c_reset(adap);
 206out:
 207        return status < 0 ? status : -ENXIO;
 208}
 209
 210static int em_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 211        int num)
 212{
 213        struct em_i2c_device *priv = i2c_get_adapdata(adap);
 214        int ret, i;
 215
 216        if (readb(priv->base + I2C_OFS_IICF0) & I2C_BIT_IICBSY)
 217                return -EAGAIN;
 218
 219        for (i = 0; i < num; i++) {
 220                ret = __em_i2c_xfer(adap, &msgs[i], (i == (num - 1)));
 221                if (ret < 0)
 222                        return ret;
 223        }
 224
 225        /* I2C transfer completed */
 226        return num;
 227}
 228
 229static irqreturn_t em_i2c_irq_handler(int this_irq, void *dev_id)
 230{
 231        struct em_i2c_device *priv = dev_id;
 232
 233        complete(&priv->msg_done);
 234        return IRQ_HANDLED;
 235}
 236
 237static u32 em_i2c_func(struct i2c_adapter *adap)
 238{
 239        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 240}
 241
 242static struct i2c_algorithm em_i2c_algo = {
 243        .master_xfer = em_i2c_xfer,
 244        .functionality = em_i2c_func,
 245};
 246
 247static int em_i2c_probe(struct platform_device *pdev)
 248{
 249        struct em_i2c_device *priv;
 250        struct resource *r;
 251        int irq, ret;
 252
 253        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 254        if (!priv)
 255                return -ENOMEM;
 256
 257        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 258        priv->base = devm_ioremap_resource(&pdev->dev, r);
 259        if (IS_ERR(priv->base))
 260                return PTR_ERR(priv->base);
 261
 262        strlcpy(priv->adap.name, "EMEV2 I2C", sizeof(priv->adap.name));
 263
 264        priv->sclk = devm_clk_get(&pdev->dev, "sclk");
 265        if (IS_ERR(priv->sclk))
 266                return PTR_ERR(priv->sclk);
 267
 268        clk_prepare_enable(priv->sclk);
 269
 270        priv->adap.timeout = msecs_to_jiffies(100);
 271        priv->adap.retries = 5;
 272        priv->adap.dev.parent = &pdev->dev;
 273        priv->adap.algo = &em_i2c_algo;
 274        priv->adap.owner = THIS_MODULE;
 275        priv->adap.dev.of_node = pdev->dev.of_node;
 276
 277        init_completion(&priv->msg_done);
 278
 279        platform_set_drvdata(pdev, priv);
 280        i2c_set_adapdata(&priv->adap, priv);
 281
 282        em_i2c_reset(&priv->adap);
 283
 284        irq = platform_get_irq(pdev, 0);
 285        ret = devm_request_irq(&pdev->dev, irq, em_i2c_irq_handler, 0,
 286                                "em_i2c", priv);
 287        if (ret)
 288                goto err_clk;
 289
 290        ret = i2c_add_adapter(&priv->adap);
 291
 292        if (ret)
 293                goto err_clk;
 294
 295        dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, irq);
 296
 297        return 0;
 298
 299err_clk:
 300        clk_disable_unprepare(priv->sclk);
 301        return ret;
 302}
 303
 304static int em_i2c_remove(struct platform_device *dev)
 305{
 306        struct em_i2c_device *priv = platform_get_drvdata(dev);
 307
 308        i2c_del_adapter(&priv->adap);
 309        clk_disable_unprepare(priv->sclk);
 310
 311        return 0;
 312}
 313
 314static const struct of_device_id em_i2c_ids[] = {
 315        { .compatible = "renesas,iic-emev2", },
 316        { }
 317};
 318
 319static struct platform_driver em_i2c_driver = {
 320        .probe = em_i2c_probe,
 321        .remove = em_i2c_remove,
 322        .driver = {
 323                .name = "em-i2c",
 324                .of_match_table = em_i2c_ids,
 325        }
 326};
 327module_platform_driver(em_i2c_driver);
 328
 329MODULE_DESCRIPTION("EMEV2 I2C bus driver");
 330MODULE_AUTHOR("Ian Molton and Wolfram Sang <wsa@sang-engineering.com>");
 331MODULE_LICENSE("GPL v2");
 332MODULE_DEVICE_TABLE(of, em_i2c_ids);
 333