/*

  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. token 机制

  2. 基于Struts2、Spring、Hibernate实现的包括多条件查询分页的基础Dao层帮助jar包实现

    操作数据库经常使用操作就是增删查改.每做一次就写一次这些操作太麻烦,也不是必需,特别是写多条件查询并分页时.太痛苦了,所以抽出时间写了个dao帮助jar.导入即搞定!妈妈再有不用操心我的项目了! 转载 ...

  3. 算法笔记_155:算法提高 概率计算(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 生成n个∈[a,b]的随机整数,输出它们的和为x的概率. 输入格式 一行输入四个整数依次为n,a,b,x,用空格分隔. 输出格式 输出一行 ...

  4. javascript设计模式:构造器模式学习一

    javascript 设计模式1.简介javascript是一种弱类型语言,不过类可以通过函数模拟出来最常见的实现方法如下:function Car(model){ this.model = mode ...

  5. Linux下查看磁盘挂载的三种方法

    Linux下查看磁盘挂载的三种方法 2009-06-05 23:17 好久没有更新日志了,呵呵.不是没有要写的东东.实在抽不出时间来写,要准备公司的考试呢,C++考试.已经有七个月没有写C++代码了, ...

  6. sms_queue 短信队列

    git地址:https://github.com/Filix/sms_queue 简介 通过队列的方式发送短信,暂时实现了redis作为队列. 以实现的第三方短信服务: 百悟.漫道. 发送短信方,只需 ...

  7. Sphinx高亮显示关键字

    选取程序中使用的一部分代码: public function buildExcerptRows($ids) { $options = array( 'before_match' => '< ...

  8. EMQ ---v2.3.11源码成熟度

    从原作者那边了解到,总体还可以,但是做不到99.99%稳定.主要是连接内存占用没有保护. pubsub均衡时很稳定,但是集群或大量消息向少量订阅发布时会崩溃,小概率情况. EMQ中CPU是公平分配给M ...

  9. cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug

    cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug http://blog.csdn.net/allenice1/article/details/ ...

  10. php 实现打印预览的功能

    <inputid="btnPrint" type="button" value="打印"onclick="javascrip ...