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