uboot/arch/powerpc/cpu/mpc512x/i2c.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003 - 2009
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 *
   7 * Based on the MPC5xxx code.
   8 */
   9
  10#include <common.h>
  11#include <asm/io.h>
  12
  13DECLARE_GLOBAL_DATA_PTR;
  14
  15#ifdef CONFIG_HARD_I2C
  16
  17#include <i2c.h>
  18
  19/* by default set I2C bus 0 active */
  20static unsigned int bus_num __attribute__ ((section (".data"))) = 0;
  21
  22#define I2C_TIMEOUT     100
  23#define I2C_RETRIES     3
  24
  25struct mpc512x_i2c_tap {
  26        int scl2tap;
  27        int tap2tap;
  28};
  29
  30static int  mpc_reg_in(volatile u32 *reg);
  31static void mpc_reg_out(volatile u32 *reg, int val, int mask);
  32static int  wait_for_bb(void);
  33static int  wait_for_pin(int *status);
  34static int  do_address(uchar chip, char rdwr_flag);
  35static int  send_bytes(uchar chip, char *buf, int len);
  36static int  receive_bytes(uchar chip, char *buf, int len);
  37static int  mpc_get_fdr(int);
  38
  39static int mpc_reg_in (volatile u32 *reg)
  40{
  41        int ret = in_be32(reg) >> 24;
  42
  43        return ret;
  44}
  45
  46static void mpc_reg_out (volatile u32 *reg, int val, int mask)
  47{
  48        if (!mask) {
  49                out_be32(reg, val << 24);
  50        } else {
  51                clrsetbits_be32(reg, mask << 24, (val & mask) << 24);
  52        }
  53}
  54
  55static int wait_for_bb (void)
  56{
  57        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  58        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
  59        int timeout = I2C_TIMEOUT;
  60        int status;
  61
  62        status = mpc_reg_in (&regs->msr);
  63
  64        while (timeout-- && (status & I2C_BB)) {
  65                mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
  66                (void)mpc_reg_in(&regs->mdr);
  67                mpc_reg_out (&regs->mcr, 0, I2C_STA);
  68                mpc_reg_out (&regs->mcr, 0, 0);
  69                mpc_reg_out (&regs->mcr, I2C_EN, 0);
  70
  71                udelay (1000);
  72                status = mpc_reg_in (&regs->msr);
  73        }
  74
  75        return (status & I2C_BB);
  76}
  77
  78static int wait_for_pin (int *status)
  79{
  80        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
  81        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
  82        int timeout = I2C_TIMEOUT;
  83
  84        *status = mpc_reg_in (&regs->msr);
  85
  86        while (timeout-- && !(*status & I2C_IF)) {
  87                udelay (1000);
  88                *status = mpc_reg_in (&regs->msr);
  89        }
  90
  91        if (!(*status & I2C_IF)) {
  92                return -1;
  93        }
  94
  95        mpc_reg_out (&regs->msr, 0, I2C_IF);
  96
  97        return 0;
  98}
  99
 100static int do_address (uchar chip, char rdwr_flag)
 101{
 102        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 103        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 104        int status;
 105
 106        chip <<= 1;
 107
 108        if (rdwr_flag) {
 109                chip |= 1;
 110        }
 111
 112        mpc_reg_out (&regs->mcr, I2C_TX, I2C_TX);
 113        mpc_reg_out (&regs->mdr, chip, 0);
 114
 115        if (wait_for_pin (&status)) {
 116                return -2;
 117        }
 118
 119        if (status & I2C_RXAK) {
 120                return -3;
 121        }
 122
 123        return 0;
 124}
 125
 126static int send_bytes (uchar chip, char *buf, int len)
 127{
 128        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 129        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 130        int wrcount;
 131        int status;
 132
 133        for (wrcount = 0; wrcount < len; ++wrcount) {
 134
 135                mpc_reg_out (&regs->mdr, buf[wrcount], 0);
 136
 137                if (wait_for_pin (&status)) {
 138                        break;
 139                }
 140
 141                if (status & I2C_RXAK) {
 142                        break;
 143                }
 144
 145        }
 146
 147        return !(wrcount == len);
 148}
 149
 150static int receive_bytes (uchar chip, char *buf, int len)
 151{
 152        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 153        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 154        int dummy   = 1;
 155        int rdcount = 0;
 156        int status;
 157        int i;
 158
 159        mpc_reg_out (&regs->mcr, 0, I2C_TX);
 160
 161        for (i = 0; i < len; ++i) {
 162                buf[rdcount] = mpc_reg_in (&regs->mdr);
 163
 164                if (dummy) {
 165                        dummy = 0;
 166                } else {
 167                        rdcount++;
 168                }
 169
 170                if (wait_for_pin (&status)) {
 171                        return -4;
 172                }
 173        }
 174
 175        mpc_reg_out (&regs->mcr, I2C_TXAK, I2C_TXAK);
 176        buf[rdcount++] = mpc_reg_in (&regs->mdr);
 177
 178        if (wait_for_pin (&status)) {
 179                return -5;
 180        }
 181
 182        mpc_reg_out (&regs->mcr, 0, I2C_TXAK);
 183
 184        return 0;
 185}
 186
 187/**************** I2C API ****************/
 188
 189void i2c_init (int speed, int saddr)
 190{
 191        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 192        int i;
 193
 194        for (i = 0; i < I2C_BUS_CNT; i++){
 195                volatile i2c512x_dev_t *regs = &im->i2c.dev[i];
 196
 197                mpc_reg_out (&regs->mcr, 0, 0);
 198
 199                /* Set clock */
 200                mpc_reg_out (&regs->mfdr, mpc_get_fdr (speed), 0);
 201                mpc_reg_out (&regs->madr, saddr << 1, 0);
 202
 203                /* Enable module */
 204                mpc_reg_out (&regs->mcr, I2C_EN, I2C_INIT_MASK);
 205                mpc_reg_out (&regs->msr, 0, I2C_IF);
 206        }
 207
 208        /* Disable interrupts */
 209        out_be32(&im->i2c.icr, 0);
 210
 211        /* Turn off filters */
 212        out_be32(&im->i2c.mifr, 0);
 213}
 214
 215static int mpc_get_fdr (int speed)
 216{
 217        static int fdr = -1;
 218
 219        if (fdr == -1) {
 220                ulong best_speed = 0;
 221                ulong divider;
 222                ulong ips, scl;
 223                ulong bestmatch = 0xffffffffUL;
 224                int best_i = 0, best_j = 0, i, j;
 225                int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
 226                struct mpc512x_i2c_tap scltap[] = {
 227                        {4, 1},
 228                        {4, 2},
 229                        {6, 4},
 230                        {6, 8},
 231                        {14, 16},
 232                        {30, 32},
 233                        {62, 64},
 234                        {126, 128}
 235                };
 236
 237                ips = gd->arch.ips_clk;
 238                for (i = 7; i >= 0; i--) {
 239                        for (j = 7; j >= 0; j--) {
 240                                scl = 2 * (scltap[j].scl2tap +
 241                                           (SCL_Tap[i] - 1) * scltap[j].tap2tap
 242                                           + 2);
 243                                if (ips <= speed*scl) {
 244                                        if ((speed*scl - ips) < bestmatch) {
 245                                                bestmatch = speed*scl - ips;
 246                                                best_i = i;
 247                                                best_j = j;
 248                                                best_speed = ips/scl;
 249                                        }
 250                                }
 251                        }
 252                }
 253                divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
 254                if (gd->flags & GD_FLG_RELOC) {
 255                        fdr = divider;
 256                } else {
 257                        debug("%ld kHz, \n", best_speed / 1000);
 258                        return divider;
 259                }
 260        }
 261
 262        return fdr;
 263}
 264
 265int i2c_probe (uchar chip)
 266{
 267        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 268        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 269        int i;
 270
 271        for (i = 0; i < I2C_RETRIES; i++) {
 272                mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
 273
 274                if (! do_address (chip, 0)) {
 275                        mpc_reg_out (&regs->mcr, 0, I2C_STA);
 276                        udelay (500);
 277                        break;
 278                }
 279
 280                mpc_reg_out (&regs->mcr, 0, I2C_STA);
 281                udelay (500);
 282        }
 283
 284        return (i == I2C_RETRIES);
 285}
 286
 287int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len)
 288{
 289        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 290        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 291        char xaddr[4];
 292        int ret = -1;
 293
 294        xaddr[0] = (addr >> 24) & 0xFF;
 295        xaddr[1] = (addr >> 16) & 0xFF;
 296        xaddr[2] = (addr >>  8) & 0xFF;
 297        xaddr[3] =  addr        & 0xFF;
 298
 299        if (wait_for_bb ()) {
 300                printf ("i2c_read: bus is busy\n");
 301                goto Done;
 302        }
 303
 304        mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
 305        if (do_address (chip, 0)) {
 306                printf ("i2c_read: failed to address chip\n");
 307                goto Done;
 308        }
 309
 310        if (send_bytes (chip, &xaddr[4-alen], alen)) {
 311                printf ("i2c_read: send_bytes failed\n");
 312                goto Done;
 313        }
 314
 315        mpc_reg_out (&regs->mcr, I2C_RSTA, I2C_RSTA);
 316        if (do_address (chip, 1)) {
 317                printf ("i2c_read: failed to address chip\n");
 318                goto Done;
 319        }
 320
 321        if (receive_bytes (chip, (char *)buf, len)) {
 322                printf ("i2c_read: receive_bytes failed\n");
 323                goto Done;
 324        }
 325
 326        ret = 0;
 327Done:
 328        mpc_reg_out (&regs->mcr, 0, I2C_STA);
 329        return ret;
 330}
 331
 332int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len)
 333{
 334        volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
 335        volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
 336        char xaddr[4];
 337        int ret = -1;
 338
 339        xaddr[0] = (addr >> 24) & 0xFF;
 340        xaddr[1] = (addr >> 16) & 0xFF;
 341        xaddr[2] = (addr >>  8) & 0xFF;
 342        xaddr[3] =  addr        & 0xFF;
 343
 344        if (wait_for_bb ()) {
 345                printf ("i2c_write: bus is busy\n");
 346                goto Done;
 347        }
 348
 349        mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
 350        if (do_address (chip, 0)) {
 351                printf ("i2c_write: failed to address chip\n");
 352                goto Done;
 353        }
 354
 355        if (send_bytes (chip, &xaddr[4-alen], alen)) {
 356                printf ("i2c_write: send_bytes failed\n");
 357                goto Done;
 358        }
 359
 360        if (send_bytes (chip, (char *)buf, len)) {
 361                printf ("i2c_write: send_bytes failed\n");
 362                goto Done;
 363        }
 364
 365        ret = 0;
 366Done:
 367        mpc_reg_out (&regs->mcr, 0, I2C_STA);
 368        return ret;
 369}
 370
 371int i2c_set_bus_num (unsigned int bus)
 372{
 373        if (bus >= I2C_BUS_CNT) {
 374                return -1;
 375        }
 376        bus_num = bus;
 377
 378        return 0;
 379}
 380
 381unsigned int i2c_get_bus_num (void)
 382{
 383        return bus_num;
 384}
 385
 386#endif  /* CONFIG_HARD_I2C */
 387