uboot/drivers/i2c/s3c24x0_i2c.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <errno.h>
  10#include <dm.h>
  11#include <fdtdec.h>
  12#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
  13#include <asm/arch/clk.h>
  14#include <asm/arch/cpu.h>
  15#include <asm/arch/pinmux.h>
  16#else
  17#include <asm/arch/s3c24x0_cpu.h>
  18#endif
  19#include <asm/io.h>
  20#include <i2c.h>
  21#include "s3c24x0_i2c.h"
  22
  23#ifndef CONFIG_SYS_I2C_S3C24X0_SLAVE
  24#define SYS_I2C_S3C24X0_SLAVE_ADDR      0
  25#else
  26#define SYS_I2C_S3C24X0_SLAVE_ADDR      CONFIG_SYS_I2C_S3C24X0_SLAVE
  27#endif
  28
  29DECLARE_GLOBAL_DATA_PTR;
  30
  31/*
  32 * Wait til the byte transfer is completed.
  33 *
  34 * @param i2c- pointer to the appropriate i2c register bank.
  35 * @return I2C_OK, if transmission was ACKED
  36 *         I2C_NACK, if transmission was NACKED
  37 *         I2C_NOK_TIMEOUT, if transaction did not complete in I2C_TIMEOUT_MS
  38 */
  39
  40static int WaitForXfer(struct s3c24x0_i2c *i2c)
  41{
  42        ulong start_time = get_timer(0);
  43
  44        do {
  45                if (readl(&i2c->iiccon) & I2CCON_IRPND)
  46                        return (readl(&i2c->iicstat) & I2CSTAT_NACK) ?
  47                                I2C_NACK : I2C_OK;
  48        } while (get_timer(start_time) < I2C_TIMEOUT_MS);
  49
  50        return I2C_NOK_TOUT;
  51}
  52
  53static void read_write_byte(struct s3c24x0_i2c *i2c)
  54{
  55        clrbits_le32(&i2c->iiccon, I2CCON_IRPND);
  56}
  57
  58static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
  59{
  60        ulong freq, pres = 16, div;
  61#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
  62        freq = get_i2c_clk();
  63#else
  64        freq = get_PCLK();
  65#endif
  66        /* calculate prescaler and divisor values */
  67        if ((freq / pres / (16 + 1)) > speed)
  68                /* set prescaler to 512 */
  69                pres = 512;
  70
  71        div = 0;
  72        while ((freq / pres / (div + 1)) > speed)
  73                div++;
  74
  75        /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */
  76        writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon);
  77
  78        /* init to SLAVE REVEIVE and set slaveaddr */
  79        writel(0, &i2c->iicstat);
  80        writel(slaveadd, &i2c->iicadd);
  81        /* program Master Transmit (and implicit STOP) */
  82        writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
  83}
  84
  85static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
  86{
  87        struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
  88
  89        i2c_bus->clock_frequency = speed;
  90
  91        i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
  92                    SYS_I2C_S3C24X0_SLAVE_ADDR);
  93
  94        return 0;
  95}
  96
  97/*
  98 * cmd_type is 0 for write, 1 for read.
  99 *
 100 * addr_len can take any value from 0-255, it is only limited
 101 * by the char, we could make it larger if needed. If it is
 102 * 0 we skip the address write cycle.
 103 */
 104static int i2c_transfer(struct s3c24x0_i2c *i2c,
 105                        unsigned char cmd_type,
 106                        unsigned char chip,
 107                        unsigned char addr[],
 108                        unsigned char addr_len,
 109                        unsigned char data[],
 110                        unsigned short data_len)
 111{
 112        int i = 0, result;
 113        ulong start_time = get_timer(0);
 114
 115        if (data == 0 || data_len == 0) {
 116                /*Don't support data transfer of no length or to address 0 */
 117                debug("i2c_transfer: bad call\n");
 118                return I2C_NOK;
 119        }
 120
 121        while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
 122                if (get_timer(start_time) > I2C_TIMEOUT_MS)
 123                        return I2C_NOK_TOUT;
 124        }
 125
 126        writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon);
 127
 128        /* Get the slave chip address going */
 129        writel(chip, &i2c->iicds);
 130        if ((cmd_type == I2C_WRITE) || (addr && addr_len))
 131                writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
 132                       &i2c->iicstat);
 133        else
 134                writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
 135                       &i2c->iicstat);
 136
 137        /* Wait for chip address to transmit. */
 138        result = WaitForXfer(i2c);
 139        if (result != I2C_OK)
 140                goto bailout;
 141
 142        /* If register address needs to be transmitted - do it now. */
 143        if (addr && addr_len) {
 144                while ((i < addr_len) && (result == I2C_OK)) {
 145                        writel(addr[i++], &i2c->iicds);
 146                        read_write_byte(i2c);
 147                        result = WaitForXfer(i2c);
 148                }
 149                i = 0;
 150                if (result != I2C_OK)
 151                        goto bailout;
 152        }
 153
 154        switch (cmd_type) {
 155        case I2C_WRITE:
 156                while ((i < data_len) && (result == I2C_OK)) {
 157                        writel(data[i++], &i2c->iicds);
 158                        read_write_byte(i2c);
 159                        result = WaitForXfer(i2c);
 160                }
 161                break;
 162
 163        case I2C_READ:
 164                if (addr && addr_len) {
 165                        /*
 166                         * Register address has been sent, now send slave chip
 167                         * address again to start the actual read transaction.
 168                         */
 169                        writel(chip, &i2c->iicds);
 170
 171                        /* Generate a re-START. */
 172                        writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
 173                                &i2c->iicstat);
 174                        read_write_byte(i2c);
 175                        result = WaitForXfer(i2c);
 176
 177                        if (result != I2C_OK)
 178                                goto bailout;
 179                }
 180
 181                while ((i < data_len) && (result == I2C_OK)) {
 182                        /* disable ACK for final READ */
 183                        if (i == data_len - 1)
 184                                writel(readl(&i2c->iiccon)
 185                                       & ~I2CCON_ACKGEN,
 186                                       &i2c->iiccon);
 187                        read_write_byte(i2c);
 188                        result = WaitForXfer(i2c);
 189                        data[i++] = readl(&i2c->iicds);
 190                }
 191                if (result == I2C_NACK)
 192                        result = I2C_OK; /* Normal terminated read. */
 193                break;
 194
 195        default:
 196                debug("i2c_transfer: bad call\n");
 197                result = I2C_NOK;
 198                break;
 199        }
 200
 201bailout:
 202        /* Send STOP. */
 203        writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
 204        read_write_byte(i2c);
 205
 206        return result;
 207}
 208
 209static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
 210{
 211        struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 212        uchar buf[1];
 213        int ret;
 214
 215        buf[0] = 0;
 216
 217        /*
 218         * What is needed is to send the chip address and verify that the
 219         * address was <ACK>ed (i.e. there was a chip at that address which
 220         * drove the data line low).
 221         */
 222        ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, 0, 0, buf, 1);
 223
 224        return ret != I2C_OK;
 225}
 226
 227static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg,
 228                          int seq)
 229{
 230        struct s3c24x0_i2c *i2c = i2c_bus->regs;
 231        bool is_read = msg->flags & I2C_M_RD;
 232        uint status;
 233        uint addr;
 234        int ret, i;
 235
 236        if (!seq)
 237                setbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
 238
 239        /* Get the slave chip address going */
 240        addr = msg->addr << 1;
 241        writel(addr, &i2c->iicds);
 242        status = I2C_TXRX_ENA | I2C_START_STOP;
 243        if (is_read)
 244                status |= I2C_MODE_MR;
 245        else
 246                status |= I2C_MODE_MT;
 247        writel(status, &i2c->iicstat);
 248        if (seq)
 249                read_write_byte(i2c);
 250
 251        /* Wait for chip address to transmit */
 252        ret = WaitForXfer(i2c);
 253        if (ret)
 254                goto err;
 255
 256        if (is_read) {
 257                for (i = 0; !ret && i < msg->len; i++) {
 258                        /* disable ACK for final READ */
 259                        if (i == msg->len - 1)
 260                                clrbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
 261                        read_write_byte(i2c);
 262                        ret = WaitForXfer(i2c);
 263                        msg->buf[i] = readl(&i2c->iicds);
 264                }
 265                if (ret == I2C_NACK)
 266                        ret = I2C_OK; /* Normal terminated read */
 267        } else {
 268                for (i = 0; !ret && i < msg->len; i++) {
 269                        writel(msg->buf[i], &i2c->iicds);
 270                        read_write_byte(i2c);
 271                        ret = WaitForXfer(i2c);
 272                }
 273        }
 274
 275err:
 276        return ret;
 277}
 278
 279static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
 280                            int nmsgs)
 281{
 282        struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 283        struct s3c24x0_i2c *i2c = i2c_bus->regs;
 284        ulong start_time;
 285        int ret, i;
 286
 287        start_time = get_timer(0);
 288        while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
 289                if (get_timer(start_time) > I2C_TIMEOUT_MS) {
 290                        debug("Timeout\n");
 291                        return -ETIMEDOUT;
 292                }
 293        }
 294
 295        for (ret = 0, i = 0; !ret && i < nmsgs; i++)
 296                ret = s3c24x0_do_msg(i2c_bus, &msg[i], i);
 297
 298        /* Send STOP */
 299        writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
 300        read_write_byte(i2c);
 301
 302        return ret ? -EREMOTEIO : 0;
 303}
 304
 305static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
 306{
 307        const void *blob = gd->fdt_blob;
 308        struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
 309        int node;
 310
 311        node = dev_of_offset(dev);
 312
 313        i2c_bus->regs = (struct s3c24x0_i2c *)devfdt_get_addr(dev);
 314
 315        i2c_bus->id = pinmux_decode_periph_id(blob, node);
 316
 317        i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
 318                                                  "clock-frequency", 100000);
 319        i2c_bus->node = node;
 320        i2c_bus->bus_num = dev->seq;
 321
 322        exynos_pinmux_config(i2c_bus->id, 0);
 323
 324        i2c_bus->active = true;
 325
 326        return 0;
 327}
 328
 329static const struct dm_i2c_ops s3c_i2c_ops = {
 330        .xfer           = s3c24x0_i2c_xfer,
 331        .probe_chip     = s3c24x0_i2c_probe,
 332        .set_bus_speed  = s3c24x0_i2c_set_bus_speed,
 333};
 334
 335static const struct udevice_id s3c_i2c_ids[] = {
 336        { .compatible = "samsung,s3c2440-i2c" },
 337        { }
 338};
 339
 340U_BOOT_DRIVER(i2c_s3c) = {
 341        .name   = "i2c_s3c",
 342        .id     = UCLASS_I2C,
 343        .of_match = s3c_i2c_ids,
 344        .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
 345        .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
 346        .ops    = &s3c_i2c_ops,
 347};
 348