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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* -*- linux-c -*- */
  2. /* plx9050.c 
  3.  * Copyright (C) 2000 by Francois Wautier
  4.  * based on code from Bjorn Davis
  5.  * 
  6.  * Read and write command for the eprom attached to
  7.  * the PLX9050 
  8.  */
  9. /* Modifications and extensions
  10.  * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
  11.  *
  12.  * This program is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU General Public License
  14.  * as published by the Free Software Foundation; either version
  15.  * 2 of the License, or (at your option) any later version.
  16.  **/
  17. /* We handle PCI devices */
  18. #include <linux/pci.h>      
  19. /* We need to use ioremap */ 
  20. #include <asm/io.h>
  21. #include <linux/delay.h>
  22. /* Joachim Martillo modified this file */
  23. /* so that it had no dependencies on specific */
  24. /* Aurora adapter card or ESSC* structures*/
  25. /* The original file use TRUE for 1 and */
  26. /* FALSE for 0.  This convention conflicted */
  27. /* with other conventions throughout LINUX */
  28. /* also TRUE was used for setting an eprom */
  29. /* bit which is a slight semantic confusion. */
  30. /* I just used 0 and 1 */
  31. #include "Reg9050.h"
  32. /*
  33.  * Write a single bit to the serial EPROM interface.
  34.  */
  35. /* eprom_ctl is the */
  36. /* address of the 9050 */
  37. /* eprom control register */
  38. /* The original & operation */
  39. /* looks wrong.  I am surprised */
  40. /* the code worked */ 
  41. /* but I left the parentheses */
  42. /* because readl, writel etc */
  43. /* are macros*/
  44. /* The following function */
  45. /* assumes the proper bit */
  46. /* in the serial eprom */
  47. /* has already been selected*/
  48. /* The 9050 registers are 32 bits */
  49. /* hence the readl and writel */
  50. /* macros are invoked*/
  51. /* eprom_ctl must be a virtual */
  52. /* address*/
  53. static void plx9050_eprom_wbit(unsigned int* eprom_ctl, unsigned int val)
  54. {
  55. unsigned int  ctrl;
  56. /* get the initial value of the CTRL register */
  57. ctrl = readl((eprom_ctl));
  58. /* set or clear the data bit */
  59. if (val) 
  60. {
  61. ctrl |= PLX_CTRL_SEPWD;
  62. }
  63. else 
  64. {
  65. ctrl &= ~PLX_CTRL_SEPWD;
  66. }
  67. writel(ctrl, (eprom_ctl));
  68. udelay(1);
  69. /* Toggle the clock line */
  70. /* gets to the next bit */
  71. /* in the serial eprom */
  72. ctrl |= PLX_CTRL_SEPCLK;
  73. writel(ctrl, (eprom_ctl));
  74. udelay(1);
  75. /* Toggle the clock line */
  76. ctrl &= ~PLX_CTRL_SEPCLK;
  77. writel(ctrl, (eprom_ctl));
  78. udelay(1);
  79. }
  80. /*
  81.  * Run a serial EPROM command.  Returns 1 on success,
  82.  *  0 otherwise.
  83.  */
  84. /* This routine does the write of data but only sets up */
  85. /* for a read*/
  86. /* the write goes from most significant to least significant */
  87. unsigned int plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data)
  88. {
  89. unsigned int ctrl;
  90. unsigned char shiftb;
  91. unsigned short shiftw;
  92. unsigned int l, v;
  93. unsigned char ret;
  94. int i;
  95. ret = 1;
  96. shiftb = addr << (NM93_BITS_PER_BYTE - NM93_ADDRBITS); /* looks a bizarre way to mask out unused bits */
  97. ctrl = readl((eprom_ctl));
  98. ctrl &= ~(PLX_CTRL_SEPCLK | PLX_CTRL_SEPWD);
  99. writel(ctrl, (eprom_ctl));
  100. udelay(1);
  101. ctrl |= PLX_CTRL_SEPCS;
  102. writel(ctrl, (eprom_ctl));
  103. plx9050_eprom_wbit(eprom_ctl, 1);
  104. /*
  105.  * Clock out the command
  106.  */
  107. plx9050_eprom_wbit(eprom_ctl, (cmd & 0x02) != 0);
  108. plx9050_eprom_wbit(eprom_ctl, (cmd & 0x01) != 0);
  109. /*
  110.  * Clock out the address
  111.  */
  112. i = NM93_ADDRBITS;
  113. while (i != 0) /* here we get to the correct */
  114. /* short in the serial eprom*/
  115. {
  116. /* printf("Loop #1n"); */
  117. plx9050_eprom_wbit(eprom_ctl, (shiftb & 0x80) != 0);
  118. shiftb <<= 1;
  119. i--;
  120. }
  121. if (cmd == NM93_WRITECMD) /* now do the write if */
  122. /* a write is to be done*/
  123. {
  124. /* write data? */
  125. /*
  126.  * Clock out the data
  127.  */
  128. shiftw = data;
  129. i = NM93_BITS_PER_WORD;
  130. while (i != 0) {
  131. /* printf("Loop #2n"); */
  132. plx9050_eprom_wbit(eprom_ctl, (shiftw & 0x8000) != 0);
  133. shiftw <<= 1;
  134. i--;
  135. }
  136. /*
  137.  * De-assert chip select for a short period of time
  138.  */
  139. ctrl = readl((eprom_ctl));
  140. ctrl &= ~PLX_CTRL_SEPCS;
  141. writel(ctrl, (eprom_ctl));
  142. udelay(2);
  143. /*
  144.  * Re-assert chip select
  145.  */
  146. ctrl |= PLX_CTRL_SEPCS;
  147. writel(ctrl, (eprom_ctl));
  148. /*
  149.  * Wait for a low to high transition of DO
  150.  */
  151. i = 20000;
  152. ctrl = readl((eprom_ctl));
  153. l = (ctrl & PLX_CTRL_SEPRD);
  154. while (i != 0) 
  155. {
  156. /* printf("Loop #3n"); */
  157. ctrl = readl((eprom_ctl));
  158. v = (ctrl & PLX_CTRL_SEPRD);
  159. if (v != 0 && l == 0) 
  160. {
  161. break;
  162. }
  163. l = v;
  164. udelay(1);
  165. i--;
  166. }
  167. if (i == 0) 
  168. {
  169. printk("plx9050: eprom didn't go low to high");
  170. ret = 0;
  171. }
  172. }
  173. if (cmd != NM93_READCMD) /* not a read -- terminate */
  174. {
  175. /*
  176.  * De-assert the chip select.
  177.  */
  178. ctrl = readl((eprom_ctl));
  179. ctrl &= ~PLX_CTRL_SEPCS;
  180. writel(ctrl,(eprom_ctl));
  181. }
  182. /* otherwise left in read state */
  183. return ret;
  184. }
  185. /*
  186.  * Read the serial EPROM.  Returns 1 on success, 0 on failure.
  187.  * reads in shorts (i.e., 16 bits at a time.)
  188.  *
  189.  */
  190. unsigned int
  191. plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len)
  192. {
  193. unsigned short shiftw;
  194. int i;
  195. unsigned int ctrl;
  196. if (!plx9050_eprom_cmd(eprom_ctl, NM93_READCMD, addr, (unsigned short) 0x0)) /* set up read */
  197. {
  198. return 0;
  199. }
  200. ctrl = readl((eprom_ctl)); /* synchronize */
  201. while (len-- > 0) /* now read one word at a time */
  202. {
  203. shiftw = 0;
  204. ctrl &= ~PLX_CTRL_SEPCLK;
  205. writel(ctrl, (eprom_ctl));
  206. udelay(1);
  207. i = NM93_BITS_PER_WORD;
  208. while (1) /* now read one bit at a time, */
  209. /* left shifting each bit */
  210. {
  211. ctrl |= PLX_CTRL_SEPCLK;
  212. writel(ctrl, (eprom_ctl));
  213. udelay(1);
  214. ctrl = readl((eprom_ctl));
  215. if ((ctrl & PLX_CTRL_SEPRD) != 0) 
  216. {
  217. shiftw |= 0x1;
  218. }
  219. i--;
  220. if (i == 0) 
  221. {
  222. break;
  223. }
  224. shiftw <<= 1;
  225. ctrl &= ~PLX_CTRL_SEPCLK;
  226. writel(ctrl, (eprom_ctl));
  227. udelay(1);
  228. }
  229. *ptr++ = shiftw;
  230. }
  231. ctrl &= ~PLX_CTRL_SEPCS;
  232. writel(ctrl, (eprom_ctl));
  233. udelay(1);
  234. ctrl &= ~PLX_CTRL_SEPCLK;
  235. writel(ctrl, (eprom_ctl));
  236. return 1;
  237. }