uboot/drivers/i2c/rcar_iic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Renesas RCar IIC driver
   4 *
   5 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
   6 *
   7 * Based on
   8 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
   9 * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
  10 */
  11
  12#include <common.h>
  13#include <clk.h>
  14#include <dm.h>
  15#include <i2c.h>
  16#include <asm/io.h>
  17#include <linux/bitops.h>
  18#include <linux/delay.h>
  19
  20struct rcar_iic_priv {
  21        void __iomem            *base;
  22        struct clk              clk;
  23        u8                      iccl;
  24        u8                      icch;
  25};
  26
  27#define RCAR_IIC_ICDR           0x00
  28#define RCAR_IIC_ICCR           0x04
  29#define RCAR_IIC_ICSR           0x08
  30#define RCAR_IIC_ICIC           0x0c
  31#define RCAR_IIC_ICCL           0x10
  32#define RCAR_IIC_ICCH           0x14
  33
  34/* ICCR */
  35#define RCAR_IIC_ICCR_ICE       BIT(7)
  36#define RCAR_IIC_ICCR_RACK      BIT(6)
  37#define RCAR_IIC_ICCR_RTS       BIT(4)
  38#define RCAR_IIC_ICCR_BUSY      BIT(2)
  39#define RCAR_IIC_ICCR_SCP       BIT(0)
  40
  41/* ICSR / ICIC */
  42#define RCAR_IC_BUSY            BIT(4)
  43#define RCAR_IC_TACK            BIT(2)
  44#define RCAR_IC_DTE             BIT(0)
  45
  46#define IRQ_WAIT 1000
  47
  48static void sh_irq_dte(struct udevice *dev)
  49{
  50        struct rcar_iic_priv *priv = dev_get_priv(dev);
  51        int i;
  52
  53        for (i = 0; i < IRQ_WAIT; i++) {
  54                if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
  55                        break;
  56                udelay(10);
  57        }
  58}
  59
  60static int sh_irq_dte_with_tack(struct udevice *dev)
  61{
  62        struct rcar_iic_priv *priv = dev_get_priv(dev);
  63        u8 icsr;
  64        int i;
  65
  66        for (i = 0; i < IRQ_WAIT; i++) {
  67                icsr = readb(priv->base + RCAR_IIC_ICSR);
  68                if (RCAR_IC_DTE & icsr)
  69                        break;
  70                if (RCAR_IC_TACK & icsr)
  71                        return -ETIMEDOUT;
  72                udelay(10);
  73        }
  74        return 0;
  75}
  76
  77static void sh_irq_busy(struct udevice *dev)
  78{
  79        struct rcar_iic_priv *priv = dev_get_priv(dev);
  80        int i;
  81
  82        for (i = 0; i < IRQ_WAIT; i++) {
  83                if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR)))
  84                        break;
  85                udelay(10);
  86        }
  87}
  88
  89static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read)
  90{
  91        struct rcar_iic_priv *priv = dev_get_priv(dev);
  92
  93        clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
  94        setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
  95
  96        writeb(priv->iccl, priv->base + RCAR_IIC_ICCL);
  97        writeb(priv->icch, priv->base + RCAR_IIC_ICCH);
  98        writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC);
  99
 100        writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY,
 101               priv->base + RCAR_IIC_ICCR);
 102        sh_irq_dte(dev);
 103
 104        clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK);
 105        writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR);
 106        return sh_irq_dte_with_tack(dev);
 107}
 108
 109static void rcar_iic_finish(struct udevice *dev)
 110{
 111        struct rcar_iic_priv *priv = dev_get_priv(dev);
 112
 113        writeb(0, priv->base + RCAR_IIC_ICSR);
 114        clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
 115}
 116
 117static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg)
 118{
 119        struct rcar_iic_priv *priv = dev_get_priv(dev);
 120        int i, ret = -EREMOTEIO;
 121
 122        if (rcar_iic_set_addr(dev, msg->addr, 1) != 0)
 123                goto err;
 124
 125        udelay(10);
 126
 127        writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
 128               priv->base + RCAR_IIC_ICCR);
 129
 130        for (i = 0; i < msg->len; i++) {
 131                if (sh_irq_dte_with_tack(dev) != 0)
 132                        goto err;
 133
 134                msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff;
 135
 136                if (msg->len - 1 == i) {
 137                        writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK,
 138                               priv->base + RCAR_IIC_ICCR);
 139                }
 140        }
 141
 142        sh_irq_busy(dev);
 143        ret = 0;
 144
 145err:
 146        rcar_iic_finish(dev);
 147        return ret;
 148}
 149
 150static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg)
 151{
 152        struct rcar_iic_priv *priv = dev_get_priv(dev);
 153        int i, ret = -EREMOTEIO;
 154
 155        if (rcar_iic_set_addr(dev, msg->addr, 0) != 0)
 156                goto err;
 157
 158        udelay(10);
 159
 160        for (i = 0; i < msg->len; i++) {
 161                writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR);
 162                if (sh_irq_dte_with_tack(dev) != 0)
 163                        goto err;
 164        }
 165
 166        if (msg->flags & I2C_M_STOP) {
 167                writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS,
 168                       priv->base + RCAR_IIC_ICCR);
 169                if (sh_irq_dte_with_tack(dev) != 0)
 170                        goto err;
 171        }
 172
 173        sh_irq_busy(dev);
 174        ret = 0;
 175
 176err:
 177        rcar_iic_finish(dev);
 178        return ret;
 179}
 180
 181static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
 182{
 183        int ret;
 184
 185        for (; nmsgs > 0; nmsgs--, msg++) {
 186                if (msg->flags & I2C_M_RD)
 187                        ret = rcar_iic_read_common(dev, msg);
 188                else
 189                        ret = rcar_iic_write_common(dev, msg);
 190
 191                if (ret)
 192                        return -EREMOTEIO;
 193        }
 194
 195        return ret;
 196}
 197
 198static int rcar_iic_set_speed(struct udevice *dev, uint speed)
 199{
 200        struct rcar_iic_priv *priv = dev_get_priv(dev);
 201        const unsigned int ratio_high = 4;
 202        const unsigned int ratio_low = 5;
 203        int clkrate, denom;
 204
 205        clkrate = clk_get_rate(&priv->clk);
 206        if (clkrate < 0)
 207                return clkrate;
 208
 209        /*
 210         * Calculate the value for ICCL and ICCH. From the data sheet:
 211         * iccl = (p-clock / transfer-rate) * (L / (L + H))
 212         * icch = (p clock / transfer rate) * (H / (L + H))
 213         * where L and H are the SCL low and high ratio.
 214         */
 215        denom = speed * (ratio_high + ratio_low);
 216        priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom);
 217        priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom);
 218
 219        return 0;
 220}
 221
 222static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags)
 223{
 224        struct rcar_iic_priv *priv = dev_get_priv(dev);
 225        int ret;
 226
 227        rcar_iic_set_addr(dev, addr, 1);
 228        writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
 229               priv->base + RCAR_IIC_ICCR);
 230        ret = sh_irq_dte_with_tack(dev);
 231        rcar_iic_finish(dev);
 232
 233        return ret;
 234}
 235
 236static int rcar_iic_probe(struct udevice *dev)
 237{
 238        struct rcar_iic_priv *priv = dev_get_priv(dev);
 239        int ret;
 240
 241        priv->base = dev_read_addr_ptr(dev);
 242
 243        ret = clk_get_by_index(dev, 0, &priv->clk);
 244        if (ret)
 245                return ret;
 246
 247        ret = clk_enable(&priv->clk);
 248        if (ret)
 249                return ret;
 250
 251        rcar_iic_finish(dev);
 252
 253        return rcar_iic_set_speed(dev, I2C_SPEED_STANDARD_RATE);
 254}
 255
 256static const struct dm_i2c_ops rcar_iic_ops = {
 257        .xfer           = rcar_iic_xfer,
 258        .probe_chip     = rcar_iic_probe_chip,
 259        .set_bus_speed  = rcar_iic_set_speed,
 260};
 261
 262static const struct udevice_id rcar_iic_ids[] = {
 263        { .compatible = "renesas,rmobile-iic" },
 264        { }
 265};
 266
 267U_BOOT_DRIVER(iic_rcar) = {
 268        .name           = "iic_rcar",
 269        .id             = UCLASS_I2C,
 270        .of_match       = rcar_iic_ids,
 271        .probe          = rcar_iic_probe,
 272        .priv_auto      = sizeof(struct rcar_iic_priv),
 273        .ops            = &rcar_iic_ops,
 274};
 275