uboot/board/evb64260/i2c.c
<<
>>
Prefs
   1#include <common.h>
   2#include <mpc8xx.h>
   3#include <malloc.h>
   4#include <galileo/gt64260R.h>
   5#include <galileo/core.h>
   6
   7#define MAX_I2C_RETRYS      10
   8#define I2C_DELAY           1000  /* Should be at least the # of MHz of Tclk */
   9#undef  DEBUG_I2C
  10
  11#ifdef DEBUG_I2C
  12#define DP(x) x
  13#else
  14#define DP(x)
  15#endif
  16
  17/* Assuming that there is only one master on the bus (us) */
  18
  19static void
  20i2c_init(int speed, int slaveaddr)
  21{
  22        unsigned int n, m, freq, margin, power;
  23        unsigned int actualFreq, actualN=0, actualM=0;
  24        unsigned int control, status;
  25        unsigned int minMargin = 0xffffffff;
  26        unsigned int tclk = 125000000;
  27
  28        DP(puts("i2c_init\n"));
  29
  30        for(n = 0 ; n < 8 ; n++)
  31        {
  32                for(m = 0 ; m < 16 ; m++)
  33                {
  34                        power = 2<<n; /* power = 2^(n+1) */
  35                        freq = tclk/(10*(m+1)*power);
  36                        if (speed > freq)
  37                                margin = speed - freq;
  38                        else
  39                                margin = freq - speed;
  40                        if(margin < minMargin)
  41                        {
  42                                minMargin   = margin;
  43                                actualFreq  = freq;
  44                                actualN     = n;
  45                                actualM     = m;
  46                        }
  47                }
  48        }
  49
  50        DP(puts("setup i2c bus\n"));
  51
  52        /* Setup bus */
  53
  54        GT_REG_WRITE(I2C_SOFT_RESET, 0);
  55
  56        DP(puts("udelay...\n"));
  57
  58        udelay(I2C_DELAY);
  59
  60        DP(puts("set baudrate\n"));
  61
  62        GT_REG_WRITE(I2C_STATUS_BAUDE_RATE, (actualM << 3) | actualN);
  63        GT_REG_WRITE(I2C_CONTROL, (0x1 << 2) | (0x1 << 6));
  64
  65        udelay(I2C_DELAY * 10);
  66
  67        DP(puts("read control, baudrate\n"));
  68
  69        GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
  70        GT_REG_READ(I2C_CONTROL, &control);
  71}
  72
  73static uchar
  74i2c_start(void)
  75{
  76        unsigned int control, status;
  77        int count = 0;
  78
  79        DP(puts("i2c_start\n"));
  80
  81        /* Set the start bit */
  82
  83        GT_REG_READ(I2C_CONTROL, &control);
  84        control |= (0x1 << 5);
  85        GT_REG_WRITE(I2C_CONTROL, control);
  86
  87        GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
  88
  89        count = 0;
  90        while ((status & 0xff) != 0x08) {
  91                udelay(I2C_DELAY);
  92                if (count > 20) {
  93                        GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
  94                        return (status);
  95                }
  96                GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
  97                count++;
  98        }
  99
 100        return (0);
 101}
 102
 103static uchar
 104i2c_select_device(uchar dev_addr, uchar read, int ten_bit)
 105{
 106        unsigned int status, data, bits = 7;
 107        int count = 0;
 108
 109        DP(puts("i2c_select_device\n"));
 110
 111        /* Output slave address */
 112
 113        if (ten_bit) {
 114                bits = 10;
 115        }
 116
 117        data = (dev_addr << 1);
 118        /* set the read bit */
 119        data |= read;
 120        GT_REG_WRITE(I2C_DATA, data);
 121        /* assert the address */
 122        RESET_REG_BITS(I2C_CONTROL, BIT3);
 123
 124        udelay(I2C_DELAY);
 125
 126        GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 127        count = 0;
 128        while (((status & 0xff) != 0x40) && ((status & 0xff) != 0x18)) {
 129                udelay(I2C_DELAY);
 130                if (count > 20) {
 131                        GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
 132                        return(status);
 133                }
 134                GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 135                count++;
 136        }
 137
 138        if (bits == 10) {
 139                printf("10 bit I2C addressing not yet implemented\n");
 140                return (0xff);
 141        }
 142
 143        return (0);
 144}
 145
 146static uchar
 147i2c_get_data(uchar* return_data, int len) {
 148
 149        unsigned int data, status = 0;
 150        int count = 0;
 151
 152        DP(puts("i2c_get_data\n"));
 153
 154        while (len) {
 155
 156                /* Get and return the data */
 157
 158                RESET_REG_BITS(I2C_CONTROL, (0x1 << 3));
 159
 160                udelay(I2C_DELAY * 5);
 161
 162                GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 163                count++;
 164                while ((status & 0xff) != 0x50) {
 165                        udelay(I2C_DELAY);
 166                        if(count > 2) {
 167                                GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
 168                                return 0;
 169                        }
 170                        GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 171                        count++;
 172                }
 173                GT_REG_READ(I2C_DATA, &data);
 174                len--;
 175                *return_data = (uchar)data;
 176                return_data++;
 177        }
 178        RESET_REG_BITS(I2C_CONTROL, BIT2|BIT3);
 179        while ((status & 0xff) != 0x58) {
 180                udelay(I2C_DELAY);
 181                if(count > 200) {
 182                        GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
 183                        return (status);
 184                }
 185                GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 186                count++;
 187        }
 188        GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /* stop */
 189
 190        return (0);
 191}
 192
 193static uchar
 194i2c_write_data(unsigned int data, int len)
 195{
 196        unsigned int status;
 197        int count = 0;
 198
 199        DP(puts("i2c_write_data\n"));
 200
 201        if (len > 4)
 202                return -1;
 203
 204        while (len) {
 205                /* Set and assert the data */
 206
 207                GT_REG_WRITE(I2C_DATA, (unsigned int)data);
 208                RESET_REG_BITS(I2C_CONTROL, (0x1 << 3));
 209
 210                udelay(I2C_DELAY);
 211
 212                GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 213                count++;
 214                while ((status & 0xff) != 0x28) {
 215                        udelay(I2C_DELAY);
 216                        if(count > 20) {
 217                                GT_REG_WRITE(I2C_CONTROL, (0x1 << 4)); /*stop*/
 218                                return (status);
 219                        }
 220                        GT_REG_READ(I2C_STATUS_BAUDE_RATE, &status);
 221                        count++;
 222                }
 223                len--;
 224        }
 225        GT_REG_WRITE(I2C_CONTROL, (0x1 << 3) | (0x1 << 4));
 226        GT_REG_WRITE(I2C_CONTROL, (0x1 << 4));
 227
 228        udelay(I2C_DELAY * 10);
 229
 230        return (0);
 231}
 232
 233static uchar
 234i2c_set_dev_offset(uchar dev_addr, unsigned int offset, int ten_bit)
 235{
 236        uchar status;
 237
 238        DP(puts("i2c_set_dev_offset\n"));
 239
 240        status = i2c_select_device(dev_addr, 0, ten_bit);
 241        if (status) {
 242#ifdef DEBUG_I2C
 243                printf("Failed to select device setting offset: 0x%02x\n",
 244                       status);
 245#endif
 246                return status;
 247        }
 248
 249        status = i2c_write_data(offset, 1);
 250        if (status) {
 251#ifdef DEBUG_I2C
 252                printf("Failed to write data: 0x%02x\n", status);
 253#endif
 254                return status;
 255        }
 256
 257        return (0);
 258}
 259
 260uchar
 261i2c_read(uchar dev_addr, unsigned int offset, int len, uchar* data,
 262         int ten_bit)
 263{
 264        uchar status = 0;
 265        unsigned int i2cFreq = 400000;
 266
 267        DP(puts("i2c_read\n"));
 268
 269        i2c_init(i2cFreq,0);
 270
 271        status = i2c_start();
 272
 273        if (status) {
 274#ifdef DEBUG_I2C
 275                printf("Transaction start failed: 0x%02x\n", status);
 276#endif
 277                return status;
 278        }
 279
 280        status = i2c_set_dev_offset(dev_addr, 0, 0);
 281        if (status) {
 282#ifdef DEBUG_I2C
 283                printf("Failed to set offset: 0x%02x\n", status);
 284#endif
 285                return status;
 286        }
 287
 288        i2c_init(i2cFreq,0);
 289
 290        status = i2c_start();
 291        if (status) {
 292#ifdef DEBUG_I2C
 293                printf("Transaction restart failed: 0x%02x\n", status);
 294#endif
 295                return status;
 296        }
 297
 298        status = i2c_select_device(dev_addr, 1, ten_bit);
 299        if (status) {
 300#ifdef DEBUG_I2C
 301                printf("Address not acknowledged: 0x%02x\n", status);
 302#endif
 303                return status;
 304        }
 305
 306        status = i2c_get_data(data, len);
 307        if (status) {
 308#ifdef DEBUG_I2C
 309                printf("Data not recieved: 0x%02x\n", status);
 310#endif
 311                return status;
 312        }
 313
 314        return 0;
 315}
 316