uboot/cpu/mpc8xx/i2c.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
   4 *
   5 * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   6 * Marius Groeger <mgroeger@sysgo.de>
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 *
  26 * Back ported to the 8xx platform (from the 8260 platform) by
  27 * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
  28 */
  29
  30#include <common.h>
  31
  32#ifdef CONFIG_HARD_I2C
  33
  34#include <commproc.h>
  35#include <i2c.h>
  36#ifdef CONFIG_LWMON
  37#include <watchdog.h>
  38#endif
  39
  40DECLARE_GLOBAL_DATA_PTR;
  41
  42/* define to enable debug messages */
  43#undef  DEBUG_I2C
  44
  45/* tx/rx timeout (we need the i2c early, so we don't use get_timer()) */
  46#define TOUT_LOOP 1000000
  47
  48#define NUM_RX_BDS 4
  49#define NUM_TX_BDS 4
  50#define MAX_TX_SPACE 256
  51#define I2C_RXTX_LEN 128        /* maximum tx/rx buffer length */
  52
  53typedef struct I2C_BD
  54{
  55  unsigned short status;
  56  unsigned short length;
  57  unsigned char *addr;
  58} I2C_BD;
  59#define BD_I2C_TX_START 0x0400  /* special status for i2c: Start condition */
  60
  61#define BD_I2C_TX_CL    0x0001  /* collision error */
  62#define BD_I2C_TX_UN    0x0002  /* underflow error */
  63#define BD_I2C_TX_NAK   0x0004  /* no acknowledge error */
  64#define BD_I2C_TX_ERR   (BD_I2C_TX_NAK|BD_I2C_TX_UN|BD_I2C_TX_CL)
  65
  66#define BD_I2C_RX_ERR   BD_SC_OV
  67
  68typedef void (*i2c_ecb_t)(int, int);    /* error callback function */
  69
  70/* This structure keeps track of the bd and buffer space usage. */
  71typedef struct i2c_state {
  72        int             rx_idx;         /* index   to next free Rx BD */
  73        int             tx_idx;         /* index   to next free Tx BD */
  74        void            *rxbd;          /* pointer to next free Rx BD */
  75        void            *txbd;          /* pointer to next free Tx BD */
  76        int             tx_space;       /* number  of Tx bytes left   */
  77        unsigned char   *tx_buf;        /* pointer to free Tx area    */
  78        i2c_ecb_t       err_cb;         /* error callback function    */
  79} i2c_state_t;
  80
  81
  82/* flags for i2c_send() and i2c_receive() */
  83#define I2CF_ENABLE_SECONDARY   0x01    /* secondary_address is valid           */
  84#define I2CF_START_COND         0x02    /* tx: generate start condition         */
  85#define I2CF_STOP_COND          0x04    /* tx: generate stop  condition         */
  86
  87/* return codes */
  88#define I2CERR_NO_BUFFERS       0x01    /* no more BDs or buffer space          */
  89#define I2CERR_MSG_TOO_LONG     0x02    /* tried to send/receive to much data   */
  90#define I2CERR_TIMEOUT          0x03    /* timeout in i2c_doio()                */
  91#define I2CERR_QUEUE_EMPTY      0x04    /* i2c_doio called without send/receive */
  92
  93/* error callback flags */
  94#define I2CECB_RX_ERR           0x10    /* this is a receive error              */
  95#define     I2CECB_RX_ERR_OV    0x02    /* receive overrun error                */
  96#define     I2CECB_RX_MASK      0x0f    /* mask for error bits                  */
  97#define I2CECB_TX_ERR           0x20    /* this is a transmit error             */
  98#define     I2CECB_TX_CL        0x01    /* transmit collision error             */
  99#define     I2CECB_TX_UN        0x02    /* transmit underflow error             */
 100#define     I2CECB_TX_NAK       0x04    /* transmit no ack error                */
 101#define     I2CECB_TX_MASK      0x0f    /* mask for error bits                  */
 102#define I2CECB_TIMEOUT          0x40    /* this is a timeout error              */
 103
 104#ifdef DEBUG_I2C
 105#define PRINTD(x) printf x
 106#else
 107#define PRINTD(x)
 108#endif
 109
 110/*
 111 * Returns the best value of I2BRG to meet desired clock speed of I2C with
 112 * input parameters (clock speed, filter, and predivider value).
 113 * It returns computer speed value and the difference between it and desired
 114 * speed.
 115 */
 116static inline int
 117i2c_roundrate(int hz, int speed, int filter, int modval,
 118                int *brgval, int *totspeed)
 119{
 120    int moddiv = 1 << (5-(modval & 3)), brgdiv, div;
 121
 122    PRINTD(("\t[I2C] trying hz=%d, speed=%d, filter=%d, modval=%d\n",
 123        hz, speed, filter, modval));
 124
 125    div = moddiv * speed;
 126    brgdiv = (hz + div - 1) / div;
 127
 128    PRINTD(("\t\tmoddiv=%d, brgdiv=%d\n", moddiv, brgdiv));
 129
 130    *brgval = ((brgdiv + 1) / 2) - 3 - (2*filter);
 131
 132    if ((*brgval < 0) || (*brgval > 255)) {
 133          PRINTD(("\t\trejected brgval=%d\n", *brgval));
 134          return -1;
 135    }
 136
 137    brgdiv = 2 * (*brgval + 3 + (2 * filter));
 138    div = moddiv * brgdiv ;
 139    *totspeed = hz / div;
 140
 141    PRINTD(("\t\taccepted brgval=%d, totspeed=%d\n", *brgval, *totspeed));
 142
 143    return  0;
 144}
 145
 146/*
 147 * Sets the I2C clock predivider and divider to meet required clock speed.
 148 */
 149static int
 150i2c_setrate (int hz, int speed)
 151{
 152        immap_t         *immap = (immap_t *) CONFIG_SYS_IMMR;
 153        volatile i2c8xx_t *i2c = (i2c8xx_t *) & immap->im_i2c;
 154        int             brgval,
 155                        modval,         /* 0-3 */
 156                        bestspeed_diff = speed,
 157                        bestspeed_brgval = 0,
 158                        bestspeed_modval = 0,
 159                        bestspeed_filter = 0,
 160                        totspeed,
 161                        filter = 0;     /* Use this fixed value */
 162
 163        for (modval = 0; modval < 4; modval++) {
 164                if (i2c_roundrate(hz,speed,filter,modval,&brgval,&totspeed) == 0) {
 165                        int diff = speed - totspeed;
 166
 167                        if ((diff >= 0) && (diff < bestspeed_diff)) {
 168                                bestspeed_diff = diff;
 169                                bestspeed_modval = modval;
 170                                bestspeed_brgval = brgval;
 171                                bestspeed_filter = filter;
 172                        }
 173                }
 174        }
 175
 176        PRINTD (("[I2C] Best is:\n"));
 177        PRINTD (("[I2C] CPU=%dhz RATE=%d F=%d I2MOD=%08x I2BRG=%08x DIFF=%dhz\n",
 178                hz,
 179                speed,
 180                bestspeed_filter,
 181                bestspeed_modval,
 182                bestspeed_brgval,
 183                bestspeed_diff));
 184
 185        i2c->i2c_i2mod |= ((bestspeed_modval & 3) << 1) | (bestspeed_filter << 3);
 186        i2c->i2c_i2brg = bestspeed_brgval & 0xff;
 187
 188        PRINTD (("[I2C] i2mod=%08x i2brg=%08x\n", i2c->i2c_i2mod,
 189                         i2c->i2c_i2brg));
 190
 191        return 1;
 192}
 193
 194void
 195i2c_init(int speed, int slaveaddr)
 196{
 197        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
 198        volatile cpm8xx_t *cp = (cpm8xx_t *)&immap->im_cpm;
 199        volatile i2c8xx_t *i2c  = (i2c8xx_t *)&immap->im_i2c;
 200        volatile iic_t *iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
 201        ulong rbase, tbase;
 202        volatile I2C_BD *rxbd, *txbd;
 203        uint dpaddr;
 204
 205#ifdef CONFIG_SYS_I2C_INIT_BOARD
 206        /* call board specific i2c bus reset routine before accessing the   */
 207        /* environment, which might be in a chip on that bus. For details   */
 208        /* about this problem see doc/I2C_Edge_Conditions.                  */
 209        i2c_init_board();
 210#endif
 211
 212#ifdef CONFIG_SYS_I2C_UCODE_PATCH
 213        iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
 214#else
 215        /* Disable relocation */
 216        iip->iic_rpbase = 0;
 217#endif
 218
 219#ifdef CONFIG_SYS_ALLOC_DPRAM
 220        dpaddr = iip->iic_rbase;
 221        if (dpaddr == 0) {
 222            /* need to allocate dual port ram */
 223            dpaddr = dpram_alloc_align(
 224                (NUM_RX_BDS * sizeof(I2C_BD)) + (NUM_TX_BDS * sizeof(I2C_BD)) +
 225                MAX_TX_SPACE, 8);
 226        }
 227#else
 228        dpaddr = CPM_I2C_BASE;
 229#endif
 230
 231        /*
 232         * initialise data in dual port ram:
 233         *
 234         * dpaddr->rbase -> rx BD         (NUM_RX_BDS * sizeof(I2C_BD) bytes)
 235         *         tbase -> tx BD         (NUM_TX_BDS * sizeof(I2C_BD) bytes)
 236         *                  tx buffer     (MAX_TX_SPACE bytes)
 237         */
 238
 239        rbase = dpaddr;
 240        tbase = rbase + NUM_RX_BDS * sizeof(I2C_BD);
 241
 242        /* Initialize Port B I2C pins. */
 243        cp->cp_pbpar |= 0x00000030;
 244        cp->cp_pbdir |= 0x00000030;
 245        cp->cp_pbodr |= 0x00000030;
 246
 247        /* Disable interrupts */
 248        i2c->i2c_i2mod = 0x00;
 249        i2c->i2c_i2cmr = 0x00;
 250        i2c->i2c_i2cer = 0xff;
 251        i2c->i2c_i2add = slaveaddr;
 252
 253        /*
 254         * Set the I2C BRG Clock division factor from desired i2c rate
 255         * and current CPU rate (we assume sccr dfbgr field is 0;
 256         * divide BRGCLK by 1)
 257         */
 258        PRINTD(("[I2C] Setting rate...\n"));
 259        i2c_setrate (gd->cpu_clk, CONFIG_SYS_I2C_SPEED) ;
 260
 261        /* Set I2C controller in master mode */
 262        i2c->i2c_i2com = 0x01;
 263
 264        /* Set SDMA bus arbitration level to 5 (SDCR) */
 265        immap->im_siu_conf.sc_sdcr = 0x0001 ;
 266
 267        /* Initialize Tx/Rx parameters */
 268        iip->iic_rbase = rbase;
 269        iip->iic_tbase = tbase;
 270        rxbd = (I2C_BD *)((unsigned char *)&cp->cp_dpmem[iip->iic_rbase]);
 271        txbd = (I2C_BD *)((unsigned char *)&cp->cp_dpmem[iip->iic_tbase]);
 272
 273        PRINTD(("[I2C] rbase = %04x\n", iip->iic_rbase));
 274        PRINTD(("[I2C] tbase = %04x\n", iip->iic_tbase));
 275        PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
 276        PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
 277
 278        /* Set big endian byte order */
 279        iip->iic_tfcr = 0x10;
 280        iip->iic_rfcr = 0x10;
 281
 282        /* Set maximum receive size. */
 283        iip->iic_mrblr = I2C_RXTX_LEN;
 284
 285#ifdef CONFIG_SYS_I2C_UCODE_PATCH
 286        /*
 287         *  Initialize required parameters if using microcode patch.
 288         */
 289        iip->iic_rbptr  = iip->iic_rbase;
 290        iip->iic_tbptr  = iip->iic_tbase;
 291        iip->iic_rstate = 0;
 292        iip->iic_tstate = 0;
 293#else
 294        cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
 295        do {
 296                __asm__ __volatile__ ("eieio");
 297        } while (cp->cp_cpcr & CPM_CR_FLG);
 298#endif
 299
 300        /* Clear events and interrupts */
 301        i2c->i2c_i2cer = 0xff;
 302        i2c->i2c_i2cmr = 0x00;
 303}
 304
 305static void
 306i2c_newio(i2c_state_t *state)
 307{
 308        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
 309        volatile cpm8xx_t *cp = (cpm8xx_t *)&immap->im_cpm;
 310        volatile iic_t *iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
 311
 312        PRINTD(("[I2C] i2c_newio\n"));
 313
 314#ifdef CONFIG_SYS_I2C_UCODE_PATCH
 315        iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
 316#endif
 317        state->rx_idx = 0;
 318        state->tx_idx = 0;
 319        state->rxbd = (void*)&cp->cp_dpmem[iip->iic_rbase];
 320        state->txbd = (void*)&cp->cp_dpmem[iip->iic_tbase];
 321        state->tx_space = MAX_TX_SPACE;
 322        state->tx_buf = (uchar*)state->txbd + NUM_TX_BDS * sizeof(I2C_BD);
 323        state->err_cb = NULL;
 324
 325        PRINTD(("[I2C] rxbd = %08x\n", (int)state->rxbd));
 326        PRINTD(("[I2C] txbd = %08x\n", (int)state->txbd));
 327        PRINTD(("[I2C] tx_buf = %08x\n", (int)state->tx_buf));
 328
 329        /* clear the buffer memory */
 330        memset((char *)state->tx_buf, 0, MAX_TX_SPACE);
 331}
 332
 333static int
 334i2c_send(i2c_state_t *state,
 335         unsigned char address,
 336         unsigned char secondary_address,
 337         unsigned int flags,
 338         unsigned short size,
 339         unsigned char *dataout)
 340{
 341        volatile I2C_BD *txbd;
 342        int i,j;
 343
 344        PRINTD(("[I2C] i2c_send add=%02d sec=%02d flag=%02d size=%d\n",
 345                        address, secondary_address, flags, size));
 346
 347        /* trying to send message larger than BD */
 348        if (size > I2C_RXTX_LEN)
 349          return I2CERR_MSG_TOO_LONG;
 350
 351        /* no more free bds */
 352        if (state->tx_idx >= NUM_TX_BDS || state->tx_space < (2 + size))
 353          return I2CERR_NO_BUFFERS;
 354
 355        txbd = (I2C_BD *)state->txbd;
 356        txbd->addr = state->tx_buf;
 357
 358        PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
 359
 360        if (flags & I2CF_START_COND) {
 361                PRINTD(("[I2C] Formatting addresses...\n"));
 362                if (flags & I2CF_ENABLE_SECONDARY) {
 363                        txbd->length = size + 2;  /* Length of msg + dest addr */
 364                        txbd->addr[0] = address << 1;
 365                        txbd->addr[1] = secondary_address;
 366                        i = 2;
 367                } else {
 368                        txbd->length = size + 1;  /* Length of msg + dest addr */
 369                        txbd->addr[0] = address << 1;  /* Write dest addr to BD */
 370                        i = 1;
 371                }
 372        } else {
 373                txbd->length = size;  /* Length of message */
 374                i = 0;
 375        }
 376
 377        /* set up txbd */
 378        txbd->status = BD_SC_READY;
 379        if (flags & I2CF_START_COND)
 380          txbd->status |= BD_I2C_TX_START;
 381        if (flags & I2CF_STOP_COND)
 382          txbd->status |= BD_SC_LAST | BD_SC_WRAP;
 383
 384        /* Copy data to send into buffer */
 385        PRINTD(("[I2C] copy data...\n"));
 386        for(j = 0; j < size; i++, j++)
 387          txbd->addr[i] = dataout[j];
 388
 389        PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
 390                   txbd->length,
 391                   txbd->status,
 392                   txbd->addr[0],
 393                   txbd->addr[1]));
 394
 395        /* advance state */
 396        state->tx_buf += txbd->length;
 397        state->tx_space -= txbd->length;
 398        state->tx_idx++;
 399        state->txbd = (void*)(txbd + 1);
 400
 401        return 0;
 402}
 403
 404static int
 405i2c_receive(i2c_state_t *state,
 406            unsigned char address,
 407            unsigned char secondary_address,
 408            unsigned int flags,
 409            unsigned short size_to_expect,
 410            unsigned char *datain)
 411{
 412        volatile I2C_BD *rxbd, *txbd;
 413
 414        PRINTD(("[I2C] i2c_receive %02d %02d %02d\n", address, secondary_address, flags));
 415
 416        /* Expected to receive too much */
 417        if (size_to_expect > I2C_RXTX_LEN)
 418          return I2CERR_MSG_TOO_LONG;
 419
 420        /* no more free bds */
 421        if (state->tx_idx >= NUM_TX_BDS || state->rx_idx >= NUM_RX_BDS
 422                 || state->tx_space < 2)
 423          return I2CERR_NO_BUFFERS;
 424
 425        rxbd = (I2C_BD *)state->rxbd;
 426        txbd = (I2C_BD *)state->txbd;
 427
 428        PRINTD(("[I2C] rxbd = %08x\n", (int)rxbd));
 429        PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
 430
 431        txbd->addr = state->tx_buf;
 432
 433        /* set up TXBD for destination address */
 434        if (flags & I2CF_ENABLE_SECONDARY) {
 435                txbd->length = 2;
 436                txbd->addr[0] = address << 1;   /* Write data */
 437                txbd->addr[1] = secondary_address;  /* Internal address */
 438                txbd->status = BD_SC_READY;
 439        } else {
 440                txbd->length = 1 + size_to_expect;
 441                txbd->addr[0] = (address << 1) | 0x01;
 442                txbd->status = BD_SC_READY;
 443                memset(&txbd->addr[1], 0, txbd->length);
 444        }
 445
 446        /* set up rxbd for reception */
 447        rxbd->status = BD_SC_EMPTY;
 448        rxbd->length = size_to_expect;
 449        rxbd->addr = datain;
 450
 451        txbd->status |= BD_I2C_TX_START;
 452        if (flags & I2CF_STOP_COND) {
 453                txbd->status |= BD_SC_LAST | BD_SC_WRAP;
 454                rxbd->status |= BD_SC_WRAP;
 455        }
 456
 457        PRINTD(("[I2C] txbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
 458                   txbd->length,
 459                   txbd->status,
 460                   txbd->addr[0],
 461                   txbd->addr[1]));
 462        PRINTD(("[I2C] rxbd: length=0x%04x status=0x%04x addr[0]=0x%02x addr[1]=0x%02x\n",
 463                   rxbd->length,
 464                   rxbd->status,
 465                   rxbd->addr[0],
 466                   rxbd->addr[1]));
 467
 468        /* advance state */
 469        state->tx_buf += txbd->length;
 470        state->tx_space -= txbd->length;
 471        state->tx_idx++;
 472        state->txbd = (void*)(txbd + 1);
 473        state->rx_idx++;
 474        state->rxbd = (void*)(rxbd + 1);
 475
 476        return 0;
 477}
 478
 479
 480static int i2c_doio(i2c_state_t *state)
 481{
 482        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
 483        volatile cpm8xx_t *cp = (cpm8xx_t *)&immap->im_cpm;
 484        volatile i2c8xx_t *i2c  = (i2c8xx_t *)&immap->im_i2c;
 485        volatile iic_t *iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
 486        volatile I2C_BD *txbd, *rxbd;
 487        volatile int j = 0;
 488
 489        PRINTD(("[I2C] i2c_doio\n"));
 490
 491#ifdef CONFIG_SYS_I2C_UCODE_PATCH
 492        iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
 493#endif
 494
 495        if (state->tx_idx <= 0 && state->rx_idx <= 0) {
 496                PRINTD(("[I2C] No I/O is queued\n"));
 497                return I2CERR_QUEUE_EMPTY;
 498        }
 499
 500        iip->iic_rbptr = iip->iic_rbase;
 501        iip->iic_tbptr = iip->iic_tbase;
 502
 503        /* Enable I2C */
 504        PRINTD(("[I2C] Enabling I2C...\n"));
 505        i2c->i2c_i2mod |= 0x01;
 506
 507        /* Begin transmission */
 508        i2c->i2c_i2com |= 0x80;
 509
 510        /* Loop until transmit & receive completed */
 511
 512        if (state->tx_idx > 0) {
 513                txbd = ((I2C_BD*)state->txbd) - 1;
 514                PRINTD(("[I2C] Transmitting...(txbd=0x%08lx)\n", (ulong)txbd));
 515                while((txbd->status & BD_SC_READY) && (j++ < TOUT_LOOP)) {
 516                        if (ctrlc()) {
 517                                return (-1);
 518                        }
 519                        __asm__ __volatile__ ("eieio");
 520                }
 521        }
 522
 523        if ((state->rx_idx > 0) && (j < TOUT_LOOP)) {
 524                rxbd = ((I2C_BD*)state->rxbd) - 1;
 525                PRINTD(("[I2C] Receiving...(rxbd=0x%08lx)\n", (ulong)rxbd));
 526                while((rxbd->status & BD_SC_EMPTY) && (j++ < TOUT_LOOP)) {
 527                        if (ctrlc()) {
 528                                return (-1);
 529                        }
 530                        __asm__ __volatile__ ("eieio");
 531                }
 532        }
 533
 534        /* Turn off I2C */
 535        i2c->i2c_i2mod &= ~0x01;
 536
 537        if (state->err_cb != NULL) {
 538                int n, i, b;
 539
 540                /*
 541                 * if we have an error callback function, look at the
 542                 * error bits in the bd status and pass them back
 543                 */
 544
 545                if ((n = state->tx_idx) > 0) {
 546                        for (i = 0; i < n; i++) {
 547                                txbd = ((I2C_BD*)state->txbd) - (n - i);
 548                                if ((b = txbd->status & BD_I2C_TX_ERR) != 0)
 549                                        (*state->err_cb)(I2CECB_TX_ERR|b, i);
 550                        }
 551                }
 552
 553                if ((n = state->rx_idx) > 0) {
 554                        for (i = 0; i < n; i++) {
 555                                rxbd = ((I2C_BD*)state->rxbd) - (n - i);
 556                                if ((b = rxbd->status & BD_I2C_RX_ERR) != 0)
 557                                        (*state->err_cb)(I2CECB_RX_ERR|b, i);
 558                        }
 559                }
 560
 561                if (j >= TOUT_LOOP)
 562                        (*state->err_cb)(I2CECB_TIMEOUT, 0);
 563        }
 564
 565        return (j >= TOUT_LOOP) ? I2CERR_TIMEOUT : 0;
 566}
 567
 568static int had_tx_nak;
 569
 570static void
 571i2c_test_callback(int flags, int xnum)
 572{
 573        if ((flags & I2CECB_TX_ERR) && (flags & I2CECB_TX_NAK))
 574                had_tx_nak = 1;
 575}
 576
 577int i2c_probe(uchar chip)
 578{
 579        i2c_state_t state;
 580        int rc;
 581        uchar buf[1];
 582
 583        i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 584
 585        i2c_newio(&state);
 586
 587        state.err_cb = i2c_test_callback;
 588        had_tx_nak = 0;
 589
 590        rc = i2c_receive(&state, chip, 0, I2CF_START_COND|I2CF_STOP_COND, 1, buf);
 591
 592        if (rc != 0)
 593                return (rc);
 594
 595        rc = i2c_doio(&state);
 596
 597        if ((rc != 0) && (rc != I2CERR_TIMEOUT))
 598                return (rc);
 599
 600        return (had_tx_nak);
 601}
 602
 603int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 604{
 605        i2c_state_t state;
 606        uchar xaddr[4];
 607        int rc;
 608
 609#ifdef CONFIG_LWMON
 610        WATCHDOG_RESET();
 611#endif
 612
 613        xaddr[0] = (addr >> 24) & 0xFF;
 614        xaddr[1] = (addr >> 16) & 0xFF;
 615        xaddr[2] = (addr >>  8) & 0xFF;
 616        xaddr[3] =  addr        & 0xFF;
 617
 618#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
 619        /*
 620         * EEPROM chips that implement "address overflow" are ones like
 621         * Catalyst 24WC04/08/16 which has 9/10/11 bits of address and the
 622         * extra bits end up in the "chip address" bit slots.  This makes
 623         * a 24WC08 (1Kbyte) chip look like four 256 byte chips.
 624         *
 625         * Note that we consider the length of the address field to still
 626         * be one byte because the extra address bits are hidden in the
 627         * chip address.
 628         */
 629         chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 630#endif
 631
 632        i2c_newio(&state);
 633
 634        rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
 635        if (rc != 0) {
 636                if (gd->have_console)
 637                        printf("i2c_read: i2c_send failed (%d)\n", rc);
 638                return 1;
 639        }
 640
 641        rc = i2c_receive(&state, chip, 0, I2CF_STOP_COND, len, buffer);
 642        if (rc != 0) {
 643                if (gd->have_console)
 644                        printf("i2c_read: i2c_receive failed (%d)\n", rc);
 645                return 1;
 646        }
 647
 648        rc = i2c_doio(&state);
 649        if (rc != 0) {
 650                if (gd->have_console)
 651                        printf("i2c_read: i2c_doio failed (%d)\n", rc);
 652                return 1;
 653        }
 654        return 0;
 655}
 656
 657int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 658{
 659        i2c_state_t state;
 660        uchar xaddr[4];
 661        int rc;
 662
 663        xaddr[0] = (addr >> 24) & 0xFF;
 664        xaddr[1] = (addr >> 16) & 0xFF;
 665        xaddr[2] = (addr >>  8) & 0xFF;
 666        xaddr[3] =  addr        & 0xFF;
 667
 668#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
 669        /*
 670         * EEPROM chips that implement "address overflow" are ones like
 671         * Catalyst 24WC04/08/16 which has 9/10/11 bits of address and the
 672         * extra bits end up in the "chip address" bit slots.  This makes
 673         * a 24WC08 (1Kbyte) chip look like four 256 byte chips.
 674         *
 675         * Note that we consider the length of the address field to still
 676         * be one byte because the extra address bits are hidden in the
 677         * chip address.
 678         */
 679         chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 680#endif
 681
 682        i2c_newio(&state);
 683
 684        rc = i2c_send(&state, chip, 0, I2CF_START_COND, alen, &xaddr[4-alen]);
 685        if (rc != 0) {
 686                if (gd->have_console)
 687                        printf("i2c_write: first i2c_send failed (%d)\n", rc);
 688                return 1;
 689        }
 690
 691        rc = i2c_send(&state, 0, 0, I2CF_STOP_COND, len, buffer);
 692        if (rc != 0) {
 693                if (gd->have_console)
 694                        printf("i2c_write: second i2c_send failed (%d)\n", rc);
 695                return 1;
 696        }
 697
 698        rc = i2c_doio(&state);
 699        if (rc != 0) {
 700                if (gd->have_console)
 701                        printf("i2c_write: i2c_doio failed (%d)\n", rc);
 702                return 1;
 703        }
 704        return 0;
 705}
 706
 707#endif  /* CONFIG_HARD_I2C */
 708