/*

  1. * st16c554.c
  2. *
  3. * TWO ST16C554 driver for AMCC PPC405EP
  4. *
  5. * Author: Li Zhi You/Zhu jiang <godiscrazy@163.com>
  6. * Date  : $Date: 2007/11/27 11:07:04 $
  7. *
  8. * $Revision: 1.1V $
  9. *
  10. ST16C554APN
  11. 7.3728mhz
  12. 扩展芯片:2*ST16C554
  13. 可为系统增加8个串口,直接与PPC405EP总线连接,8位数据宽度
  14. 地址空间:占用系统PC3
  15. 地址从前到后分别对应每个UART0-7个寄存器
  16. UART0A:0xf0200020---0xf020027
  17. A2A1A0(ST16C554)
  18. 0xf0200020     0 0 0
  19. 0xf0200021     0 0 1
  20. 0xf0200022     0 1 0
  21. 0xf0200023     0 1 1
  22. 0xf0200024     1 0 0
  23. 0xf0200025     1 0 1
  24. 0xf0200026     1 1 0
  25. 0xf0200027     1 1 1
  26. UART0B:0xf0200028---0xf020002f
  27. UART0C:0xf0200030---0xf0200037
  28. UART0D:0xf0200038---0xf020003f
  29. UART0E:0xf0200040---0xf020047
  30. A2A1A0(ST16C554)
  31. 0xf0200040     0 0 0
  32. 0xf0200041     0 0 1
  33. 0xf0200042     0 1 0
  34. 0xf0200043     0 1 1
  35. 0xf0200044     1 0 0
  36. 0xf0200045     1 0 1
  37. 0xf0200046     1 1 0
  38. 0xf0200047     1 1 1
  39. UART0F:0xf0200048---0xf020004f
  40. UART0G:0xf0200050---0xf0200057
  41. UART0H:0xf0200058---0xf020005f
  42. 控制寄存器
  43. Line-control register(LCR)
  44. 0x03
  45. FIFO-control register(FCR)
  46. 0x02
  47. Modem-control register(MCR)
  48. 0x04
  49. Divisor-latch LSB(DLL)
  50. LCR(bit7=1)0x00
  51. Divisor-latch MSB(DLM)
  52. LCR(bit7=1)0x01
  53. Interrupt enable register(IER)
  54. 0x01
  55. 状态寄存器
  56. Line-status register(LSR)
  57. 0x05
  58. Modem-status register(MSR)
  59. 0x06
  60. 数据寄存器
  61. Receiver-buffer register(RBR)
  62. 0x00
  63. Transmitter-holding register(THR)
  64. 0x00
  65. */
  66. #include <linux/config.h>
  67. #include <linux/module.h>
  68. #include <linux/kernel.h>
  69. #include <linux/init.h>
  70. #include <linux/miscdevice.h>
  71. #include <linux/sched.h>
  72. #include <linux/delay.h>
  73. #include <linux/poll.h>
  74. #include <linux/spinlock.h>
  75. #include <linux/irq.h>
  76. #include <asm/processor.h>
  77. #include <platforms/ibm405ep.h>
  78. #include <platforms/ibm405lp.h>
  79. #include <linux/devfs_fs_kernel.h>
  80. #include <asm/io.h>
  81. #define ST0_A_READ  0
  82. #define ST0_B_READ  1
  83. #define ST0_C_READ  2
  84. #define ST0_D_READ  3
  85. #define ST1_A_READ  4
  86. #define ST1_B_READ  5
  87. #define ST1_C_READ  6
  88. #define ST1_D_READ  7
  89. #define ST0_A_WRITE 8
  90. #define ST0_B_WRITE 9
  91. #define ST0_C_WRITE 10
  92. #define ST0_D_WRITE 11
  93. #define ST1_A_WRITE 12
  94. #define ST1_B_WRITE 13
  95. #define ST1_C_WRITE 14
  96. #define ST1_D_WRITE 15
  97. #define ST_INIT 32
  98. typedef struct tagST_INIT{
  99. int nChn;
  100. int nBaud;
  101. unsigned char byMode;
  102. } myST_INIT;
  103. myST_INIT st0A_init;
  104. myST_INIT st0B_init;
  105. myST_INIT st0C_init;
  106. myST_INIT st0D_init;
  107. myST_INIT st0E_init;
  108. myST_INIT st0F_init;
  109. myST_INIT st0G_init;
  110. myST_INIT st0H_init;
  111. #define NONEPARITY  0x00
  112. #define ODDPARITY   0x08
  113. #define EVENPARITY  0x18
  114. #define DATA7BIT    0x80
  115. #define BAUDBASE    0x30                    /***4800bps->hex***/
  116. #define ST_COM_CNT  8
  117. #define ST_RECV_LEN 1600
  118. #define ST_SEND_LEN 160
  119. //以下定义与系统地址相关(与CPLD有关系)
  120. /*   68 mode interface
  121. HOW TO Select CHannel
  122. CS    A4     A3      CHANNEL
  123. 1      0/1   0/1       None
  124. 0       0      0           A
  125. 0       0      1           B
  126. 0       1      0           C
  127. 0       1      1           D
  128. Internal Register is Decoded by A2 A1 A0;
  129. 具体定义见程序开头的宏定义
  130. 两片ST16C554都接在405EP的PCS3上,
  131. 用A6和A5来区分ST16C554   */
  132. /*这里采用D、C、B、A及H、G、F、E的方式编号主要是为了满足板子
  133. 上串口定死的从左到右1——8顺序,并没有其它特殊含义*/
  134. #define  YC_PHY_BASE_ADRR           0xf0200000      //映射基地址空间
  135. #define  UcsAnd                     0xffffff07      // addr(7)='0',addr(6)='0',addr(5)='0',addr(4)='0',addr(3)='0'
  136. #define  Ucs_DChannel_Or            0x20            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='0'
  137. #define  Ucs_CChannel_Or            0x28            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='1'
  138. #define  Ucs_BChannel_Or            0x30            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='0'
  139. #define  Ucs_AChannel_Or            0x38            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='1'
  140. #define  Ucs_HChannel_Or            0x40            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='0'
  141. #define  Ucs_GChannel_Or            0x48            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='1'
  142. #define  Ucs_FChannel_Or            0x50            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='0'
  143. #define  Ucs_EChannel_Or            0x58            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='1'
  144. #define  YC_mul232_IRQ0   26  //中断号 IRQ1
  145. #define  YC_mul232_IRQ1   30  //中断号 IRQ5
  146. #define delay_counter 100000  //用于写函数,写入一个字符寄存器先延时,然后再写下一个字符
  147. typedef struct {
  148. int nAddress0;
  149. int nAddress1;
  150. int sInited;
  151. unsigned char *pbyBase0;
  152. //数据寄存器
  153. int RBR;//Receiver-buffer register              0
  154. int THR;//Transmitter-holding register          0
  155. //状态寄存器
  156. int LSR;//Line-status register                  5
  157. int MSR;//Modem-status register                 6
  158. //控制寄存器
  159. int LCR;//Line-control register                 3
  160. int FCR;//FIFO-control register                 2
  161. int MCR;//Modem-control register                4
  162. int DLL;//Divisor-latch LSB                     0
  163. int DLM;//Divisor-latch MSB                     1
  164. int IER;//Interrupt enable register             1
  165. //其它寄存器
  166. int SPR;//Scratchpad register                   7
  167. int IIR;//Interrupt identification register     2
  168. //串口数据接收缓冲区
  169. volatile short sRecvHead;
  170. volatile short sRecvTail;
  171. volatile unsigned char abyRecvData[ST_RECV_LEN];
  172. //串口数据发送缓冲区
  173. volatile short sSendHead;
  174. volatile short sSendTail;
  175. volatile unsigned char abySendData[ST_SEND_LEN];
  176. } ST_COM;
  177. static ST_COM st0A = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_AChannel_Or), 0};
  178. static ST_COM st0B = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_BChannel_Or), 0};
  179. static ST_COM st0C = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_CChannel_Or), 0};
  180. static ST_COM st0D = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_DChannel_Or), 0};
  181. static ST_COM st0E = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_EChannel_Or), 0};
  182. static ST_COM st0F = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_FChannel_Or), 0};
  183. static ST_COM st0G = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_GChannel_Or), 0};
  184. static ST_COM st0H = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_HChannel_Or), 0};
  185. #define DEVICE_NAME "ST16C554"
  186. #define DEVICE_MAJOR 233
  187. #define ST0A    0
  188. #define ST0B    1
  189. #define ST0C    2
  190. #define ST0D    3
  191. #define ST0E    4
  192. #define ST0F    5
  193. #define ST0G    6
  194. #define ST0H    7
  195. static int stMajor = 233;
  196. inline int get_ST0A_rxLen(void){
  197. if(st0A.sRecvHead==st0A.sRecvTail){
  198. return 0;
  199. }
  200. else if(st0A.sRecvTail>st0A.sRecvHead){
  201. return (st0A.sRecvTail-st0A.sRecvHead);
  202. }
  203. else{
  204. return ( ST_RECV_LEN-(st0A.sRecvHead-st0A.sRecvTail) );
  205. }
  206. }
  207. inline int get_ST0B_rxLen(void){
  208. if(st0B.sRecvHead==st0B.sRecvTail){
  209. return 0;
  210. }
  211. else if(st0B.sRecvTail>st0B.sRecvHead){
  212. return (st0B.sRecvTail-st0B.sRecvHead);
  213. }
  214. else{
  215. return ( ST_RECV_LEN-(st0B.sRecvHead-st0B.sRecvTail) );
  216. }
  217. }
  218. inline int get_ST0C_rxLen(void){
  219. if(st0C.sRecvHead==st0C.sRecvTail){
  220. return 0;
  221. }
  222. else if(st0C.sRecvTail>st0C.sRecvHead){
  223. return (st0C.sRecvTail-st0C.sRecvHead);
  224. }
  225. else{
  226. return ( ST_RECV_LEN-(st0C.sRecvHead-st0C.sRecvTail) );
  227. }
  228. }
  229. inline int get_ST0D_rxLen(void){
  230. if(st0D.sRecvHead==st0D.sRecvTail){
  231. return 0;
  232. }
  233. else if(st0D.sRecvTail>st0D.sRecvHead){
  234. return (st0D.sRecvTail-st0D.sRecvHead);
  235. }
  236. else{
  237. return ( ST_RECV_LEN-(st0D.sRecvHead-st0D.sRecvTail) );
  238. }
  239. }
  240. inline int get_ST0E_rxLen(void){
  241. if(st0E.sRecvHead==st0E.sRecvTail){
  242. return 0;
  243. }
  244. else if(st0E.sRecvTail>st0E.sRecvHead){
  245. return (st0E.sRecvTail-st0E.sRecvHead);
  246. }
  247. else{
  248. return ( ST_RECV_LEN-(st0E.sRecvHead-st0E.sRecvTail) );
  249. }
  250. }
  251. inline int get_ST0F_rxLen(void){
  252. if(st0F.sRecvHead==st0F.sRecvTail){
  253. return 0;
  254. }
  255. else if(st0F.sRecvTail>st0F.sRecvHead){
  256. return (st0F.sRecvTail-st0F.sRecvHead);
  257. }
  258. else{
  259. return ( ST_RECV_LEN-(st0F.sRecvHead-st0F.sRecvTail) );
  260. }
  261. }
  262. inline int get_ST0G_rxLen(void){
  263. if(st0G.sRecvHead==st0G.sRecvTail){
  264. return 0;
  265. }
  266. else if(st0G.sRecvTail>st0G.sRecvHead){
  267. return (st0G.sRecvTail-st0G.sRecvHead);
  268. }
  269. else{
  270. return ( ST_RECV_LEN-(st0G.sRecvHead-st0G.sRecvTail) );
  271. }
  272. }
  273. inline int get_ST0H_rxLen(void){
  274. if(st0H.sRecvHead==st0H.sRecvTail){
  275. return 0;
  276. }
  277. else if(st0H.sRecvTail>st0H.sRecvHead){
  278. return (st0H.sRecvTail-st0H.sRecvHead);
  279. }
  280. else{
  281. return ( ST_RECV_LEN-(st0H.sRecvHead-st0H.sRecvTail) );
  282. }
  283. }
  284. inline int get_ST0A_txLen(void){
  285. if(st0A.sSendHead==st0A.sSendTail){
  286. return 0;
  287. }
  288. else if(st0A.sSendTail>st0A.sSendHead){
  289. return (st0A.sSendTail-st0A.sSendHead);
  290. }
  291. else{
  292. return ( ST_SEND_LEN-(st0A.sSendHead-st0A.sSendTail) );
  293. }
  294. }
  295. inline int get_ST0B_txLen(void){
  296. if(st0B.sSendHead==st0B.sSendTail){
  297. return 0;
  298. }
  299. else if(st0B.sSendTail>st0B.sSendHead){
  300. return (st0B.sSendTail-st0B.sSendHead);
  301. }
  302. else{
  303. return ( ST_SEND_LEN-(st0B.sSendHead-st0B.sSendTail) );
  304. }
  305. }
  306. inline int get_ST0C_txLen(void){
  307. if(st0C.sSendHead==st0C.sSendTail){
  308. return 0;
  309. }
  310. else if(st0C.sSendTail>st0C.sSendHead){
  311. return (st0C.sSendTail-st0C.sSendHead);
  312. }
  313. else{
  314. return ( ST_SEND_LEN-(st0C.sSendHead-st0C.sSendTail) );
  315. }
  316. }
  317. inline int get_ST0D_txLen(void){
  318. if(st0D.sSendHead==st0D.sSendTail){
  319. return 0;
  320. }
  321. else if(st0D.sSendTail>st0D.sSendHead){
  322. return (st0D.sSendTail-st0D.sSendHead);
  323. }
  324. else{
  325. return ( ST_SEND_LEN-(st0D.sSendHead-st0D.sSendTail) );
  326. }
  327. }
  328. inline int get_ST0E_txLen(void){
  329. if(st0E.sSendHead==st0E.sSendTail){
  330. return 0;
  331. }
  332. else if(st0E.sSendTail>st0E.sSendHead){
  333. return (st0E.sSendTail-st0E.sSendHead);
  334. }
  335. else{
  336. return ( ST_SEND_LEN-(st0E.sSendHead-st0E.sSendTail) );
  337. }
  338. }
  339. inline int get_ST0F_txLen(void){
  340. if(st0F.sSendHead==st0F.sSendTail){
  341. return 0;
  342. }
  343. else if(st0F.sSendTail>st0F.sSendHead){
  344. return (st0F.sSendTail-st0F.sSendHead);
  345. }
  346. else{
  347. return ( ST_SEND_LEN-(st0F.sSendHead-st0F.sSendTail) );
  348. }
  349. }
  350. inline int get_ST0G_txLen(void){
  351. if(st0G.sSendHead==st0G.sSendTail){
  352. return 0;
  353. }
  354. else if(st0G.sSendTail>st0G.sSendHead){
  355. return (st0G.sSendTail-st0G.sSendHead);
  356. }
  357. else{
  358. return ( ST_SEND_LEN-(st0G.sSendHead-st0G.sSendTail) );
  359. }
  360. }
  361. inline int get_ST0H_txLen(void){
  362. if(st0H.sSendHead==st0H.sSendTail){
  363. return 0;
  364. }
  365. else if(st0H.sSendTail>st0H.sSendHead){
  366. return (st0H.sSendTail-st0H.sSendHead);
  367. }
  368. else{
  369. return ( ST_SEND_LEN-(st0H.sSendHead-st0H.sSendTail) );
  370. }
  371. }
  372. inline char st0aIsEmpty_rx(void){
  373. return (st0A.sRecvHead==st0A.sRecvTail ? 1 : 0);
  374. }
  375. inline char st0bIsEmpty_rx(void){
  376. return (st0B.sRecvHead==st0B.sRecvTail ? 1 : 0);
  377. }
  378. inline char st0cIsEmpty_rx(void){
  379. return (st0C.sRecvHead==st0C.sRecvTail ? 1 : 0);
  380. }
  381. inline char st0dIsEmpty_rx(void){
  382. return (st0D.sRecvHead==st0D.sRecvTail ? 1 : 0);
  383. }
  384. inline char st0eIsEmpty_rx(void){
  385. return (st0E.sRecvHead==st0E.sRecvTail ? 1 : 0);
  386. }
  387. inline char st0fIsEmpty_rx(void){
  388. return (st0F.sRecvHead==st0F.sRecvTail ? 1 : 0);
  389. }
  390. inline char st0gIsEmpty_rx(void){
  391. return (st0G.sRecvHead==st0G.sRecvTail ? 1 : 0);
  392. }
  393. inline char st0hIsEmpty_rx(void){
  394. return (st0H.sRecvHead==st0H.sRecvTail ? 1 : 0);
  395. }
  396. inline char st0aIsFull_rx(void){
  397. return (st0A.sRecvHead==(st0A.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  398. }
  399. inline char st0bIsFull_rx(void){
  400. return (st0B.sRecvHead==(st0B.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  401. }
  402. inline char st0cIsFull_rx(void){
  403. return (st0C.sRecvHead==(st0C.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  404. }
  405. inline char st0dIsFull_rx(void){
  406. return (st0D.sRecvHead==(st0D.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  407. }
  408. inline char st0eIsFull_rx(void){
  409. return (st0E.sRecvHead==(st0E.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  410. }
  411. inline char st0fIsFull_rx(void){
  412. return (st0F.sRecvHead==(st0F.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  413. }
  414. inline char st0gIsFull_rx(void){
  415. return (st0G.sRecvHead==(st0G.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  416. }
  417. inline char st0hIsFull_rx(void){
  418. return (st0H.sRecvHead==(st0H.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
  419. }
  420. inline char st0aIsEmpty_tx(void){
  421. return (st0A.sSendHead==st0A.sSendTail ? 1 : 0);
  422. }
  423. inline char st0bIsEmpty_tx(void){
  424. return (st0B.sSendHead==st0B.sSendTail ? 1 : 0);
  425. }
  426. inline char st0cIsEmpty_tx(void){
  427. return (st0C.sSendHead==st0C.sSendTail ? 1 : 0);
  428. }
  429. inline char st0dIsEmpty_tx(void){
  430. return (st0D.sSendHead==st0D.sSendTail ? 1 : 0);
  431. }
  432. inline char st0eIsEmpty_tx(void){
  433. return (st0E.sSendHead==st0E.sSendTail ? 1 : 0);
  434. }
  435. inline char st0fIsEmpty_tx(void){
  436. return (st0F.sSendHead==st0F.sSendTail ? 1 : 0);
  437. }
  438. inline char st0gIsEmpty_tx(void){
  439. return (st0G.sSendHead==st0G.sSendTail ? 1 : 0);
  440. }
  441. inline char st0hIsEmpty_tx(void){
  442. return (st0H.sSendHead==st0H.sSendTail ? 1 : 0);
  443. }
  444. inline char st0aIsFull_tx(void){
  445. return (st0A.sSendHead==(st0A.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  446. }
  447. inline char st0bIsFull_tx(void){
  448. return (st0B.sSendHead==(st0B.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  449. }
  450. inline char st0cIsFull_tx(void){
  451. return (st0C.sSendHead==(st0C.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  452. }
  453. inline char st0dIsFull_tx(void){
  454. return (st0D.sSendHead==(st0D.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  455. }
  456. inline char st0eIsFull_tx(void){
  457. return (st0E.sSendHead==(st0E.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  458. }
  459. inline char st0fIsFull_tx(void){
  460. return (st0F.sSendHead==(st0F.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  461. }
  462. inline char st0gIsFull_tx(void){
  463. return (st0G.sSendHead==(st0G.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  464. }
  465. inline char st0hIsFull_tx(void){
  466. return (st0H.sSendHead==(st0H.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
  467. }
  468. inline void pushST0ARX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  469. st0A.abyRecvData[st0A.sRecvTail] = byRx;
  470. if(!st0aIsFull_rx()){
  471. st0A.sRecvTail++;
  472. st0A.sRecvTail %= ST_RECV_LEN;
  473. }
  474. }
  475. inline void pushST0BRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  476. st0B.abyRecvData[st0B.sRecvTail] = byRx;
  477. if(!st0bIsFull_rx()){
  478. st0B.sRecvTail++;
  479. st0B.sRecvTail %= ST_RECV_LEN;
  480. }
  481. }
  482. inline void pushST0CRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  483. st0C.abyRecvData[st0C.sRecvTail] = byRx;
  484. if(!st0cIsFull_rx()){
  485. st0C.sRecvTail++;
  486. st0C.sRecvTail %= ST_RECV_LEN;
  487. }
  488. }
  489. inline void pushST0DRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  490. st0D.abyRecvData[st0D.sRecvTail] = byRx;
  491. if(!st0dIsFull_rx()){
  492. st0D.sRecvTail++;
  493. st0D.sRecvTail %= ST_RECV_LEN;
  494. }
  495. }
  496. inline void pushST0ERX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  497. st0E.abyRecvData[st0E.sRecvTail] = byRx;
  498. if(!st0eIsFull_rx()){
  499. st0E.sRecvTail++;
  500. st0E.sRecvTail %= ST_RECV_LEN;
  501. }
  502. }
  503. inline void pushST0FRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  504. st0F.abyRecvData[st0F.sRecvTail] = byRx;
  505. if(!st0fIsFull_rx()){
  506. st0F.sRecvTail++;
  507. st0F.sRecvTail %= ST_RECV_LEN;
  508. }
  509. }
  510. inline void pushST0GRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  511. st0G.abyRecvData[st0G.sRecvTail] = byRx;
  512. if(!st0gIsFull_rx()){
  513. st0G.sRecvTail++;
  514. st0G.sRecvTail %= ST_RECV_LEN;
  515. }
  516. }
  517. inline void pushST0HRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
  518. st0H.abyRecvData[st0H.sRecvTail] = byRx;
  519. if(!st0hIsFull_rx()){
  520. st0H.sRecvTail++;
  521. st0H.sRecvTail %= ST_RECV_LEN;
  522. }
  523. }
  524. inline unsigned char st0apopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  525. unsigned char byRet;
  526. byRet = st0A.abyRecvData[st0A.sRecvHead];
  527. if(!st0aIsEmpty_rx()){
  528. st0A.sRecvHead++;
  529. st0A.sRecvHead %= ST_RECV_LEN;
  530. }
  531. return byRet;
  532. }
  533. inline unsigned char st0bpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  534. unsigned char byRet;
  535. byRet = st0B.abyRecvData[st0B.sRecvHead];
  536. if(!st0bIsEmpty_rx()){
  537. st0B.sRecvHead++;
  538. st0B.sRecvHead %= ST_RECV_LEN;
  539. }
  540. return byRet;
  541. }
  542. inline unsigned char st0cpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  543. unsigned char byRet;
  544. byRet = st0C.abyRecvData[st0C.sRecvHead];
  545. if(!st0cIsEmpty_rx()){
  546. st0C.sRecvHead++;
  547. st0C.sRecvHead %= ST_RECV_LEN;
  548. }
  549. return byRet;
  550. }
  551. inline unsigned char st0dpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  552. unsigned char byRet;
  553. byRet = st0D.abyRecvData[st0D.sRecvHead];
  554. if(!st0dIsEmpty_rx()){
  555. st0D.sRecvHead++;
  556. st0D.sRecvHead %= ST_RECV_LEN;
  557. }
  558. return byRet;
  559. }
  560. inline unsigned char st0epopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  561. unsigned char byRet;
  562. byRet = st0E.abyRecvData[st0E.sRecvHead];
  563. if(!st0eIsEmpty_rx()){
  564. st0E.sRecvHead++;
  565. st0E.sRecvHead %= ST_RECV_LEN;
  566. }
  567. return byRet;
  568. }
  569. inline unsigned char st0fpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  570. unsigned char byRet;
  571. byRet = st0F.abyRecvData[st0F.sRecvHead];
  572. if(!st0fIsEmpty_rx()){
  573. st0F.sRecvHead++;
  574. st0F.sRecvHead %= ST_RECV_LEN;
  575. }
  576. return byRet;
  577. }
  578. inline unsigned char st0gpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  579. unsigned char byRet;
  580. byRet = st0G.abyRecvData[st0G.sRecvHead];
  581. if(!st0gIsEmpty_rx()){
  582. st0G.sRecvHead++;
  583. st0G.sRecvHead %= ST_RECV_LEN;
  584. }
  585. return byRet;
  586. }
  587. inline unsigned char st0hpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
  588. unsigned char byRet;
  589. byRet = st0H.abyRecvData[st0H.sRecvHead];
  590. if(!st0hIsEmpty_rx()){
  591. st0H.sRecvHead++;
  592. st0H.sRecvHead %= ST_RECV_LEN;
  593. }
  594. return byRet;
  595. }
  596. static void InitCommont(ST_COM *pst,int nBaud, unsigned char byMode)
  597. {
  598. volatile unsigned char byRx;
  599. int i;
  600. if(0 != pst->sInited){
  601. iounmap((void *) (pst->pbyBase0));
  602. }
  603. pst->pbyBase0 = (unsigned char *)ioremap_nocache(pst->nAddress0, 8);
  604. pst->RBR = (int)(pst->pbyBase0);
  605. pst->THR = (int)(pst->pbyBase0);
  606. pst->DLL = (int)(pst->pbyBase0);
  607. pst->DLM = (int)(pst->pbyBase0+1);
  608. pst->IER = (int)(pst->pbyBase0+1);
  609. pst->FCR = (int)(pst->pbyBase0+2);
  610. pst->IIR = (int)(pst->pbyBase0+2);
  611. pst->LCR = (int)(pst->pbyBase0+3);
  612. pst->MCR = (int)(pst->pbyBase0+4);
  613. pst->LSR = (int)(pst->pbyBase0+5);
  614. pst->MSR = (int)(pst->pbyBase0+6);
  615. pst->SPR = (int)(pst->pbyBase0+7);
  616. pst->sRecvHead = 0;
  617. pst->sRecvTail = 0;
  618. pst->sSendHead = 0;
  619. pst->sSendTail = 0;
  620. //IER
  621. //接收保持和中断允许
  622. *(volatile unsigned char *)(pst->IER) = 0x01;//0x05;
  623. //FIFO控制器
  624. //set FCR.FIFO允许,RXD复位,TXD复位,DMAmode=1,触发为14
  625. *(volatile unsigned char *)(pst->FCR) = 0xcf;
  626. for(i=0; i<100; i++);
  627. //set FCR.RXD复位,TXD复位
  628. *(volatile unsigned char *)(pst->FCR) = 0xc9;
  629. //Modem状态
  630. //set MCR.中断A-D开
  631. //*(volatile unsigned char *)(pst->MCR) = 0x08;  //change by zhujiang,our program not use this now
  632. if(byMode&0x80){
  633. *(volatile unsigned char *)(pst->LCR) = 0x82|(byMode&0x7f);//7 bit
  634. }
  635. else{
  636. //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器
  637. *(volatile unsigned char *)(pst->LCR) = 0x83|byMode;
  638. }
  639. /***************************************************************************
  640. **  SET st baudrate.
  641. BAUD RATE GENRATOR PROGRAMMING TABLE
  642. Output Baud Rate        DLM    DLL
  643. (7.3278MHz Clock)       (HEX)  (HEX)
  644. 200          09      00
  645. 1200         01     80
  646. 2400         00     C0
  647. 4800         00     60
  648. 9600         00     30
  649. 19.2K        00     18
  650. 38.4K        00     0C
  651. 76.8K        00     06
  652. 153.6K       00     03
  653. 230.4K       00     02
  654. 460.8K       00     01
  655. **
  656. ***************************************************************************/
  657. //  特殊寄存器已打开,设置BPS
  658. //  *(volatile unsigned char *)(pst->DLL) = BAUDBASE/nBaud;
  659. //  高位
  660. //  *(volatile unsigned char *)(pst->DLM) = 0x00;
  661. switch(nBaud){
  662. case 200:
  663. *(volatile unsigned char *)(pst->DLL) = 0x00;
  664. //高位
  665. *(volatile unsigned char *)(pst->DLM) = 0x09;
  666. break;
  667. case 1200:
  668. *(volatile unsigned char *)(pst->DLL) = 0x80;
  669. //高位
  670. *(volatile unsigned char *)(pst->DLM) = 0x01;
  671. break;
  672. case 2400:
  673. *(volatile unsigned char *)(pst->DLL) = 0xC0;
  674. //高位
  675. *(volatile unsigned char *)(pst->DLM) = 0x00;
  676. break;
  677. case 4800:
  678. *(volatile unsigned char *)(pst->DLL) = 0x60;
  679. //高位
  680. *(volatile unsigned char *)(pst->DLM) = 0x00;
  681. break;
  682. case 9600:
  683. *(volatile unsigned char *)(pst->DLL) = 0x30;
  684. //高位
  685. *(volatile unsigned char *)(pst->DLM) = 0x00;
  686. break;
  687. case 19200:
  688. *(volatile unsigned char *)(pst->DLL) = 0x18;
  689. //高位
  690. *(volatile unsigned char *)(pst->DLM) = 0x00;
  691. break;
  692. case 38400:
  693. *(volatile unsigned char *)(pst->DLL) = 0x0C;
  694. //高位
  695. *(volatile unsigned char *)(pst->DLM) = 0x00;
  696. break;
  697. case 76800:
  698. *(volatile unsigned char *)(pst->DLL) = 0x06;
  699. //高位
  700. *(volatile unsigned char *)(pst->DLM) = 0x00;
  701. break;
  702. case 153600:
  703. *(volatile unsigned char *)(pst->DLL) = 0x03;
  704. //高位
  705. *(volatile unsigned char *)(pst->DLM) = 0x00;
  706. break;
  707. default:
  708. break;
  709. }
  710. if(byMode&0x80){
  711. *(volatile unsigned char *)(pst->LCR) = 0x02|(byMode&0x7f);//7 bit
  712. }
  713. else{
  714. //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器
  715. *(volatile unsigned char *)(pst->LCR) = 0x03|byMode;
  716. }
  717. //空读一次
  718. byRx = *(volatile unsigned char *)(pst->RBR);
  719. //读空
  720. i=0;
  721. while(1){
  722. //检查接收状态
  723. byRx = *(volatile unsigned char *)(pst->LSR);
  724. if(byRx&0x01){
  725. byRx = *(volatile unsigned char *)(pst->RBR);
  726. }
  727. else
  728. break;
  729. //防止死循环
  730. i++;
  731. if(i > 4096)//每个UART最多只能缓存16个字节
  732. break;
  733. }
  734. pst->sInited = 1;
  735. }
  736. //ST16C554初始化
  737. void Init_ST0A(int nBaud, unsigned char byMode){
  738. InitCommont(&st0A,nBaud,byMode);
  739. }
  740. void Init_ST0B(int nBaud, unsigned char byMode){
  741. InitCommont(&st0B,nBaud,byMode);
  742. }
  743. void Init_ST0C(int nBaud, unsigned char byMode){
  744. InitCommont(&st0C,nBaud,byMode);
  745. }
  746. void Init_ST0D(int nBaud, unsigned char byMode){
  747. InitCommont(&st0D,nBaud,byMode);
  748. }
  749. void Init_ST0E(int nBaud, unsigned char byMode){
  750. InitCommont(&st0E,nBaud,byMode);
  751. }
  752. void Init_ST0F(int nBaud, unsigned char byMode){
  753. InitCommont(&st0F,nBaud,byMode);
  754. }
  755. void Init_ST0G(int nBaud, unsigned char byMode){
  756. InitCommont(&st0G,nBaud,byMode);
  757. }
  758. void Init_ST0H(int nBaud, unsigned char byMode){
  759. InitCommont(&st0H,nBaud,byMode);
  760. }
  761. //ST16C554的接收
  762. unsigned char ST0A_Rxd(void){
  763. volatile unsigned char byRx;
  764. volatile unsigned char bySt;
  765. int nRxCnt = 0;
  766. while(nRxCnt < 256){
  767. bySt = *(volatile unsigned char *)(st0A.LSR);//检查接收状态
  768. if(bySt&0x01){//数据就绪
  769. byRx = *(volatile unsigned char *)(st0A.RBR);
  770. pushST0ARX(byRx);
  771. }
  772. else
  773. break;
  774. nRxCnt++;
  775. }
  776. return byRx;
  777. }
  778. unsigned char ST0B_Rxd(void){
  779. volatile unsigned char byRx;
  780. volatile unsigned char bySt;
  781. int nRxCnt = 0;
  782. while(nRxCnt < 256){
  783. bySt = *(volatile unsigned char *)(st0B.LSR);//检查接收状态
  784. if(bySt&0x01){//数据就绪
  785. byRx = *(volatile unsigned char *)(st0B.RBR);
  786. pushST0BRX(byRx);
  787. }
  788. else{
  789. break;
  790. }
  791. nRxCnt++;
  792. }
  793. return byRx;
  794. }
  795. unsigned char ST0C_Rxd(void){
  796. volatile unsigned char byRx;
  797. volatile unsigned char bySt;
  798. int nRxCnt = 0;
  799. while(nRxCnt < 256){
  800. bySt = *(volatile unsigned char *)(st0C.LSR);//检查接收状态
  801. if(bySt&0x01){//数据就绪
  802. byRx = *(volatile unsigned char *)(st0C.RBR);
  803. pushST0CRX(byRx);
  804. }
  805. else
  806. break;
  807. nRxCnt++;
  808. }
  809. return byRx;
  810. }
  811. unsigned char ST0D_Rxd(void){
  812. volatile unsigned char byRx;
  813. volatile unsigned char bySt;
  814. int nRxCnt = 0;
  815. while(nRxCnt < 256){
  816. bySt = *(volatile unsigned char *)(st0D.LSR);//检查接收状态
  817. if(bySt&0x01){//数据就绪
  818. byRx = *(volatile unsigned char *)(st0D.RBR);
  819. pushST0DRX(byRx);
  820. }
  821. else
  822. break;
  823. nRxCnt++;
  824. }
  825. return byRx;
  826. }
  827. unsigned char ST0E_Rxd(void){
  828. volatile unsigned char byRx;
  829. volatile unsigned char bySt;
  830. int nRxCnt = 0;
  831. while(nRxCnt < 256){
  832. bySt = *(volatile unsigned char *)(st0E.LSR);//检查接收状态
  833. if(bySt&0x01){//数据就绪
  834. byRx = *(volatile unsigned char *)(st0E.RBR);
  835. pushST0ERX(byRx);
  836. }
  837. else
  838. break;
  839. nRxCnt++;
  840. }
  841. return byRx;
  842. }
  843. unsigned char ST0F_Rxd(void){
  844. volatile unsigned char byRx;
  845. volatile unsigned char bySt;
  846. int nRxCnt = 0;
  847. while(nRxCnt < 256){
  848. bySt = *(volatile unsigned char *)(st0F.LSR);//检查接收状态
  849. if(bySt&0x01){//数据就绪
  850. byRx = *(volatile unsigned char *)(st0F.RBR);
  851. pushST0FRX(byRx);
  852. }
  853. else{
  854. break;
  855. }
  856. nRxCnt++;
  857. }
  858. return byRx;
  859. }
  860. unsigned char ST0G_Rxd(void){
  861. volatile unsigned char byRx;
  862. volatile unsigned char bySt;
  863. int nRxCnt = 0;
  864. while(nRxCnt < 256){
  865. bySt = *(volatile unsigned char *)(st0G.LSR);//检查接收状态
  866. if(bySt&0x01){//数据就绪
  867. byRx = *(volatile unsigned char *)(st0G.RBR);
  868. pushST0GRX(byRx);
  869. }
  870. else
  871. break;
  872. nRxCnt++;
  873. }
  874. return byRx;
  875. }
  876. unsigned char ST0H_Rxd(void){
  877. volatile unsigned char byRx;
  878. volatile unsigned char bySt;
  879. int nRxCnt = 0;
  880. while(nRxCnt < 256){
  881. bySt = *(volatile unsigned char *)(st0H.LSR);//检查接收状态
  882. if(bySt&0x01){//数据就绪
  883. byRx = *(volatile unsigned char *)(st0H.RBR);
  884. pushST0HRX(byRx);
  885. }
  886. else
  887. break;
  888. nRxCnt++;
  889. }
  890. return byRx;
  891. }
  892. //ST16C554的发送
  893. //返回:1,成功
  894. //     0,失败
  895. int ST_ComTxd(ST_COM *pst,unsigned char byTxd){
  896. unsigned char byRx;
  897. int nTxCnt = 0;
  898. while(nTxCnt < 256){
  899. byRx = *(volatile unsigned char *)(pst->LSR);//检查发送状态
  900. if(byRx&0x20){//发送就绪
  901. *(volatile unsigned char *)(pst->THR) = byTxd;
  902. return 1;
  903. }
  904. else{
  905. nTxCnt++;
  906. }
  907. }
  908. return 0;
  909. }
  910. static void UART0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  911. {
  912. //save_flags_cli(flags);
  913. if (st0A.sInited)
  914. ST0A_Rxd();
  915. //      printk(KERN_INFO "UART0_interrupt1\n" );
  916. if (st0B.sInited)
  917. ST0B_Rxd();
  918. //      printk(KERN_INFO "UART0_interrupt2\n" );
  919. if (st0C.sInited);
  920. ST0C_Rxd();
  921. //      printk(KERN_INFO "UART0_interrupt3\n" );
  922. if (st0D.sInited)
  923. ST0D_Rxd();
  924. //      printk(KERN_INFO "UART0_interrupt4\n" );
  925. //restore_flags(flags);
  926. }
  927. static void UART1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  928. {
  929. if (st0E.sInited)
  930. ST0E_Rxd();
  931. //      printk(KERN_INFO "UART1_interrupt0\n" );
  932. if (st0F.sInited)
  933. ST0F_Rxd();
  934. //      printk(KERN_INFO "UART1_interrupt1\n" );
  935. if (st0G.sInited)
  936. ST0G_Rxd();
  937. //      printk(KERN_INFO "UART1_interrupt2\n" );
  938. if (st0H.sInited)
  939. ST0H_Rxd();
  940. //      printk(KERN_INFO "UART1_interrupt3\n" );
  941. }
  942. static int st16c554_open(struct inode *inode, struct file *filp)
  943. {
  944. int nRet = 0;
  945. MOD_INC_USE_COUNT;
  946. return nRet;
  947. }
  948. static int st16c554_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  949. {
  950. int nRet = 0;
  951. switch(cmd) {
  952. default:
  953. return -EINVAL;
  954. }
  955. return nRet;
  956. }
  957. static int st16c554_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
  958. {
  959. int nRet = 0;
  960. return nRet;
  961. }
  962. static int st16c554_release(struct inode *inode, struct file *filp)
  963. {
  964. int nRet = 0;
  965. MOD_DEC_USE_COUNT;
  966. return nRet;
  967. }
  968. static int st16c554_ComWrite(const char *buf, size_t nCount ,ST_COM *mPst)
  969. {
  970. int i,j,nRet;
  971. unsigned char abySend[ST_SEND_LEN];
  972. int m,k;
  973. m=nCount/ST_SEND_LEN;
  974. k=nCount%ST_SEND_LEN;
  975. for(i=0; i<m; i++){
  976. if (copy_from_user(abySend,buf+i*ST_SEND_LEN,ST_SEND_LEN)){
  977. return -EFAULT;
  978. }
  979. for(nRet=0; nRet<ST_SEND_LEN; nRet++){
  980. ST_ComTxd(mPst,abySend[nRet]);
  981. //ST0A_Txd(abySend[nRet]);
  982. for(j=0; j<delay_counter; j++);//300000
  983. //      printk("A:%02X\n", abySend[nRet]);
  984. }
  985. }
  986. if (k>0){
  987. if (copy_from_user(abySend,buf+m*ST_SEND_LEN,k)){
  988. return -EFAULT;
  989. }
  990. for(nRet=0; nRet<k; nRet++){
  991. ST_ComTxd(mPst,abySend[nRet]);
  992. //ST0A_Txd(abySend[nRet]);
  993. for(j=0; j<delay_counter; j++);//300000
  994. //      printk("A:%02X\n", abySend[nRet]);
  995. }
  996. }
  997. return nRet;
  998. }
  999. static int ST0A_open(struct inode *inode, struct file *filp)
  1000. {
  1001. int nRet = 0;
  1002. MOD_INC_USE_COUNT;
  1003. return nRet;
  1004. }
  1005. static int ST0A_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1006. {
  1007. int nRet = 0;
  1008. switch(cmd) {
  1009. case ST_INIT:
  1010. copy_from_user(&st0A_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1011. Init_ST0A(st0A_init.nBaud, st0A_init.byMode);
  1012. break;
  1013. default:
  1014. return -EINVAL;
  1015. }
  1016. return nRet;
  1017. }
  1018. static int ST0A_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1019. {
  1020. int i;
  1021. int nLen;
  1022. unsigned char abyRecv[ST_RECV_LEN];
  1023. nLen = get_ST0A_rxLen();
  1024. nLen = nLen>count ? count : nLen;
  1025. for(i=0; i<nLen; i++){
  1026. abyRecv[i] = st0A.abyRecvData[st0A.sRecvHead];
  1027. if(st0A.sRecvHead != st0A.sRecvTail){
  1028. st0A.sRecvHead++;
  1029. st0A.sRecvHead %= ST_RECV_LEN;
  1030. }
  1031. else
  1032. break;
  1033. }
  1034. copy_to_user((void *)buf, &abyRecv, i);
  1035. return i;
  1036. }
  1037. static int ST0A_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1038. return st16c554_ComWrite(buf,count,&st0A);
  1039. }
  1040. static int ST0A_release(struct inode *inode, struct file *filp)
  1041. {
  1042. int nRet = 0;
  1043. MOD_DEC_USE_COUNT;
  1044. return nRet;
  1045. }
  1046. static int ST0B_open(struct inode *inode, struct file *filp)
  1047. {
  1048. int nRet = 0;
  1049. MOD_INC_USE_COUNT;
  1050. return nRet;
  1051. }
  1052. static int ST0B_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1053. {
  1054. int nRet = 0;
  1055. switch(cmd) {
  1056. case ST_INIT:
  1057. copy_from_user(&st0B_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1058. Init_ST0B(st0B_init.nBaud, st0B_init.byMode);
  1059. break;
  1060. default:
  1061. return -EINVAL;
  1062. }
  1063. return nRet;
  1064. }
  1065. static int ST0B_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1066. {
  1067. int i;
  1068. int nLen;
  1069. unsigned char abyRecv[ST_RECV_LEN];
  1070. nLen = get_ST0B_rxLen();
  1071. nLen = nLen>count ? count : nLen;
  1072. for(i=0; i<nLen; i++){
  1073. abyRecv[i] = st0B.abyRecvData[st0B.sRecvHead];
  1074. if(st0B.sRecvHead != st0B.sRecvTail){
  1075. st0B.sRecvHead++;
  1076. st0B.sRecvHead %= ST_RECV_LEN;
  1077. }
  1078. else
  1079. break;
  1080. }
  1081. copy_to_user((void *)buf, &abyRecv, i);
  1082. return i;
  1083. }
  1084. static int ST0B_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1085. return st16c554_ComWrite(buf,count,&st0B);
  1086. }
  1087. static int ST0B_release(struct inode *inode, struct file *filp)
  1088. {
  1089. int nRet = 0;
  1090. MOD_DEC_USE_COUNT;
  1091. return nRet;
  1092. }
  1093. static int ST0C_open(struct inode *inode, struct file *filp)
  1094. {
  1095. int nRet = 0;
  1096. MOD_INC_USE_COUNT;
  1097. return nRet;
  1098. }
  1099. static int ST0C_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1100. {
  1101. int nRet = 0;
  1102. switch(cmd) {
  1103. case ST_INIT:
  1104. copy_from_user(&st0C_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1105. Init_ST0C(st0C_init.nBaud, st0C_init.byMode);
  1106. break;
  1107. default:
  1108. return -EINVAL;
  1109. }
  1110. return nRet;
  1111. }
  1112. static int ST0C_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1113. {
  1114. int i;
  1115. int nLen;
  1116. unsigned char abyRecv[ST_RECV_LEN];
  1117. nLen = get_ST0C_rxLen();
  1118. nLen = nLen>count ? count : nLen;
  1119. for(i=0; i<nLen; i++){
  1120. abyRecv[i] = st0C.abyRecvData[st0C.sRecvHead];
  1121. if(st0C.sRecvHead != st0C.sRecvTail){
  1122. st0C.sRecvHead++;
  1123. st0C.sRecvHead %= ST_RECV_LEN;
  1124. }
  1125. else
  1126. break;
  1127. }
  1128. copy_to_user((void *)buf, &abyRecv, i);
  1129. return i;
  1130. }
  1131. static int ST0C_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1132. return st16c554_ComWrite(buf,count,&st0C);
  1133. }
  1134. static int ST0C_release(struct inode *inode, struct file *filp)
  1135. {
  1136. int nRet = 0;
  1137. MOD_DEC_USE_COUNT;
  1138. return nRet;
  1139. }
  1140. static int ST0D_open(struct inode *inode, struct file *filp)
  1141. {
  1142. int nRet = 0;
  1143. MOD_INC_USE_COUNT;
  1144. return nRet;
  1145. }
  1146. static int ST0D_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1147. {
  1148. int nRet = 0;
  1149. switch(cmd) {
  1150. case ST_INIT:
  1151. copy_from_user(&st0D_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1152. Init_ST0D(st0D_init.nBaud, st0D_init.byMode);
  1153. break;
  1154. default:
  1155. return -EINVAL;
  1156. }
  1157. return nRet;
  1158. }
  1159. static int ST0D_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1160. {
  1161. int i;
  1162. int nLen;
  1163. unsigned char abyRecv[ST_RECV_LEN];
  1164. nLen = get_ST0D_rxLen();
  1165. nLen = nLen>count ? count : nLen;
  1166. for(i=0; i<nLen; i++){
  1167. abyRecv[i] = st0D.abyRecvData[st0D.sRecvHead];
  1168. if(st0D.sRecvHead != st0D.sRecvTail){
  1169. st0D.sRecvHead++;
  1170. st0D.sRecvHead %= ST_RECV_LEN;
  1171. }
  1172. else
  1173. break;
  1174. //      printk("D-:%02X\n", abyRecv[i]);
  1175. }
  1176. copy_to_user((void *)buf, &abyRecv, i);
  1177. return i;
  1178. }
  1179. static int ST0D_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1180. return st16c554_ComWrite(buf,count,&st0D);
  1181. }
  1182. static int ST0D_release(struct inode *inode, struct file *filp)
  1183. {
  1184. int nRet = 0;
  1185. MOD_DEC_USE_COUNT;
  1186. return nRet;
  1187. }
  1188. static int ST0E_open(struct inode *inode, struct file *filp)
  1189. {
  1190. int nRet = 0;
  1191. MOD_INC_USE_COUNT;
  1192. return nRet;
  1193. }
  1194. static int ST0E_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1195. {
  1196. int nRet = 0;
  1197. switch(cmd) {
  1198. case ST_INIT:
  1199. copy_from_user(&st0E_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1200. Init_ST0E(st0E_init.nBaud, st0E_init.byMode);
  1201. break;
  1202. default:
  1203. return -EINVAL;
  1204. }
  1205. return nRet;
  1206. }
  1207. static int ST0E_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1208. {
  1209. int i;
  1210. int nLen;
  1211. unsigned char abyRecv[ST_RECV_LEN];
  1212. nLen = get_ST0E_rxLen();
  1213. nLen = nLen>count ? count : nLen;
  1214. for(i=0; i<nLen; i++){
  1215. abyRecv[i] = st0E.abyRecvData[st0E.sRecvHead];
  1216. if(st0E.sRecvHead != st0E.sRecvTail){
  1217. st0E.sRecvHead++;
  1218. st0E.sRecvHead %= ST_RECV_LEN;
  1219. }
  1220. else
  1221. break;
  1222. }
  1223. copy_to_user((void *)buf, &abyRecv, i);
  1224. return i;
  1225. }
  1226. static int ST0E_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1227. return st16c554_ComWrite(buf,count,&st0E);
  1228. }
  1229. static int ST0E_release(struct inode *inode, struct file *filp)
  1230. {
  1231. int nRet = 0;
  1232. MOD_DEC_USE_COUNT;
  1233. return nRet;
  1234. }
  1235. static int ST0F_open(struct inode *inode, struct file *filp)
  1236. {
  1237. int nRet = 0;
  1238. MOD_INC_USE_COUNT;
  1239. return nRet;
  1240. }
  1241. static int ST0F_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1242. {
  1243. int nRet = 0;
  1244. switch(cmd) {
  1245. case ST_INIT:
  1246. copy_from_user(&st0F_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1247. Init_ST0F(st0F_init.nBaud, st0F_init.byMode);
  1248. break;
  1249. default:
  1250. return -EINVAL;
  1251. }
  1252. return nRet;
  1253. }
  1254. static int ST0F_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1255. {
  1256. int i;
  1257. int nLen;
  1258. unsigned char abyRecv[ST_RECV_LEN];
  1259. nLen = get_ST0F_rxLen();
  1260. nLen = nLen>count ? count : nLen;
  1261. for(i=0; i<nLen; i++){
  1262. abyRecv[i] = st0F.abyRecvData[st0F.sRecvHead];
  1263. if(st0F.sRecvHead != st0F.sRecvTail){
  1264. st0F.sRecvHead++;
  1265. st0F.sRecvHead %= ST_RECV_LEN;
  1266. }
  1267. else
  1268. break;
  1269. }
  1270. copy_to_user((void *)buf, &abyRecv, i);
  1271. return i;
  1272. }
  1273. static int ST0F_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1274. return st16c554_ComWrite(buf,count,&st0F);
  1275. }
  1276. static int ST0F_release(struct inode *inode, struct file *filp)
  1277. {
  1278. int nRet = 0;
  1279. MOD_DEC_USE_COUNT;
  1280. return nRet;
  1281. }
  1282. static int ST0G_open(struct inode *inode, struct file *filp)
  1283. {
  1284. int nRet = 0;
  1285. MOD_INC_USE_COUNT;
  1286. return nRet;
  1287. }
  1288. static int ST0G_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1289. {
  1290. int nRet = 0;
  1291. switch(cmd) {
  1292. case ST_INIT:
  1293. copy_from_user(&st0G_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1294. Init_ST0G(st0G_init.nBaud, st0G_init.byMode);
  1295. break;
  1296. default:
  1297. return -EINVAL;
  1298. }
  1299. return nRet;
  1300. }
  1301. static int ST0G_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1302. {
  1303. int i;
  1304. int nLen;
  1305. unsigned char abyRecv[ST_RECV_LEN];
  1306. nLen = get_ST0G_rxLen();
  1307. nLen = nLen>count ? count : nLen;
  1308. for(i=0; i<nLen; i++){
  1309. abyRecv[i] = st0G.abyRecvData[st0G.sRecvHead];
  1310. if(st0G.sRecvHead != st0G.sRecvTail){
  1311. st0G.sRecvHead++;
  1312. st0G.sRecvHead %= ST_RECV_LEN;
  1313. }
  1314. else
  1315. break;
  1316. }
  1317. copy_to_user((void *)buf, &abyRecv, i);
  1318. return i;
  1319. }
  1320. static int ST0G_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1321. return st16c554_ComWrite(buf,count,&st0G);
  1322. }
  1323. static int ST0G_release(struct inode *inode, struct file *filp)
  1324. {
  1325. int nRet = 0;
  1326. MOD_DEC_USE_COUNT;
  1327. return nRet;
  1328. }
  1329. static int ST0H_open(struct inode *inode, struct file *filp)
  1330. {
  1331. int nRet = 0;
  1332. MOD_INC_USE_COUNT;
  1333. return nRet;
  1334. }
  1335. static int ST0H_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1336. {
  1337. int nRet = 0;
  1338. switch(cmd) {
  1339. case ST_INIT:
  1340. copy_from_user(&st0H_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
  1341. Init_ST0H(st0H_init.nBaud, st0H_init.byMode);
  1342. break;
  1343. default:
  1344. return -EINVAL;
  1345. }
  1346. return nRet;
  1347. }
  1348. static int ST0H_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
  1349. {
  1350. int i;
  1351. int nLen;
  1352. unsigned char abyRecv[ST_RECV_LEN];
  1353. nLen = get_ST0H_rxLen();
  1354. nLen = nLen>count ? count : nLen;
  1355. for(i=0; i<nLen; i++){
  1356. abyRecv[i] = st0H.abyRecvData[st0H.sRecvHead];
  1357. if(st0H.sRecvHead != st0H.sRecvTail){
  1358. st0H.sRecvHead++;
  1359. st0H.sRecvHead %= ST_RECV_LEN;
  1360. }
  1361. else
  1362. break;
  1363. //      printk("D-:%02X\n", abyRecv[i]);
  1364. }
  1365. copy_to_user((void *)buf, &abyRecv, i);
  1366. return i;
  1367. }
  1368. static int ST0H_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
  1369. return st16c554_ComWrite(buf,count,&st0H);
  1370. }
  1371. static int ST0H_release(struct inode *inode, struct file *filp)
  1372. {
  1373. int nRet = 0;
  1374. MOD_DEC_USE_COUNT;
  1375. return nRet;
  1376. }
  1377. static struct file_operations st16c554_fops = {
  1378. owner:  THIS_MODULE,
  1379. open:   st16c554_open,
  1380. ioctl:  st16c554_ioctl,
  1381. read:   st16c554_read,
  1382. release:    st16c554_release,
  1383. };
  1384. static struct file_operations ST0A_fops = {
  1385. owner:  THIS_MODULE,
  1386. open:   ST0A_open,
  1387. ioctl:  ST0A_ioctl,
  1388. read:   ST0A_read,
  1389. write:  ST0A_write,
  1390. release:    ST0A_release,
  1391. };
  1392. static struct file_operations ST0B_fops = {
  1393. owner:  THIS_MODULE,
  1394. open:   ST0B_open,
  1395. ioctl:  ST0B_ioctl,
  1396. read:   ST0B_read,
  1397. write:  ST0B_write,
  1398. release:    ST0B_release,
  1399. };
  1400. static struct file_operations ST0C_fops = {
  1401. owner:  THIS_MODULE,
  1402. open:   ST0C_open,
  1403. ioctl:  ST0C_ioctl,
  1404. read:   ST0C_read,
  1405. write:  ST0C_write,
  1406. release:    ST0C_release,
  1407. };
  1408. static struct file_operations ST0D_fops = {
  1409. owner:  THIS_MODULE,
  1410. open:   ST0D_open,
  1411. ioctl:  ST0D_ioctl,
  1412. read:   ST0D_read,
  1413. write:  ST0D_write,
  1414. release:    ST0D_release,
  1415. };
  1416. static struct file_operations ST0E_fops = {
  1417. owner:  THIS_MODULE,
  1418. open:   ST0E_open,
  1419. ioctl:  ST0E_ioctl,
  1420. read:   ST0E_read,
  1421. write:  ST0E_write,
  1422. release:    ST0E_release,
  1423. };
  1424. static struct file_operations ST0F_fops = {
  1425. owner:  THIS_MODULE,
  1426. open:   ST0F_open,
  1427. ioctl:  ST0F_ioctl,
  1428. read:   ST0F_read,
  1429. write:  ST0F_write,
  1430. release:    ST0F_release,
  1431. };
  1432. static struct file_operations ST0G_fops = {
  1433. owner:  THIS_MODULE,
  1434. open:   ST0G_open,
  1435. ioctl:  ST0G_ioctl,
  1436. read:   ST0G_read,
  1437. write:  ST0G_write,
  1438. release:    ST0G_release,
  1439. };
  1440. static struct file_operations ST0H_fops = {
  1441. owner:  THIS_MODULE,
  1442. open:   ST0H_open,
  1443. ioctl:  ST0H_ioctl,
  1444. read:   ST0H_read,
  1445. write:  ST0H_write,
  1446. release:    ST0H_release,
  1447. };
  1448. static devfs_handle_t devfs_st_dir, devfs_ST0A, devfs_ST0B, devfs_ST0C, devfs_ST0D;
  1449. static devfs_handle_t devfs_ST0E, devfs_ST0F, devfs_ST0G, devfs_ST0H;
  1450. static int __init st16c554_init(void)
  1451. {
  1452. int ret;
  1453. printk(KERN_INFO "Init ST16C554 ......\n" );
  1454. mtdcr(DCRN_EBC0_CFGADDR, DCRN_EBC0_B3CR);
  1455. printk(KERN_INFO "B3CR1=== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );
  1456. mtdcr(DCRN_EBC0_CFGDATA, 0xf0218000);  //SET PCS3 BASEADDR
  1457. printk(KERN_INFO "B3CR2== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );
  1458. ret = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &st16c554_fops);
  1459. if (ret < 0) {
  1460. printk(DEVICE_NAME " can't get major number\n");
  1461. return ret;
  1462. }
  1463. stMajor = ret;
  1464. devfs_st_dir = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
  1465. if (devfs_st_dir == NULL)
  1466. printk( " devfs_mk_dir() error! \n");
  1467. devfs_ST0A = devfs_register(devfs_st_dir, "0", DEVFS_FL_DEFAULT,     // dev/st16c554/0 for ST0A
  1468. stMajor, ST0A, S_IFCHR | S_IRUSR | S_IWUSR,
  1469. &ST0A_fops, NULL);
  1470. devfs_ST0B = devfs_register(devfs_st_dir, "1", DEVFS_FL_DEFAULT,     // dev/st16c554/1 for ST0B
  1471. stMajor, ST0B, S_IFCHR | S_IRUSR | S_IWUSR,
  1472. &ST0B_fops, NULL);
  1473. devfs_ST0C = devfs_register(devfs_st_dir, "2", DEVFS_FL_DEFAULT,     // dev/st16c554/2 for ST0C
  1474. stMajor, ST0C, S_IFCHR | S_IRUSR | S_IWUSR,
  1475. &ST0C_fops, NULL);
  1476. devfs_ST0D = devfs_register(devfs_st_dir, "3", DEVFS_FL_DEFAULT,     // dev/st16c554/3 for ST0D
  1477. stMajor, ST0D, S_IFCHR | S_IRUSR | S_IWUSR,
  1478. &ST0D_fops, NULL);
  1479. devfs_ST0E = devfs_register(devfs_st_dir, "4", DEVFS_FL_DEFAULT,     // dev/st16c554/4 for ST0E
  1480. stMajor, ST0E, S_IFCHR | S_IRUSR | S_IWUSR,
  1481. &ST0E_fops, NULL);
  1482. devfs_ST0F = devfs_register(devfs_st_dir, "5", DEVFS_FL_DEFAULT,     // dev/st16c554/5 for ST0F
  1483. stMajor, ST0F, S_IFCHR | S_IRUSR | S_IWUSR,
  1484. &ST0F_fops, NULL);
  1485. devfs_ST0G = devfs_register(devfs_st_dir, "6", DEVFS_FL_DEFAULT,     // dev/st16c554/6 for ST0G
  1486. stMajor, ST0G, S_IFCHR | S_IRUSR | S_IWUSR,
  1487. &ST0G_fops, NULL);
  1488. devfs_ST0H = devfs_register(devfs_st_dir, "7", DEVFS_FL_DEFAULT,     // dev/st16c554/7 for ST0H
  1489. stMajor, ST0H, S_IFCHR | S_IRUSR | S_IWUSR,
  1490. &ST0H_fops, NULL);
  1491. ret = request_irq(YC_mul232_IRQ0, UART0_interrupt, SA_INTERRUPT, "ST16C554_0_RX Ready", UART0_interrupt);
  1492. if(ret) {
  1493. printk("ST16C554: failed to register IRQ_EINT0(%d)\n", YC_mul232_IRQ0);
  1494. goto UART0_failed;
  1495. }
  1496. ret = request_irq(YC_mul232_IRQ1, UART1_interrupt, SA_INTERRUPT, "ST16C554_1_RX Ready", UART1_interrupt);
  1497. if(ret) {
  1498. printk("ST16C554: failed to register IRQ_EINT1(%d)\n", YC_mul232_IRQ1);
  1499. goto UART1_failed;
  1500. }
  1501. return 0;
  1502. UART1_failed:
  1503. free_irq(YC_mul232_IRQ1, NULL);
  1504. UART0_failed:
  1505. printk("ST16C554 DEVICE: failed to register \n");
  1506. devfs_unregister(devfs_ST0D);
  1507. devfs_unregister(devfs_ST0C);
  1508. devfs_unregister(devfs_ST0B);
  1509. devfs_unregister(devfs_ST0A);
  1510. devfs_unregister(devfs_ST0E);
  1511. devfs_unregister(devfs_ST0F);
  1512. devfs_unregister(devfs_ST0G);
  1513. devfs_unregister(devfs_ST0H);
  1514. devfs_unregister(devfs_st_dir);
  1515. unregister_chrdev(stMajor, DEVICE_NAME);
  1516. return 0;
  1517. }
  1518. static void __exit st16c554_exit(void)
  1519. {
  1520. free_irq(YC_mul232_IRQ0, NULL);
  1521. free_irq(YC_mul232_IRQ1, NULL);
  1522. devfs_unregister(devfs_ST0D);
  1523. devfs_unregister(devfs_ST0C);
  1524. devfs_unregister(devfs_ST0B);
  1525. devfs_unregister(devfs_ST0A);
  1526. devfs_unregister(devfs_ST0E);
  1527. devfs_unregister(devfs_ST0F);
  1528. devfs_unregister(devfs_ST0G);
  1529. devfs_unregister(devfs_ST0H);
  1530. devfs_unregister(devfs_st_dir);
  1531. unregister_chrdev(stMajor, DEVICE_NAME);
  1532. iounmap((void *) (st0A.pbyBase0));
  1533. iounmap((void *) (st0B.pbyBase0));
  1534. iounmap((void *) (st0C.pbyBase0));
  1535. iounmap((void *) (st0D.pbyBase0));
  1536. iounmap((void *) (st0E.pbyBase0));
  1537. iounmap((void *) (st0F.pbyBase0));
  1538. iounmap((void *) (st0G.pbyBase0));
  1539. iounmap((void *) (st0H.pbyBase0));
  1540. }
  1541. module_init(st16c554_init);
  1542. module_exit(st16c554_exit);
 

st16c554的更多相关文章

  1. 16V554 的测试代码

    //------------------------------------------------------------------------ #include   "AT16C554 ...

  2. 16C554在LINUX上的移植(AT91)

    16C554在LINUX上的移植(AT91) linux版本:3.14.17 AT91SAMa5d36   EINTA_0   ARM-IO5        PA14         14 EINTA ...

随机推荐

  1. Python 爬虫 之 阅读呼叫转移(三)

    尽管上一篇博客中我们能够连续地阅读章节了,可是.难道每一次看小说都执行一下我们的 Python 程序?连记录看到哪里都不行,每次都是又一次来过?当然不能这样,改! 如今这么多小说阅读器,我们仅仅须要把 ...

  2. excel 快捷使用

    1)excel填充相同内容 A:在需要填充相同内容的格中一个添加需要的内容,然后选中所有填充格,快捷键 ctrl-D 2)excel中合并单元格快捷键 A:1.点击上方-其他命令 2.选择“合并”进行 ...

  3. windows 7 64bit安装apche php

    http://windows.php.net/download#php-5.6-ts-VC11-x64http://www.apachehaus.com/cgi-bin/download.plx 下载 ...

  4. PHP 图像因其本身有错无法显示怎么办

    1 先确认自己的PHP和GD库版本够高,根据PHP手册的要求,PHP最好高于4.0.6,GD库要求2.0.1 2 对于使用PHPNOW的用户,在首页就可以找到相关信息 3 你也可以运行以下代码来检测是 ...

  5. C#控制台下的AO程序

    好几年没写过控制台程序了(上一次是大二时写坐标转换时用过),因为我觉得用户难以接受没有良好操作界面的应用程序,我不想偷懒,今天来将应用程序改写为控制台程序,记录一下,忘记的内容: 1.数据的交互 不管 ...

  6. 教大家如何在word 2007中同时打出对齐上下标以及字母头上有波浪线(非编辑器)

    教大家如何在word 2007中打出(非编辑器): 如果要在多个字符串上面加上划线,可以使用一下步骤 按下“Ctrl+F9”组合键,出现“{}”,在{}中输入“EQ \x\to(要加上划线的字符串)” ...

  7. 取球游戏_nyoj_518(博弈-蓝桥杯原题).java

    取球游戏 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 2   描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下 ...

  8. CodeForces 2A - Winner(模拟)

    题目链接:http://codeforces.com/problemset/problem/2/A A. Winner time limit per test 1 second memory limi ...

  9. sql通过某个字段名找到数据库中对应的表

    sql通过某个字段名找到数据库中对应的表 SELECT sb.name FROM syscolumns s JOIN sysobjects sb ON s.id=sb.id WHERE s.name= ...

  10. 【TP3.2】模板布局和文件引入

    TP3.2框架引入文件使用<include file="blue/common/header">标签,==>blue主题下的公共头文件(blue放在View/目录 ...