/*
- * st16c554.c
- *
- * TWO ST16C554 driver for AMCC PPC405EP
- *
- * Author: Li Zhi You/Zhu jiang <godiscrazy@163.com>
- * Date : $Date: 2007/11/27 11:07:04 $
- *
- * $Revision: 1.1V $
- *
- ST16C554APN
- 7.3728mhz
- 扩展芯片:2*ST16C554
- 可为系统增加8个串口,直接与PPC405EP总线连接,8位数据宽度
- 地址空间:占用系统PC3
- 地址从前到后分别对应每个UART0-7个寄存器
- UART0A:0xf0200020---0xf020027
- A2A1A0(ST16C554)
- 0xf0200020 0 0 0
- 0xf0200021 0 0 1
- 0xf0200022 0 1 0
- 0xf0200023 0 1 1
- 0xf0200024 1 0 0
- 0xf0200025 1 0 1
- 0xf0200026 1 1 0
- 0xf0200027 1 1 1
- UART0B:0xf0200028---0xf020002f
- UART0C:0xf0200030---0xf0200037
- UART0D:0xf0200038---0xf020003f
- UART0E:0xf0200040---0xf020047
- A2A1A0(ST16C554)
- 0xf0200040 0 0 0
- 0xf0200041 0 0 1
- 0xf0200042 0 1 0
- 0xf0200043 0 1 1
- 0xf0200044 1 0 0
- 0xf0200045 1 0 1
- 0xf0200046 1 1 0
- 0xf0200047 1 1 1
- UART0F:0xf0200048---0xf020004f
- UART0G:0xf0200050---0xf0200057
- UART0H:0xf0200058---0xf020005f
- 控制寄存器
- Line-control register(LCR)
- 0x03
- FIFO-control register(FCR)
- 0x02
- Modem-control register(MCR)
- 0x04
- Divisor-latch LSB(DLL)
- LCR(bit7=1)0x00
- Divisor-latch MSB(DLM)
- LCR(bit7=1)0x01
- Interrupt enable register(IER)
- 0x01
- 状态寄存器
- Line-status register(LSR)
- 0x05
- Modem-status register(MSR)
- 0x06
- 数据寄存器
- Receiver-buffer register(RBR)
- 0x00
- Transmitter-holding register(THR)
- 0x00
- */
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/miscdevice.h>
- #include <linux/sched.h>
- #include <linux/delay.h>
- #include <linux/poll.h>
- #include <linux/spinlock.h>
- #include <linux/irq.h>
- #include <asm/processor.h>
- #include <platforms/ibm405ep.h>
- #include <platforms/ibm405lp.h>
- #include <linux/devfs_fs_kernel.h>
- #include <asm/io.h>
- #define ST0_A_READ 0
- #define ST0_B_READ 1
- #define ST0_C_READ 2
- #define ST0_D_READ 3
- #define ST1_A_READ 4
- #define ST1_B_READ 5
- #define ST1_C_READ 6
- #define ST1_D_READ 7
- #define ST0_A_WRITE 8
- #define ST0_B_WRITE 9
- #define ST0_C_WRITE 10
- #define ST0_D_WRITE 11
- #define ST1_A_WRITE 12
- #define ST1_B_WRITE 13
- #define ST1_C_WRITE 14
- #define ST1_D_WRITE 15
- #define ST_INIT 32
- typedef struct tagST_INIT{
- int nChn;
- int nBaud;
- unsigned char byMode;
- } myST_INIT;
- myST_INIT st0A_init;
- myST_INIT st0B_init;
- myST_INIT st0C_init;
- myST_INIT st0D_init;
- myST_INIT st0E_init;
- myST_INIT st0F_init;
- myST_INIT st0G_init;
- myST_INIT st0H_init;
- #define NONEPARITY 0x00
- #define ODDPARITY 0x08
- #define EVENPARITY 0x18
- #define DATA7BIT 0x80
- #define BAUDBASE 0x30 /***4800bps->hex***/
- #define ST_COM_CNT 8
- #define ST_RECV_LEN 1600
- #define ST_SEND_LEN 160
- //以下定义与系统地址相关(与CPLD有关系)
- /* 68 mode interface
- HOW TO Select CHannel
- CS A4 A3 CHANNEL
- 1 0/1 0/1 None
- 0 0 0 A
- 0 0 1 B
- 0 1 0 C
- 0 1 1 D
- Internal Register is Decoded by A2 A1 A0;
- 具体定义见程序开头的宏定义
- 两片ST16C554都接在405EP的PCS3上,
- 用A6和A5来区分ST16C554 */
- /*这里采用D、C、B、A及H、G、F、E的方式编号主要是为了满足板子
- 上串口定死的从左到右1——8顺序,并没有其它特殊含义*/
- #define YC_PHY_BASE_ADRR 0xf0200000 //映射基地址空间
- #define UcsAnd 0xffffff07 // addr(7)='0',addr(6)='0',addr(5)='0',addr(4)='0',addr(3)='0'
- #define Ucs_DChannel_Or 0x20 // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='0'
- #define Ucs_CChannel_Or 0x28 // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='1'
- #define Ucs_BChannel_Or 0x30 // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='0'
- #define Ucs_AChannel_Or 0x38 // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='1'
- #define Ucs_HChannel_Or 0x40 // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='0'
- #define Ucs_GChannel_Or 0x48 // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='1'
- #define Ucs_FChannel_Or 0x50 // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='0'
- #define Ucs_EChannel_Or 0x58 // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='1'
- #define YC_mul232_IRQ0 26 //中断号 IRQ1
- #define YC_mul232_IRQ1 30 //中断号 IRQ5
- #define delay_counter 100000 //用于写函数,写入一个字符寄存器先延时,然后再写下一个字符
- typedef struct {
- int nAddress0;
- int nAddress1;
- int sInited;
- unsigned char *pbyBase0;
- //数据寄存器
- int RBR;//Receiver-buffer register 0
- int THR;//Transmitter-holding register 0
- //状态寄存器
- int LSR;//Line-status register 5
- int MSR;//Modem-status register 6
- //控制寄存器
- int LCR;//Line-control register 3
- int FCR;//FIFO-control register 2
- int MCR;//Modem-control register 4
- int DLL;//Divisor-latch LSB 0
- int DLM;//Divisor-latch MSB 1
- int IER;//Interrupt enable register 1
- //其它寄存器
- int SPR;//Scratchpad register 7
- int IIR;//Interrupt identification register 2
- //串口数据接收缓冲区
- volatile short sRecvHead;
- volatile short sRecvTail;
- volatile unsigned char abyRecvData[ST_RECV_LEN];
- //串口数据发送缓冲区
- volatile short sSendHead;
- volatile short sSendTail;
- volatile unsigned char abySendData[ST_SEND_LEN];
- } ST_COM;
- static ST_COM st0A = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_AChannel_Or), 0};
- static ST_COM st0B = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_BChannel_Or), 0};
- static ST_COM st0C = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_CChannel_Or), 0};
- static ST_COM st0D = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_DChannel_Or), 0};
- static ST_COM st0E = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_EChannel_Or), 0};
- static ST_COM st0F = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_FChannel_Or), 0};
- static ST_COM st0G = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_GChannel_Or), 0};
- static ST_COM st0H = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_HChannel_Or), 0};
- #define DEVICE_NAME "ST16C554"
- #define DEVICE_MAJOR 233
- #define ST0A 0
- #define ST0B 1
- #define ST0C 2
- #define ST0D 3
- #define ST0E 4
- #define ST0F 5
- #define ST0G 6
- #define ST0H 7
- static int stMajor = 233;
- inline int get_ST0A_rxLen(void){
- if(st0A.sRecvHead==st0A.sRecvTail){
- return 0;
- }
- else if(st0A.sRecvTail>st0A.sRecvHead){
- return (st0A.sRecvTail-st0A.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0A.sRecvHead-st0A.sRecvTail) );
- }
- }
- inline int get_ST0B_rxLen(void){
- if(st0B.sRecvHead==st0B.sRecvTail){
- return 0;
- }
- else if(st0B.sRecvTail>st0B.sRecvHead){
- return (st0B.sRecvTail-st0B.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0B.sRecvHead-st0B.sRecvTail) );
- }
- }
- inline int get_ST0C_rxLen(void){
- if(st0C.sRecvHead==st0C.sRecvTail){
- return 0;
- }
- else if(st0C.sRecvTail>st0C.sRecvHead){
- return (st0C.sRecvTail-st0C.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0C.sRecvHead-st0C.sRecvTail) );
- }
- }
- inline int get_ST0D_rxLen(void){
- if(st0D.sRecvHead==st0D.sRecvTail){
- return 0;
- }
- else if(st0D.sRecvTail>st0D.sRecvHead){
- return (st0D.sRecvTail-st0D.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0D.sRecvHead-st0D.sRecvTail) );
- }
- }
- inline int get_ST0E_rxLen(void){
- if(st0E.sRecvHead==st0E.sRecvTail){
- return 0;
- }
- else if(st0E.sRecvTail>st0E.sRecvHead){
- return (st0E.sRecvTail-st0E.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0E.sRecvHead-st0E.sRecvTail) );
- }
- }
- inline int get_ST0F_rxLen(void){
- if(st0F.sRecvHead==st0F.sRecvTail){
- return 0;
- }
- else if(st0F.sRecvTail>st0F.sRecvHead){
- return (st0F.sRecvTail-st0F.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0F.sRecvHead-st0F.sRecvTail) );
- }
- }
- inline int get_ST0G_rxLen(void){
- if(st0G.sRecvHead==st0G.sRecvTail){
- return 0;
- }
- else if(st0G.sRecvTail>st0G.sRecvHead){
- return (st0G.sRecvTail-st0G.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0G.sRecvHead-st0G.sRecvTail) );
- }
- }
- inline int get_ST0H_rxLen(void){
- if(st0H.sRecvHead==st0H.sRecvTail){
- return 0;
- }
- else if(st0H.sRecvTail>st0H.sRecvHead){
- return (st0H.sRecvTail-st0H.sRecvHead);
- }
- else{
- return ( ST_RECV_LEN-(st0H.sRecvHead-st0H.sRecvTail) );
- }
- }
- inline int get_ST0A_txLen(void){
- if(st0A.sSendHead==st0A.sSendTail){
- return 0;
- }
- else if(st0A.sSendTail>st0A.sSendHead){
- return (st0A.sSendTail-st0A.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0A.sSendHead-st0A.sSendTail) );
- }
- }
- inline int get_ST0B_txLen(void){
- if(st0B.sSendHead==st0B.sSendTail){
- return 0;
- }
- else if(st0B.sSendTail>st0B.sSendHead){
- return (st0B.sSendTail-st0B.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0B.sSendHead-st0B.sSendTail) );
- }
- }
- inline int get_ST0C_txLen(void){
- if(st0C.sSendHead==st0C.sSendTail){
- return 0;
- }
- else if(st0C.sSendTail>st0C.sSendHead){
- return (st0C.sSendTail-st0C.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0C.sSendHead-st0C.sSendTail) );
- }
- }
- inline int get_ST0D_txLen(void){
- if(st0D.sSendHead==st0D.sSendTail){
- return 0;
- }
- else if(st0D.sSendTail>st0D.sSendHead){
- return (st0D.sSendTail-st0D.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0D.sSendHead-st0D.sSendTail) );
- }
- }
- inline int get_ST0E_txLen(void){
- if(st0E.sSendHead==st0E.sSendTail){
- return 0;
- }
- else if(st0E.sSendTail>st0E.sSendHead){
- return (st0E.sSendTail-st0E.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0E.sSendHead-st0E.sSendTail) );
- }
- }
- inline int get_ST0F_txLen(void){
- if(st0F.sSendHead==st0F.sSendTail){
- return 0;
- }
- else if(st0F.sSendTail>st0F.sSendHead){
- return (st0F.sSendTail-st0F.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0F.sSendHead-st0F.sSendTail) );
- }
- }
- inline int get_ST0G_txLen(void){
- if(st0G.sSendHead==st0G.sSendTail){
- return 0;
- }
- else if(st0G.sSendTail>st0G.sSendHead){
- return (st0G.sSendTail-st0G.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0G.sSendHead-st0G.sSendTail) );
- }
- }
- inline int get_ST0H_txLen(void){
- if(st0H.sSendHead==st0H.sSendTail){
- return 0;
- }
- else if(st0H.sSendTail>st0H.sSendHead){
- return (st0H.sSendTail-st0H.sSendHead);
- }
- else{
- return ( ST_SEND_LEN-(st0H.sSendHead-st0H.sSendTail) );
- }
- }
- inline char st0aIsEmpty_rx(void){
- return (st0A.sRecvHead==st0A.sRecvTail ? 1 : 0);
- }
- inline char st0bIsEmpty_rx(void){
- return (st0B.sRecvHead==st0B.sRecvTail ? 1 : 0);
- }
- inline char st0cIsEmpty_rx(void){
- return (st0C.sRecvHead==st0C.sRecvTail ? 1 : 0);
- }
- inline char st0dIsEmpty_rx(void){
- return (st0D.sRecvHead==st0D.sRecvTail ? 1 : 0);
- }
- inline char st0eIsEmpty_rx(void){
- return (st0E.sRecvHead==st0E.sRecvTail ? 1 : 0);
- }
- inline char st0fIsEmpty_rx(void){
- return (st0F.sRecvHead==st0F.sRecvTail ? 1 : 0);
- }
- inline char st0gIsEmpty_rx(void){
- return (st0G.sRecvHead==st0G.sRecvTail ? 1 : 0);
- }
- inline char st0hIsEmpty_rx(void){
- return (st0H.sRecvHead==st0H.sRecvTail ? 1 : 0);
- }
- inline char st0aIsFull_rx(void){
- return (st0A.sRecvHead==(st0A.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0bIsFull_rx(void){
- return (st0B.sRecvHead==(st0B.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0cIsFull_rx(void){
- return (st0C.sRecvHead==(st0C.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0dIsFull_rx(void){
- return (st0D.sRecvHead==(st0D.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0eIsFull_rx(void){
- return (st0E.sRecvHead==(st0E.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0fIsFull_rx(void){
- return (st0F.sRecvHead==(st0F.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0gIsFull_rx(void){
- return (st0G.sRecvHead==(st0G.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0hIsFull_rx(void){
- return (st0H.sRecvHead==(st0H.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);
- }
- inline char st0aIsEmpty_tx(void){
- return (st0A.sSendHead==st0A.sSendTail ? 1 : 0);
- }
- inline char st0bIsEmpty_tx(void){
- return (st0B.sSendHead==st0B.sSendTail ? 1 : 0);
- }
- inline char st0cIsEmpty_tx(void){
- return (st0C.sSendHead==st0C.sSendTail ? 1 : 0);
- }
- inline char st0dIsEmpty_tx(void){
- return (st0D.sSendHead==st0D.sSendTail ? 1 : 0);
- }
- inline char st0eIsEmpty_tx(void){
- return (st0E.sSendHead==st0E.sSendTail ? 1 : 0);
- }
- inline char st0fIsEmpty_tx(void){
- return (st0F.sSendHead==st0F.sSendTail ? 1 : 0);
- }
- inline char st0gIsEmpty_tx(void){
- return (st0G.sSendHead==st0G.sSendTail ? 1 : 0);
- }
- inline char st0hIsEmpty_tx(void){
- return (st0H.sSendHead==st0H.sSendTail ? 1 : 0);
- }
- inline char st0aIsFull_tx(void){
- return (st0A.sSendHead==(st0A.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0bIsFull_tx(void){
- return (st0B.sSendHead==(st0B.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0cIsFull_tx(void){
- return (st0C.sSendHead==(st0C.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0dIsFull_tx(void){
- return (st0D.sSendHead==(st0D.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0eIsFull_tx(void){
- return (st0E.sSendHead==(st0E.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0fIsFull_tx(void){
- return (st0F.sSendHead==(st0F.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0gIsFull_tx(void){
- return (st0G.sSendHead==(st0G.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline char st0hIsFull_tx(void){
- return (st0H.sSendHead==(st0H.sSendTail+1)%ST_SEND_LEN ? 1 : 0);
- }
- inline void pushST0ARX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0A.abyRecvData[st0A.sRecvTail] = byRx;
- if(!st0aIsFull_rx()){
- st0A.sRecvTail++;
- st0A.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0BRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0B.abyRecvData[st0B.sRecvTail] = byRx;
- if(!st0bIsFull_rx()){
- st0B.sRecvTail++;
- st0B.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0CRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0C.abyRecvData[st0C.sRecvTail] = byRx;
- if(!st0cIsFull_rx()){
- st0C.sRecvTail++;
- st0C.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0DRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0D.abyRecvData[st0D.sRecvTail] = byRx;
- if(!st0dIsFull_rx()){
- st0D.sRecvTail++;
- st0D.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0ERX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0E.abyRecvData[st0E.sRecvTail] = byRx;
- if(!st0eIsFull_rx()){
- st0E.sRecvTail++;
- st0E.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0FRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0F.abyRecvData[st0F.sRecvTail] = byRx;
- if(!st0fIsFull_rx()){
- st0F.sRecvTail++;
- st0F.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0GRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0G.abyRecvData[st0G.sRecvTail] = byRx;
- if(!st0gIsFull_rx()){
- st0G.sRecvTail++;
- st0G.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline void pushST0HRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置
- st0H.abyRecvData[st0H.sRecvTail] = byRx;
- if(!st0hIsFull_rx()){
- st0H.sRecvTail++;
- st0H.sRecvTail %= ST_RECV_LEN;
- }
- }
- inline unsigned char st0apopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0A.abyRecvData[st0A.sRecvHead];
- if(!st0aIsEmpty_rx()){
- st0A.sRecvHead++;
- st0A.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0bpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0B.abyRecvData[st0B.sRecvHead];
- if(!st0bIsEmpty_rx()){
- st0B.sRecvHead++;
- st0B.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0cpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0C.abyRecvData[st0C.sRecvHead];
- if(!st0cIsEmpty_rx()){
- st0C.sRecvHead++;
- st0C.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0dpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0D.abyRecvData[st0D.sRecvHead];
- if(!st0dIsEmpty_rx()){
- st0D.sRecvHead++;
- st0D.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0epopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0E.abyRecvData[st0E.sRecvHead];
- if(!st0eIsEmpty_rx()){
- st0E.sRecvHead++;
- st0E.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0fpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0F.abyRecvData[st0F.sRecvHead];
- if(!st0fIsEmpty_rx()){
- st0F.sRecvHead++;
- st0F.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0gpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0G.abyRecvData[st0G.sRecvHead];
- if(!st0gIsEmpty_rx()){
- st0G.sRecvHead++;
- st0G.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- inline unsigned char st0hpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据
- unsigned char byRet;
- byRet = st0H.abyRecvData[st0H.sRecvHead];
- if(!st0hIsEmpty_rx()){
- st0H.sRecvHead++;
- st0H.sRecvHead %= ST_RECV_LEN;
- }
- return byRet;
- }
- static void InitCommont(ST_COM *pst,int nBaud, unsigned char byMode)
- {
- volatile unsigned char byRx;
- int i;
- if(0 != pst->sInited){
- iounmap((void *) (pst->pbyBase0));
- }
- pst->pbyBase0 = (unsigned char *)ioremap_nocache(pst->nAddress0, 8);
- pst->RBR = (int)(pst->pbyBase0);
- pst->THR = (int)(pst->pbyBase0);
- pst->DLL = (int)(pst->pbyBase0);
- pst->DLM = (int)(pst->pbyBase0+1);
- pst->IER = (int)(pst->pbyBase0+1);
- pst->FCR = (int)(pst->pbyBase0+2);
- pst->IIR = (int)(pst->pbyBase0+2);
- pst->LCR = (int)(pst->pbyBase0+3);
- pst->MCR = (int)(pst->pbyBase0+4);
- pst->LSR = (int)(pst->pbyBase0+5);
- pst->MSR = (int)(pst->pbyBase0+6);
- pst->SPR = (int)(pst->pbyBase0+7);
- pst->sRecvHead = 0;
- pst->sRecvTail = 0;
- pst->sSendHead = 0;
- pst->sSendTail = 0;
- //IER
- //接收保持和中断允许
- *(volatile unsigned char *)(pst->IER) = 0x01;//0x05;
- //FIFO控制器
- //set FCR.FIFO允许,RXD复位,TXD复位,DMAmode=1,触发为14
- *(volatile unsigned char *)(pst->FCR) = 0xcf;
- for(i=0; i<100; i++);
- //set FCR.RXD复位,TXD复位
- *(volatile unsigned char *)(pst->FCR) = 0xc9;
- //Modem状态
- //set MCR.中断A-D开
- //*(volatile unsigned char *)(pst->MCR) = 0x08; //change by zhujiang,our program not use this now
- if(byMode&0x80){
- *(volatile unsigned char *)(pst->LCR) = 0x82|(byMode&0x7f);//7 bit
- }
- else{
- //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器
- *(volatile unsigned char *)(pst->LCR) = 0x83|byMode;
- }
- /***************************************************************************
- ** SET st baudrate.
- BAUD RATE GENRATOR PROGRAMMING TABLE
- Output Baud Rate DLM DLL
- (7.3278MHz Clock) (HEX) (HEX)
- 200 09 00
- 1200 01 80
- 2400 00 C0
- 4800 00 60
- 9600 00 30
- 19.2K 00 18
- 38.4K 00 0C
- 76.8K 00 06
- 153.6K 00 03
- 230.4K 00 02
- 460.8K 00 01
- **
- ***************************************************************************/
- // 特殊寄存器已打开,设置BPS
- // *(volatile unsigned char *)(pst->DLL) = BAUDBASE/nBaud;
- // 高位
- // *(volatile unsigned char *)(pst->DLM) = 0x00;
- switch(nBaud){
- case 200:
- *(volatile unsigned char *)(pst->DLL) = 0x00;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x09;
- break;
- case 1200:
- *(volatile unsigned char *)(pst->DLL) = 0x80;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x01;
- break;
- case 2400:
- *(volatile unsigned char *)(pst->DLL) = 0xC0;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 4800:
- *(volatile unsigned char *)(pst->DLL) = 0x60;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 9600:
- *(volatile unsigned char *)(pst->DLL) = 0x30;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 19200:
- *(volatile unsigned char *)(pst->DLL) = 0x18;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 38400:
- *(volatile unsigned char *)(pst->DLL) = 0x0C;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 76800:
- *(volatile unsigned char *)(pst->DLL) = 0x06;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- case 153600:
- *(volatile unsigned char *)(pst->DLL) = 0x03;
- //高位
- *(volatile unsigned char *)(pst->DLM) = 0x00;
- break;
- default:
- break;
- }
- if(byMode&0x80){
- *(volatile unsigned char *)(pst->LCR) = 0x02|(byMode&0x7f);//7 bit
- }
- else{
- //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器
- *(volatile unsigned char *)(pst->LCR) = 0x03|byMode;
- }
- //空读一次
- byRx = *(volatile unsigned char *)(pst->RBR);
- //读空
- i=0;
- while(1){
- //检查接收状态
- byRx = *(volatile unsigned char *)(pst->LSR);
- if(byRx&0x01){
- byRx = *(volatile unsigned char *)(pst->RBR);
- }
- else
- break;
- //防止死循环
- i++;
- if(i > 4096)//每个UART最多只能缓存16个字节
- break;
- }
- pst->sInited = 1;
- }
- //ST16C554初始化
- void Init_ST0A(int nBaud, unsigned char byMode){
- InitCommont(&st0A,nBaud,byMode);
- }
- void Init_ST0B(int nBaud, unsigned char byMode){
- InitCommont(&st0B,nBaud,byMode);
- }
- void Init_ST0C(int nBaud, unsigned char byMode){
- InitCommont(&st0C,nBaud,byMode);
- }
- void Init_ST0D(int nBaud, unsigned char byMode){
- InitCommont(&st0D,nBaud,byMode);
- }
- void Init_ST0E(int nBaud, unsigned char byMode){
- InitCommont(&st0E,nBaud,byMode);
- }
- void Init_ST0F(int nBaud, unsigned char byMode){
- InitCommont(&st0F,nBaud,byMode);
- }
- void Init_ST0G(int nBaud, unsigned char byMode){
- InitCommont(&st0G,nBaud,byMode);
- }
- void Init_ST0H(int nBaud, unsigned char byMode){
- InitCommont(&st0H,nBaud,byMode);
- }
- //ST16C554的接收
- unsigned char ST0A_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0A.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0A.RBR);
- pushST0ARX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0B_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0B.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0B.RBR);
- pushST0BRX(byRx);
- }
- else{
- break;
- }
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0C_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0C.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0C.RBR);
- pushST0CRX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0D_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0D.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0D.RBR);
- pushST0DRX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0E_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0E.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0E.RBR);
- pushST0ERX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0F_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0F.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0F.RBR);
- pushST0FRX(byRx);
- }
- else{
- break;
- }
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0G_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0G.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0G.RBR);
- pushST0GRX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- unsigned char ST0H_Rxd(void){
- volatile unsigned char byRx;
- volatile unsigned char bySt;
- int nRxCnt = 0;
- while(nRxCnt < 256){
- bySt = *(volatile unsigned char *)(st0H.LSR);//检查接收状态
- if(bySt&0x01){//数据就绪
- byRx = *(volatile unsigned char *)(st0H.RBR);
- pushST0HRX(byRx);
- }
- else
- break;
- nRxCnt++;
- }
- return byRx;
- }
- //ST16C554的发送
- //返回:1,成功
- // 0,失败
- int ST_ComTxd(ST_COM *pst,unsigned char byTxd){
- unsigned char byRx;
- int nTxCnt = 0;
- while(nTxCnt < 256){
- byRx = *(volatile unsigned char *)(pst->LSR);//检查发送状态
- if(byRx&0x20){//发送就绪
- *(volatile unsigned char *)(pst->THR) = byTxd;
- return 1;
- }
- else{
- nTxCnt++;
- }
- }
- return 0;
- }
- static void UART0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
- //save_flags_cli(flags);
- if (st0A.sInited)
- ST0A_Rxd();
- // printk(KERN_INFO "UART0_interrupt1\n" );
- if (st0B.sInited)
- ST0B_Rxd();
- // printk(KERN_INFO "UART0_interrupt2\n" );
- if (st0C.sInited);
- ST0C_Rxd();
- // printk(KERN_INFO "UART0_interrupt3\n" );
- if (st0D.sInited)
- ST0D_Rxd();
- // printk(KERN_INFO "UART0_interrupt4\n" );
- //restore_flags(flags);
- }
- static void UART1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
- if (st0E.sInited)
- ST0E_Rxd();
- // printk(KERN_INFO "UART1_interrupt0\n" );
- if (st0F.sInited)
- ST0F_Rxd();
- // printk(KERN_INFO "UART1_interrupt1\n" );
- if (st0G.sInited)
- ST0G_Rxd();
- // printk(KERN_INFO "UART1_interrupt2\n" );
- if (st0H.sInited)
- ST0H_Rxd();
- // printk(KERN_INFO "UART1_interrupt3\n" );
- }
- static int st16c554_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int st16c554_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int st16c554_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
- {
- int nRet = 0;
- return nRet;
- }
- static int st16c554_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int st16c554_ComWrite(const char *buf, size_t nCount ,ST_COM *mPst)
- {
- int i,j,nRet;
- unsigned char abySend[ST_SEND_LEN];
- int m,k;
- m=nCount/ST_SEND_LEN;
- k=nCount%ST_SEND_LEN;
- for(i=0; i<m; i++){
- if (copy_from_user(abySend,buf+i*ST_SEND_LEN,ST_SEND_LEN)){
- return -EFAULT;
- }
- for(nRet=0; nRet<ST_SEND_LEN; nRet++){
- ST_ComTxd(mPst,abySend[nRet]);
- //ST0A_Txd(abySend[nRet]);
- for(j=0; j<delay_counter; j++);//300000
- // printk("A:%02X\n", abySend[nRet]);
- }
- }
- if (k>0){
- if (copy_from_user(abySend,buf+m*ST_SEND_LEN,k)){
- return -EFAULT;
- }
- for(nRet=0; nRet<k; nRet++){
- ST_ComTxd(mPst,abySend[nRet]);
- //ST0A_Txd(abySend[nRet]);
- for(j=0; j<delay_counter; j++);//300000
- // printk("A:%02X\n", abySend[nRet]);
- }
- }
- return nRet;
- }
- static int ST0A_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0A_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0A_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0A(st0A_init.nBaud, st0A_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0A_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0A_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0A.abyRecvData[st0A.sRecvHead];
- if(st0A.sRecvHead != st0A.sRecvTail){
- st0A.sRecvHead++;
- st0A.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0A_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0A);
- }
- static int ST0A_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0B_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0B_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0B_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0B(st0B_init.nBaud, st0B_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0B_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0B_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0B.abyRecvData[st0B.sRecvHead];
- if(st0B.sRecvHead != st0B.sRecvTail){
- st0B.sRecvHead++;
- st0B.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0B_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0B);
- }
- static int ST0B_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0C_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0C_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0C_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0C(st0C_init.nBaud, st0C_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0C_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0C_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0C.abyRecvData[st0C.sRecvHead];
- if(st0C.sRecvHead != st0C.sRecvTail){
- st0C.sRecvHead++;
- st0C.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0C_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0C);
- }
- static int ST0C_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0D_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0D_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0D_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0D(st0D_init.nBaud, st0D_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0D_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0D_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0D.abyRecvData[st0D.sRecvHead];
- if(st0D.sRecvHead != st0D.sRecvTail){
- st0D.sRecvHead++;
- st0D.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- // printk("D-:%02X\n", abyRecv[i]);
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0D_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0D);
- }
- static int ST0D_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0E_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0E_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0E_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0E(st0E_init.nBaud, st0E_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0E_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0E_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0E.abyRecvData[st0E.sRecvHead];
- if(st0E.sRecvHead != st0E.sRecvTail){
- st0E.sRecvHead++;
- st0E.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0E_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0E);
- }
- static int ST0E_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0F_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0F_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0F_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0F(st0F_init.nBaud, st0F_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0F_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0F_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0F.abyRecvData[st0F.sRecvHead];
- if(st0F.sRecvHead != st0F.sRecvTail){
- st0F.sRecvHead++;
- st0F.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0F_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0F);
- }
- static int ST0F_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0G_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0G_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0G_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0G(st0G_init.nBaud, st0G_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0G_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0G_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0G.abyRecvData[st0G.sRecvHead];
- if(st0G.sRecvHead != st0G.sRecvTail){
- st0G.sRecvHead++;
- st0G.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0G_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0G);
- }
- static int ST0G_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static int ST0H_open(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_INC_USE_COUNT;
- return nRet;
- }
- static int ST0H_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
- {
- int nRet = 0;
- switch(cmd) {
- case ST_INIT:
- copy_from_user(&st0H_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));
- Init_ST0H(st0H_init.nBaud, st0H_init.byMode);
- break;
- default:
- return -EINVAL;
- }
- return nRet;
- }
- static int ST0H_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
- {
- int i;
- int nLen;
- unsigned char abyRecv[ST_RECV_LEN];
- nLen = get_ST0H_rxLen();
- nLen = nLen>count ? count : nLen;
- for(i=0; i<nLen; i++){
- abyRecv[i] = st0H.abyRecvData[st0H.sRecvHead];
- if(st0H.sRecvHead != st0H.sRecvTail){
- st0H.sRecvHead++;
- st0H.sRecvHead %= ST_RECV_LEN;
- }
- else
- break;
- // printk("D-:%02X\n", abyRecv[i]);
- }
- copy_to_user((void *)buf, &abyRecv, i);
- return i;
- }
- static int ST0H_write (struct file *file, const char *buf, size_t count, loff_t *ppos){
- return st16c554_ComWrite(buf,count,&st0H);
- }
- static int ST0H_release(struct inode *inode, struct file *filp)
- {
- int nRet = 0;
- MOD_DEC_USE_COUNT;
- return nRet;
- }
- static struct file_operations st16c554_fops = {
- owner: THIS_MODULE,
- open: st16c554_open,
- ioctl: st16c554_ioctl,
- read: st16c554_read,
- release: st16c554_release,
- };
- static struct file_operations ST0A_fops = {
- owner: THIS_MODULE,
- open: ST0A_open,
- ioctl: ST0A_ioctl,
- read: ST0A_read,
- write: ST0A_write,
- release: ST0A_release,
- };
- static struct file_operations ST0B_fops = {
- owner: THIS_MODULE,
- open: ST0B_open,
- ioctl: ST0B_ioctl,
- read: ST0B_read,
- write: ST0B_write,
- release: ST0B_release,
- };
- static struct file_operations ST0C_fops = {
- owner: THIS_MODULE,
- open: ST0C_open,
- ioctl: ST0C_ioctl,
- read: ST0C_read,
- write: ST0C_write,
- release: ST0C_release,
- };
- static struct file_operations ST0D_fops = {
- owner: THIS_MODULE,
- open: ST0D_open,
- ioctl: ST0D_ioctl,
- read: ST0D_read,
- write: ST0D_write,
- release: ST0D_release,
- };
- static struct file_operations ST0E_fops = {
- owner: THIS_MODULE,
- open: ST0E_open,
- ioctl: ST0E_ioctl,
- read: ST0E_read,
- write: ST0E_write,
- release: ST0E_release,
- };
- static struct file_operations ST0F_fops = {
- owner: THIS_MODULE,
- open: ST0F_open,
- ioctl: ST0F_ioctl,
- read: ST0F_read,
- write: ST0F_write,
- release: ST0F_release,
- };
- static struct file_operations ST0G_fops = {
- owner: THIS_MODULE,
- open: ST0G_open,
- ioctl: ST0G_ioctl,
- read: ST0G_read,
- write: ST0G_write,
- release: ST0G_release,
- };
- static struct file_operations ST0H_fops = {
- owner: THIS_MODULE,
- open: ST0H_open,
- ioctl: ST0H_ioctl,
- read: ST0H_read,
- write: ST0H_write,
- release: ST0H_release,
- };
- static devfs_handle_t devfs_st_dir, devfs_ST0A, devfs_ST0B, devfs_ST0C, devfs_ST0D;
- static devfs_handle_t devfs_ST0E, devfs_ST0F, devfs_ST0G, devfs_ST0H;
- static int __init st16c554_init(void)
- {
- int ret;
- printk(KERN_INFO "Init ST16C554 ......\n" );
- mtdcr(DCRN_EBC0_CFGADDR, DCRN_EBC0_B3CR);
- printk(KERN_INFO "B3CR1=== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );
- mtdcr(DCRN_EBC0_CFGDATA, 0xf0218000); //SET PCS3 BASEADDR
- printk(KERN_INFO "B3CR2== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );
- ret = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &st16c554_fops);
- if (ret < 0) {
- printk(DEVICE_NAME " can't get major number\n");
- return ret;
- }
- stMajor = ret;
- devfs_st_dir = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
- if (devfs_st_dir == NULL)
- printk( " devfs_mk_dir() error! \n");
- devfs_ST0A = devfs_register(devfs_st_dir, "0", DEVFS_FL_DEFAULT, // dev/st16c554/0 for ST0A
- stMajor, ST0A, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0A_fops, NULL);
- devfs_ST0B = devfs_register(devfs_st_dir, "1", DEVFS_FL_DEFAULT, // dev/st16c554/1 for ST0B
- stMajor, ST0B, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0B_fops, NULL);
- devfs_ST0C = devfs_register(devfs_st_dir, "2", DEVFS_FL_DEFAULT, // dev/st16c554/2 for ST0C
- stMajor, ST0C, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0C_fops, NULL);
- devfs_ST0D = devfs_register(devfs_st_dir, "3", DEVFS_FL_DEFAULT, // dev/st16c554/3 for ST0D
- stMajor, ST0D, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0D_fops, NULL);
- devfs_ST0E = devfs_register(devfs_st_dir, "4", DEVFS_FL_DEFAULT, // dev/st16c554/4 for ST0E
- stMajor, ST0E, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0E_fops, NULL);
- devfs_ST0F = devfs_register(devfs_st_dir, "5", DEVFS_FL_DEFAULT, // dev/st16c554/5 for ST0F
- stMajor, ST0F, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0F_fops, NULL);
- devfs_ST0G = devfs_register(devfs_st_dir, "6", DEVFS_FL_DEFAULT, // dev/st16c554/6 for ST0G
- stMajor, ST0G, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0G_fops, NULL);
- devfs_ST0H = devfs_register(devfs_st_dir, "7", DEVFS_FL_DEFAULT, // dev/st16c554/7 for ST0H
- stMajor, ST0H, S_IFCHR | S_IRUSR | S_IWUSR,
- &ST0H_fops, NULL);
- ret = request_irq(YC_mul232_IRQ0, UART0_interrupt, SA_INTERRUPT, "ST16C554_0_RX Ready", UART0_interrupt);
- if(ret) {
- printk("ST16C554: failed to register IRQ_EINT0(%d)\n", YC_mul232_IRQ0);
- goto UART0_failed;
- }
- ret = request_irq(YC_mul232_IRQ1, UART1_interrupt, SA_INTERRUPT, "ST16C554_1_RX Ready", UART1_interrupt);
- if(ret) {
- printk("ST16C554: failed to register IRQ_EINT1(%d)\n", YC_mul232_IRQ1);
- goto UART1_failed;
- }
- return 0;
- UART1_failed:
- free_irq(YC_mul232_IRQ1, NULL);
- UART0_failed:
- printk("ST16C554 DEVICE: failed to register \n");
- devfs_unregister(devfs_ST0D);
- devfs_unregister(devfs_ST0C);
- devfs_unregister(devfs_ST0B);
- devfs_unregister(devfs_ST0A);
- devfs_unregister(devfs_ST0E);
- devfs_unregister(devfs_ST0F);
- devfs_unregister(devfs_ST0G);
- devfs_unregister(devfs_ST0H);
- devfs_unregister(devfs_st_dir);
- unregister_chrdev(stMajor, DEVICE_NAME);
- return 0;
- }
- static void __exit st16c554_exit(void)
- {
- free_irq(YC_mul232_IRQ0, NULL);
- free_irq(YC_mul232_IRQ1, NULL);
- devfs_unregister(devfs_ST0D);
- devfs_unregister(devfs_ST0C);
- devfs_unregister(devfs_ST0B);
- devfs_unregister(devfs_ST0A);
- devfs_unregister(devfs_ST0E);
- devfs_unregister(devfs_ST0F);
- devfs_unregister(devfs_ST0G);
- devfs_unregister(devfs_ST0H);
- devfs_unregister(devfs_st_dir);
- unregister_chrdev(stMajor, DEVICE_NAME);
- iounmap((void *) (st0A.pbyBase0));
- iounmap((void *) (st0B.pbyBase0));
- iounmap((void *) (st0C.pbyBase0));
- iounmap((void *) (st0D.pbyBase0));
- iounmap((void *) (st0E.pbyBase0));
- iounmap((void *) (st0F.pbyBase0));
- iounmap((void *) (st0G.pbyBase0));
- iounmap((void *) (st0H.pbyBase0));
- }
- module_init(st16c554_init);
- module_exit(st16c554_exit);