linux/arch/ppc/boot/simple/iic.c
<<
>>
Prefs
   1/* Minimal support functions to read configuration from IIC EEPROMS
   2 * on MPC8xx boards.  Originally written for RPGC RPX-Lite.
   3 * Dan Malek (dmalek@jlc.net).
   4 */
   5#include <linux/types.h>
   6#include <asm/uaccess.h>
   7#include <asm/mpc8xx.h>
   8#include <asm/commproc.h>
   9
  10
  11/* IIC functions.
  12 * These are just the basic master read/write operations so we can
  13 * examine serial EEPROM.
  14 */
  15void    iic_read(uint devaddr, u_char *buf, uint offset, uint count);
  16
  17static  int     iic_init_done;
  18
  19static void
  20iic_init(void)
  21{
  22        volatile iic_t *iip;
  23        volatile i2c8xx_t *i2c;
  24        volatile cpm8xx_t       *cp;
  25        volatile immap_t        *immap;
  26        uint    dpaddr;
  27
  28        immap = (immap_t *)IMAP_ADDR;
  29        cp = (cpm8xx_t *)&(immap->im_cpm);
  30
  31        /* Reset the CPM.  This is necessary on the 860 processors
  32         * that may have started the SCC1 ethernet without relocating
  33         * the IIC.
  34         * This also stops the Ethernet in case we were loaded by a
  35         * BOOTP rom monitor.
  36         */
  37        cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
  38
  39        /* Wait for it.
  40        */
  41        while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
  42
  43        /* Remove any microcode patches.  We will install our own
  44         * later.
  45         */
  46        cp->cp_cpmcr1 = 0;
  47        cp->cp_cpmcr2 = 0;
  48        cp->cp_cpmcr3 = 0;
  49        cp->cp_cpmcr4 = 0;
  50        cp->cp_rccr = 0;
  51
  52        iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
  53        i2c = (i2c8xx_t *)&(immap->im_i2c);
  54
  55        /* Initialize Port B IIC pins.
  56        */
  57        cp->cp_pbpar |= 0x00000030;
  58        cp->cp_pbdir |= 0x00000030;
  59        cp->cp_pbodr |= 0x00000030;
  60
  61        /* Initialize the parameter ram.
  62        */
  63
  64        /* Allocate space for a two transmit and one receive buffer
  65         * descriptor in the DP ram.
  66         * For now, this address seems OK, but it may have to
  67         * change with newer versions of the firmware.
  68         */
  69        dpaddr = 0x0840;
  70
  71        /* Set up the IIC parameters in the parameter ram.
  72        */
  73        iip->iic_tbase = dpaddr;
  74        iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
  75
  76        iip->iic_tfcr = SMC_EB;
  77        iip->iic_rfcr = SMC_EB;
  78
  79        /* This should really be done by the reader/writer.
  80        */
  81        iip->iic_mrblr = 128;
  82
  83        /* Initialize Tx/Rx parameters.
  84        */
  85        cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
  86        while (cp->cp_cpcr & CPM_CR_FLG);
  87
  88        /* Select an arbitrary address.  Just make sure it is unique.
  89        */
  90        i2c->i2c_i2add = 0x34;
  91
  92        /* Make clock run maximum slow.
  93        */
  94        i2c->i2c_i2brg = 7;
  95
  96        /* Disable interrupts.
  97        */
  98        i2c->i2c_i2cmr = 0;
  99        i2c->i2c_i2cer = 0xff;
 100
 101        /* Enable SDMA.
 102        */
 103        immap->im_siu_conf.sc_sdcr = 1;
 104
 105        iic_init_done = 1;
 106}
 107
 108/* Read from IIC.
 109 * Caller provides device address, memory buffer, and byte count.
 110 */
 111static  u_char  iitemp[32];
 112
 113void
 114iic_read(uint devaddr, u_char *buf, uint offset, uint count)
 115{
 116        volatile iic_t          *iip;
 117        volatile i2c8xx_t       *i2c;
 118        volatile cbd_t          *tbdf, *rbdf;
 119        volatile cpm8xx_t       *cp;
 120        volatile immap_t        *immap;
 121        u_char                  *tb;
 122        uint                    temp;
 123
 124        /* If the interface has not been initialized, do that now.
 125        */
 126        if (!iic_init_done)
 127                iic_init();
 128
 129        immap = (immap_t *)IMAP_ADDR;
 130        cp = (cpm8xx_t *)&(immap->im_cpm);
 131
 132        iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
 133        i2c = (i2c8xx_t *)&(immap->im_i2c);
 134
 135        tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
 136        rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
 137
 138        /* Send a "dummy write" operation.  This is a write request with
 139         * only the offset sent, followed by another start condition.
 140         * This will ensure we start reading from the first location
 141         * of the EEPROM.
 142         */
 143        tb = iitemp;
 144        tb = (u_char *)(((uint)tb + 15) & ~15);
 145        tbdf->cbd_bufaddr = (int)tb;
 146        *tb = devaddr & 0xfe;   /* Device address */
 147        *(tb+1) = offset;               /* Offset */
 148        tbdf->cbd_datlen = 2;           /* Length */
 149        tbdf->cbd_sc =
 150              BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
 151
 152        i2c->i2c_i2mod = 1;     /* Enable */
 153        i2c->i2c_i2cer = 0xff;
 154        i2c->i2c_i2com = 0x81;  /* Start master */
 155
 156        /* Wait for IIC transfer.
 157        */
 158#if 0
 159        while ((i2c->i2c_i2cer & 3) == 0);
 160
 161        if (tbdf->cbd_sc & BD_SC_READY)
 162                printf("IIC ra complete but tbuf ready\n");
 163#else
 164        temp = 10000000;
 165        while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
 166                temp--;
 167#if 0
 168        /* We can't do this...there is no serial port yet!
 169        */
 170        if (temp == 0) {
 171                printf("Timeout reading EEPROM\n");
 172                return;
 173        }
 174#endif
 175#endif
 176        
 177        /* Chip errata, clear enable.
 178        */
 179        i2c->i2c_i2mod = 0;
 180
 181        /* To read, we need an empty buffer of the proper length.
 182         * All that is used is the first byte for address, the remainder
 183         * is just used for timing (and doesn't really have to exist).
 184         */
 185        tbdf->cbd_bufaddr = (int)tb;
 186        *tb = devaddr | 1;      /* Device address */
 187        rbdf->cbd_bufaddr = (uint)buf;          /* Desination buffer */
 188        tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;        /* Length */
 189        tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
 190        rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
 191
 192        /* Chip bug, set enable here.
 193        */
 194        i2c->i2c_i2mod = 1;     /* Enable */
 195        i2c->i2c_i2cer = 0xff;
 196        i2c->i2c_i2com = 0x81;  /* Start master */
 197
 198        /* Wait for IIC transfer.
 199        */
 200#if 0
 201        while ((i2c->i2c_i2cer & 1) == 0);
 202
 203        if (rbdf->cbd_sc & BD_SC_EMPTY)
 204                printf("IIC read complete but rbuf empty\n");
 205#else
 206        temp = 10000000;
 207        while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
 208                temp--;
 209#endif
 210        
 211        /* Chip errata, clear enable.
 212        */
 213        i2c->i2c_i2mod = 0;
 214}
 215