common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / i2c / rcar_i2c.c
index 10b0f8bad470eaa9d79779387fe00d7e04f1ca54..5a902047bc920dd240b5c64091340f6e947edf60 100644 (file)
 #include <i2c.h>
 #include <asm/io.h>
 #include <wait_bit.h>
-
-#define RCAR_I2C_ICSCR                 0x00
-#define RCAR_I2C_ICMCR                 0x04
-#define RCAR_I2C_ICMCR_MDBS            BIT(7)
-#define RCAR_I2C_ICMCR_FSCL            BIT(6)
-#define RCAR_I2C_ICMCR_FSDA            BIT(5)
-#define RCAR_I2C_ICMCR_OBPC            BIT(4)
-#define RCAR_I2C_ICMCR_MIE             BIT(3)
+#include <dm/device_compat.h>
+#include <linux/delay.h>
+
+#define RCAR_I2C_ICSCR                 0x00 /* slave ctrl */
+#define RCAR_I2C_ICMCR                 0x04 /* master ctrl */
+#define RCAR_I2C_ICMCR_MDBS            BIT(7) /* non-fifo mode switch */
+#define RCAR_I2C_ICMCR_FSCL            BIT(6) /* override SCL pin */
+#define RCAR_I2C_ICMCR_FSDA            BIT(5) /* override SDA pin */
+#define RCAR_I2C_ICMCR_OBPC            BIT(4) /* override pins */
+#define RCAR_I2C_ICMCR_MIE             BIT(3) /* master if enable */
 #define RCAR_I2C_ICMCR_TSBE            BIT(2)
-#define RCAR_I2C_ICMCR_FSB             BIT(1)
-#define RCAR_I2C_ICMCR_ESG             BIT(0)
-#define RCAR_I2C_ICSSR                 0x08
-#define RCAR_I2C_ICMSR                 0x0c
+#define RCAR_I2C_ICMCR_FSB             BIT(1) /* force stop bit */
+#define RCAR_I2C_ICMCR_ESG             BIT(0) /* enable start bit gen */
+#define RCAR_I2C_ICSSR                 0x08 /* slave status */
+#define RCAR_I2C_ICMSR                 0x0c /* master status */
 #define RCAR_I2C_ICMSR_MASK            0x7f
-#define RCAR_I2C_ICMSR_MNR             BIT(6)
-#define RCAR_I2C_ICMSR_MAL             BIT(5)
-#define RCAR_I2C_ICMSR_MST             BIT(4)
+#define RCAR_I2C_ICMSR_MNR             BIT(6) /* Nack */
+#define RCAR_I2C_ICMSR_MAL             BIT(5) /* Arbitration lost */
+#define RCAR_I2C_ICMSR_MST             BIT(4) /* Stop */
 #define RCAR_I2C_ICMSR_MDE             BIT(3)
 #define RCAR_I2C_ICMSR_MDT             BIT(2)
 #define RCAR_I2C_ICMSR_MDR             BIT(1)
 #define RCAR_I2C_ICMSR_MAT             BIT(0)
-#define RCAR_I2C_ICSIER                        0x10
-#define RCAR_I2C_ICMIER                        0x14
-#define RCAR_I2C_ICCCR                 0x18
+#define RCAR_I2C_ICSIER                        0x10 /* slave irq enable */
+#define RCAR_I2C_ICMIER                        0x14 /* master irq enable */
+#define RCAR_I2C_ICCCR                 0x18 /* clock dividers */
 #define RCAR_I2C_ICCCR_SCGD_OFF                3
-#define RCAR_I2C_ICSAR                 0x1c
-#define RCAR_I2C_ICMAR                 0x20
-#define RCAR_I2C_ICRXD_ICTXD           0x24
+#define RCAR_I2C_ICSAR                 0x1c /* slave address */
+#define RCAR_I2C_ICMAR                 0x20 /* master address */
+#define RCAR_I2C_ICRXD_ICTXD           0x24 /* data port */
+/*
+ * First Bit Setup Cycle (Gen3).
+ * Defines 1st bit delay between SDA and SCL.
+ */
 #define RCAR_I2C_ICFBSCR               0x38
-#define RCAR_I2C_ICFBSCR_TCYC17                0x0f
+#define RCAR_I2C_ICFBSCR_TCYC17                0x0f /* 17*Tcyc */
+
 
 enum rcar_i2c_type {
        RCAR_I2C_TYPE_GEN2,
@@ -76,12 +83,13 @@ static int rcar_i2c_finish(struct udevice *dev)
        return ret;
 }
 
-static void rcar_i2c_recover(struct udevice *dev)
+static int rcar_i2c_recover(struct udevice *dev)
 {
        struct rcar_i2c_priv *priv = dev_get_priv(dev);
        u32 mcr = RCAR_I2C_ICMCR_MDBS | RCAR_I2C_ICMCR_OBPC;
        u32 mcra = mcr | RCAR_I2C_ICMCR_FSDA;
        int i;
+       u32 mstat;
 
        /* Send 9 SCL pulses */
        for (i = 0; i < 9; i++) {
@@ -101,6 +109,9 @@ static void rcar_i2c_recover(struct udevice *dev)
        udelay(5);
        writel(mcra | RCAR_I2C_ICMCR_FSCL, priv->base + RCAR_I2C_ICMCR);
        udelay(5);
+
+       mstat = readl(priv->base + RCAR_I2C_ICMSR);
+       return mstat & RCAR_I2C_ICMCR_FSDA ? -EBUSY : 0;
 }
 
 static int rcar_i2c_set_addr(struct udevice *dev, u8 chip, u8 read)
@@ -108,7 +119,6 @@ static int rcar_i2c_set_addr(struct udevice *dev, u8 chip, u8 read)
        struct rcar_i2c_priv *priv = dev_get_priv(dev);
        u32 mask = RCAR_I2C_ICMSR_MAT |
                   (read ? RCAR_I2C_ICMSR_MDR : RCAR_I2C_ICMSR_MDE);
-       u32 val;
        int ret;
 
        writel(0, priv->base + RCAR_I2C_ICMIER);
@@ -116,24 +126,22 @@ static int rcar_i2c_set_addr(struct udevice *dev, u8 chip, u8 read)
        writel(0, priv->base + RCAR_I2C_ICMSR);
        writel(priv->icccr, priv->base + RCAR_I2C_ICCCR);
 
-       if (priv->type == RCAR_I2C_TYPE_GEN3)
-               writel(RCAR_I2C_ICFBSCR_TCYC17, priv->base + RCAR_I2C_ICFBSCR);
-
+       /* Wait for the bus */
        ret = wait_for_bit_le32(priv->base + RCAR_I2C_ICMCR,
                                RCAR_I2C_ICMCR_FSDA, false, 2, true);
        if (ret) {
-               rcar_i2c_recover(dev);
-               val = readl(priv->base + RCAR_I2C_ICMSR);
-               if (val & RCAR_I2C_ICMCR_FSDA) {
+               if (rcar_i2c_recover(dev)) {
                        dev_err(dev, "Bus busy, aborting\n");
                        return ret;
                }
        }
 
        writel((chip << 1) | read, priv->base + RCAR_I2C_ICMAR);
-       writel(0, priv->base + RCAR_I2C_ICMSR);
+       /* Reset */
        writel(RCAR_I2C_ICMCR_MDBS | RCAR_I2C_ICMCR_MIE | RCAR_I2C_ICMCR_ESG,
               priv->base + RCAR_I2C_ICMCR);
+       /* Clear Status */
+       writel(0, priv->base + RCAR_I2C_ICMSR);
 
        ret = wait_for_bit_le32(priv->base + RCAR_I2C_ICMSR, mask,
                                true, 100, true);
@@ -153,10 +161,6 @@ static int rcar_i2c_read_common(struct udevice *dev, struct i2c_msg *msg)
        u32 icmcr = RCAR_I2C_ICMCR_MDBS | RCAR_I2C_ICMCR_MIE;
        int i, ret = -EREMOTEIO;
 
-       ret = rcar_i2c_set_addr(dev, msg->addr, 1);
-       if (ret)
-               return ret;
-
        for (i = 0; i < msg->len; i++) {
                if (msg->len - 1 == i)
                        icmcr |= RCAR_I2C_ICMCR_FSB;
@@ -183,10 +187,6 @@ static int rcar_i2c_write_common(struct udevice *dev, struct i2c_msg *msg)
        u32 icmcr = RCAR_I2C_ICMCR_MDBS | RCAR_I2C_ICMCR_MIE;
        int i, ret = -EREMOTEIO;
 
-       ret = rcar_i2c_set_addr(dev, msg->addr, 0);
-       if (ret)
-               return ret;
-
        for (i = 0; i < msg->len; i++) {
                writel(msg->buf[i], priv->base + RCAR_I2C_ICRXD_ICTXD);
                writel(icmcr, priv->base + RCAR_I2C_ICMCR);
@@ -210,16 +210,20 @@ static int rcar_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
        int ret;
 
        for (; nmsgs > 0; nmsgs--, msg++) {
+               ret = rcar_i2c_set_addr(dev, msg->addr, 1);
+               if (ret)
+                       return ret;
+
                if (msg->flags & I2C_M_RD)
                        ret = rcar_i2c_read_common(dev, msg);
                else
                        ret = rcar_i2c_write_common(dev, msg);
 
                if (ret)
-                       return -EREMOTEIO;
+                       return ret;
        }
 
-       return ret;
+       return 0;
 }
 
 static int rcar_i2c_probe_chip(struct udevice *dev, uint addr, uint flags)
@@ -304,6 +308,11 @@ scgd_find:
        priv->icccr = (scgd << RCAR_I2C_ICCCR_SCGD_OFF) | cdf;
        writel(priv->icccr, priv->base + RCAR_I2C_ICCCR);
 
+       if (priv->type == RCAR_I2C_TYPE_GEN3) {
+               /* Set SCL/SDA delay */
+               writel(RCAR_I2C_ICFBSCR_TCYC17, priv->base + RCAR_I2C_ICFBSCR);
+       }
+
        return 0;
 }
 
@@ -337,7 +346,7 @@ static int rcar_i2c_probe(struct udevice *dev)
        writel(0, priv->base + RCAR_I2C_ICMSR);
        writel(0, priv->base + RCAR_I2C_ICMAR);
 
-       ret = rcar_i2c_set_speed(dev, 100000);
+       ret = rcar_i2c_set_speed(dev, I2C_SPEED_STANDARD_RATE);
        if (ret)
                clk_disable(&priv->clk);