iic.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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