//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.

  Module Name: common_pdd_ser.h 

Abstract:

Platform dependent Serial definitions for UART controller.

Notes: 
--*/
#ifndef __PDDSER_H_
#define __PDDSER_H_
#include <cmthread.h>
#include <cserpdd.h>
#include <register_map.h>
#include <bsp_cfg.h>
#include <dma_controller.h>
#include "ser_dma.h"
extern DBGPARAM dpCurSettings;

#ifndef UARTDRV_DEBUGZONES
#define UARTDRV_DEBUGZONES           (ZONEMASK_ERROR |\
        ZONEMASK_WARNING |\
        ZONEMASK_TEMP |\
        ZONEMASK_THREAD |\
        ZONEMASK_INIT |\
        ZONEMASK_OPEN |\
        ZONEMASK_CLOSE |\
        ZONEMASK_IOCTL)

#endif

#ifndef UARTDRV_RETAILZONES
#define UARTDRV_RETAILZONES          (ZONEMASK_ERROR)
#endif

#ifdef  UART_PDD_DRIVER_DEBUG
#define UARTDRV_ZONES    UARTDRV_DEBUGZONES
#else
#define UARTDRV_ZONES    UARTDRV_RETAILZONES
#endif




#ifdef  UART_PDD_DRIVER_DEBUG

#define ZONEID_ERROR          0
#define ZONEID_WARNING        1
#define ZONEID_PERF           2
#define ZONEID_TEMP           3
#define ZONEID_THREAD         4
#define ZONEID_INIT           5
#define ZONEID_OPEN           7
#define ZONEID_CLOSE          8
#define ZONEID_IOCTL          9
#define ZONEID_READ           10
#define ZONEID_WRITE          11

#define UART_ZONE_ERROR        DEBUGZONE(ZONEID_ERROR)
#define UART_ZONE_WARNING      DEBUGZONE(ZONEID_WARNING)
#define UART_ZONE_PERF         DEBUGZONE(ZONEID_PERF)
#define UART_ZONE_TEMP         DEBUGZONE(ZONEID_TEMP)
#define UART_ZONE_THREAD       DEBUGZONE(ZONEID_THREAD)
#define UART_ZONE_INIT         DEBUGZONE(ZONEID_INIT)
#define UART_ZONE_OPEN         DEBUGZONE(ZONEID_OPEN)
#define UART_ZONE_CLOSE        DEBUGZONE(ZONEID_CLOSE)
#define UART_ZONE_IOCTL        DEBUGZONE(ZONEID_IOCTL)
#define UART_ZONE_READ         DEBUGZONE(ZONEID_READ)
#define UART_ZONE_WRITE        DEBUGZONE(ZONEID_WRITE)

#define ZONEMASK_ERROR         (1 << ZONEID_ERROR)
#define ZONEMASK_WARNING       (1 << ZONEID_WARNING)
#define ZONEMASK_PERF          (1 << ZONEID_PERF)
#define ZONEMASK_TEMP          (1 << ZONEID_TEMP)
#define ZONEMASK_THREAD        (1 << ZONEID_THREAD)
#define ZONEMASK_INIT          (1 << ZONEID_INIT)
#define ZONEMASK_OPEN          (1 << ZONEID_OPEN)
#define ZONEMASK_CLOSE         (1 << ZONEID_CLOSE)
#define ZONEMASK_IOCTL         (1 << ZONEID_IOCTL)
#define ZONEMASK_CAMIF         (1 << ZONEID_READ)
#define ZONEMASK_POSTIF        (1 << ZONEID_WRITE)

#endif

//IOCTL Definitions
#define SERIAL_PORT_FUNC_CODE_BASE  2100

//-------------------------------------------------------------------------
// BSP IOCTLs (2100 ~ 2101)
//-------------------------------------------------------------------------
#define IOCTL_REQUEST_UART_SAVE_POWER         CTL_CODE(FILE_DEVICE_SERIAL_PORT, (SERIAL_PORT_FUNC_CODE_BASE+0), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_UART_FULL_POWER         CTL_CODE(FILE_DEVICE_SERIAL_PORT, (SERIAL_PORT_FUNC_CODE_BASE+1), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_ENABLE_AFC              CTL_CODE(FILE_DEVICE_SERIAL_PORT, (SERIAL_PORT_FUNC_CODE_BASE+2), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_DISABLE_AFC             CTL_CODE(FILE_DEVICE_SERIAL_PORT, (SERIAL_PORT_FUNC_CODE_BASE+3), METHOD_BUFFERED, FILE_ANY_ACCESS)
//------------------------------------------------------------------------------


#define UART0_POWER_NAME L"COM1:"
#define UART1_POWER_NAME L"COM2:"
#define UART2_POWER_NAME L"COM3:"
#define UART3_POWER_NAME L"COM4:"

#define  DISABLE     0
#define  ENABLE      1


#define  CLK_UART0_SEL      16  
#define  CLK_UART1_SEL      20
#define  CLK_UART2_SEL      24  
#define  CLK_UART3_SEL      28  



#define  CLK_UART0_PASS      (1 << 17)  
#define  CLK_UART1_PASS      (1 << 18)  
#define  CLK_UART2_PASS      (1 << 19)  
#define  CLK_UART3_PASS      (1 << 20)  

#define  CLK_UART0_MASK      (~(1 << 17))
#define  CLK_UART1_MASK      (~(1 << 18))
#define  CLK_UART2_MASK      (~(1 << 19))
#define  CLK_UART3_MASK      (~(1 << 20))

#define  CLK_SRC_MASK0_UART0_ENABLE      (1 << 12)
#define  CLK_SRC_MASK0_UART1_ENABLE      (1 << 13)
#define  CLK_SRC_MASK0_UART2_ENABLE      (1 << 14)
#define  CLK_SRC_MASK0_UART3_ENABLE      (1 << 15)

#define  CLK_SRC_MASK0_UART0_DISABLE      (~(1 << 12))
#define  CLK_SRC_MASK0_UART1_DISABLE      (~(1 << 13))
#define  CLK_SRC_MASK0_UART2_DISABLE      (~(1 << 14))
#define  CLK_SRC_MASK0_UART3_DISABLE      (~(1 << 15))


#define    DEFAULT_PCLK    (PCLKPSYS)


#define    DEFAULT_VALUE_WATER_MARK 8
#define    DEFAULT_VALUE_MEM_LENGTH 0x40
#define    TIMEOUT_TX_EMPTY         1000

#define    PCLK_UART0               (1<<0)
#define    PCLK_UART1               (1<<1)
#define    PCLK_UART2               (1<<2)
#define    PCLK_UART3               (1<<3)
#define    SCLK_UART                (1<<3)

#define    DTR_PORT_NUMBER          1
#define    DSR_PORT_NUMBER          2
#define    BASE_REG_OFFSET_UART 0x400

/////////////////////////////////////////////////////////////////////////////////////////
//// S5PV210 UART Register Bit Definition

/*---------------------------------------------------------*/
//UART Line Control Register ULCON
/*---------------------------------------------------------*/
//Mode
#define    LCR_NORMAL_MODE                 (0 << 6)
#define    LCR_IR_MODE                     (1 << 6)
#define    LCR_MODE_MASK                   (1 << 6)
//Parity
#define    LCR_NO_PARITY                   (0 << 3)
#define    LCR_PARITY_ODD                  (4 << 3)
#define    LCR_PARITY_EVEN                 (5 << 3)
#define    LCR_PARITY_FORCE_1              (6 << 3)
#define    LCR_PARITY_FORCE_0              (7 << 3)
#define    LCR_PARITY_MASK                 (7 << 3)
//Stop Bit
#define    LCR_1_STOPBIT                   (0 << 2)
#define    LCR_2_STOPBITS                  (1 << 2)
#define    LCR_STOPBIT_MASK                (1 << 2)
//Data Length
#define    LCR_DATA_LENGTH_5BIT            (0 << 0)
#define    LCR_DATA_LENGTH_6BIT            (1 << 0)
#define    LCR_DATA_LENGTH_7BIT            (2 << 0)
#define    LCR_DATA_LENGTH_8BIT            (3 << 0)
#define    LCR_DATA_LENGTH_MASK            (3 << 0)


/*---------------------------------------------------------*/
//UART Control Register UCON
/*---------------------------------------------------------*/

//Tx DMA Burst Size 
#define    TX_DMA_BURST_1_BYTE            (0 << 20)
#define    TX_DMA_BURST_4_BYTE            (1 << 20)
#define    TX_DMA_BURST_8_BYTE            (2 << 20)
#define    TX_DMA_BURST_16_BYTE           (3 << 20)
#define    TX_DMA_BURST_32_BYTE           (4 << 20)
#define    TX_DMA_BURST_64_BYTE           (5 << 20)
#define    TX_DMA_BURST_128_BYTE          (6 << 20)
#define    TX_DMA_BURST_256_BYTE          (7 << 20)

//Rx DMA Burst Size 
#define    RX_DMA_BURST_1_BYTE            (0 << 16)
#define    RX_DMA_BURST_4_BYTE            (1 << 16)
#define    RX_DMA_BURST_8_BYTE            (2 << 16)
#define    RX_DMA_BURST_16_BYTE           (3 << 16)
#define    RX_DMA_BURST_32_BYTE           (4 << 16)
#define    RX_DMA_BURST_64_BYTE           (5 << 16)
#define    RX_DMA_BURST_128_BYTE          (6 << 16)
#define    RX_DMA_BURST_256_BYTE          (7 << 16)

//Clock Selection
#define    CLKSEL_PCLK                    (0 << 10)
#define    CLKSEL_SCLK                    (1 << 10)
#define    CLKSEL_MASK                    (1 << 10)

//Tx Interrupt Type
#define    TX_INT_TYPE_PULSE               (0 << 9)
#define    TX_INT_TYPE_LEVEL               (1 << 9)
#define    TX_INT_TYPE_MASK                (1 << 9)

//Rx Interrupt Type
#define    RX_INT_TYPE_PULSE               (0 << 8)
#define    RX_INT_TYPE_LEVEL               (1 << 8)
#define    RX_INT_TYPE_MASK                (1 << 8)

//Rx Time Out Enable
#define    RX_TIMEOUT_DISABLE              (0 << 7)
#define    RX_TIMEOUT_ENABLE               (1 << 7)
#define    RX_TIMEOUT_MASK                 (1 << 7)

//Rx Error Status Interrupt Enable
#define    RX_ERR_INT_DISABLE              (0 << 6)
#define    RX_ERR_INT_ENABLE               (1 << 6)
#define    RX_ERR_INT_MASK                 (1 << 6)

//Loop-back Mode
#define    LOOPBACK_DISABLE                (0 << 5)
#define    LOOPBACK_ENABLE                 (1 << 5)
#define    LOOPBACK_MASK                   (1 << 5)

//Send Break Signal
#define    BREAK_SIGNAL_DISABLE            (0 << 4)
#define    BREAK_SIGNAL_ENABLE             (1 << 4)
#define    BREAK_SIGNAL_MASK               (1 << 4)

//Transmit Mode
#define    TX_DISABLE                      (0 << 2)
#define    TX_INT_POLL                     (1 << 2)
#define    TX_DMA_MODE                     (2 << 2)
#define    TX_MODE_MASK                    (3 << 2)

//Receive Mode
#define    RX_DISABLE                      (0 << 0)
#define    RX_INT_POLL                     (1 << 0)
#define    RX_DMA_MODE                     (2 << 0)
#define    RX_MODE_MASK                    (3 << 0)


/*---------------------------------------------------------*/
//UART FIFO Control Register  UFCON
/*---------------------------------------------------------*/
//Tx FIFO Trigger Level
#define    FCR_TX_FIFO_TRIG_1              (0 << 8)
#define    FCR_TX_FIFO_TRIG_4              (1 << 8)
#define    FCR_TX_FIFO_TRIG_8              (2 << 8)
#define    FCR_TX_FIFO_TRIG_16             (3 << 8)
#define    FCR_TX_FIFO_TRIG_32             (4 << 8)
#define    FCR_TX_FIFO_TRIG_64             (5 << 8)
#define    FCR_TX_FIFO_TRIG_128            (6 << 8)
#define    FCR_TX_FIFO_TRIG_256            (7 << 8)
#define    FCR_TX_FIFO_TRIG_MASK           (7 << 8)

//Rx FIFO Trigger Level
#define    FCR_RX_FIFO_TRIG_1              (0 << 4)
#define    FCR_RX_FIFO_TRIG_4              (1 << 4)
#define    FCR_RX_FIFO_TRIG_8              (2 << 4)
#define    FCR_RX_FIFO_TRIG_16             (3 << 4)
#define    FCR_RX_FIFO_TRIG_32             (4 << 4)
#define    FCR_RX_FIFO_TRIG_64             (5 << 4)
#define    FCR_RX_FIFO_TRIG_128            (6 << 4)
#define    FCR_RX_FIFO_TRIG_256            (7 << 4)
#define    FCR_RX_FIFO_TRIG_MASK           (7 << 4)
#define    FCR_RX_FIFO_TRIG_SHIFT          (4)

//Tx FIFO Reset
#define    FCR_TX_FIFO_RESET               (1 << 2)

//Rx FIFO Reset
#define    FCR_RX_FIFO_RESET               (1 << 1)

//FIFO Enable
#define    FCR_FIFO_DISABLE                (0 << 0)
#define    FCR_FIFO_ENABLE                 (1 << 0)

/*---------------------------------------------------------*/
//UART Modem Control Register  UMCR
/*---------------------------------------------------------*/
//RTS Trigger Level
#define    CH0_MCR_RTS_TRIG_255          (0 << 5)
#define    CH0_MCR_RTS_TRIG_224          (1 << 5)
#define    CH0_MCR_RTS_TRIG_192          (2 << 5)
#define    CH0_MCR_RTS_TRIG_160          (3 << 5)
#define    CH0_MCR_RTS_TRIG_128          (4 << 5)
#define    CH0_MCR_RTS_TRIG_96           (5 << 5)
#define    CH0_MCR_RTS_TRIG_64           (6 << 5)
#define    CH0_MCR_RTS_TRIG_32           (7 << 5)
#define    CH0_MCR_RTS_TRIG_MASK         (7 << 5)

//RTS Trigger Level
#define    CH1_MCR_RTS_TRIG_63           (0 << 5)
#define    CH1_MCR_RTS_TRIG_56           (1 << 5)
#define    CH1_MCR_RTS_TRIG_48           (2 << 5)
#define    CH1_MCR_RTS_TRIG_40           (3 << 5)
#define    CH1_MCR_RTS_TRIG_32           (4 << 5)
#define    CH1_MCR_RTS_TRIG_24           (5 << 5)
#define    CH1_MCR_RTS_TRIG_16           (6 << 5)
#define    CH1_MCR_RTS_TRIG_8            (7 << 5)
#define    CH1_MCR_RTS_TRIG_MASK         (7 << 5)

//RTS Trigger Level
#define    CH2_MCR_RTS_TRIG_15           (0 << 5)
#define    CH2_MCR_RTS_TRIG_14           (1 << 5)
#define    CH2_MCR_RTS_TRIG_12           (2 << 5)
#define    CH2_MCR_RTS_TRIG_10           (3 << 5)
#define    CH2_MCR_RTS_TRIG_8            (4 << 5)
#define    CH2_MCR_RTS_TRIG_6            (5 << 5)
#define    CH2_MCR_RTS_TRIG_4            (6 << 5)
#define    CH2_MCR_RTS_TRIG_2            (7 << 5)
#define    CH2_MCR_RTS_TRIG_MASK         (7 << 5)

//Auto Flow Control (AFC)
#define    MCR_AUTO_FLOW_DISABLE           (0 << 4)
#define    MCR_AUTO_FLOW_ENABLE            (1 << 4)
#define    MCR_AUTO_FLOW_MASK              (1 << 4)

//Modem Interrupt Enable
#define    MCR_MODEM_INTERRUPT_DISABLE     (0 << 3)
#define    MCR_MODEM_INTERRUPT_ENABLE      (1 << 3)
#define    MCR_MODEM_INTERRUPT_MASK        (1 << 3)

//Request To Send (RTS)
#define    MCR_CLEAR_RTS                   (0 << 0)
#define    MCR_SET_RTS                     (1 << 0)
#define    MCR_RTS_MASK                    (1 << 0)

/*---------------------------------------------------------*/
//UART TX/RX Status Register USR
/*---------------------------------------------------------*/
//Transmitter Empty
#define    TRANSMITTER_NOT_EMPTY           (0 << 2)
#define    TRANSMITTER_EMPTY               (1 << 2)
#define    TRANSMITTER_STATUS_MASK         (1 << 2)

//Transmitter Buffer Empty
#define    TX_BUFFER_NOT_EMPTY             (0 << 1)
#define    TX_BUFFER_EMPTY                 (1 << 1)
#define    TX_BUFFER_STATUS_MASK           (1 << 1)

//Receive Buffer Data Ready
#define    RX_BUFFER_EMPTY                 (0 << 0)
#define    RX_BUFFER_NOT_EMPTY             (1 << 0)
#define    RX_BUFFER_STATUS_MASK           (1 << 0)

/*---------------------------------------------------------*/
//UART Error Status Register UESR
/*---------------------------------------------------------*/
#define    ESR_BREAK_DETECT            (1 << 3)
#define    ESR_FRAME_ERROR             (1 << 2)
#define    ESR_PARITY_ERROR            (1 << 1)
#define    ESR_OVERRUN_ERROR           (1 << 0)

/*---------------------------------------------------------*/
//UART FIFO Status Register UFSR
/*---------------------------------------------------------*/
//Tx FIFO Full
#define    FSR_TX_FIFO_NOT_FULL            (0 << 24)
#define    FSR_TX_FIFO_FULL                (1 << 24)
#define    FSR_TX_FIFO_MASK                (1 << 24)

//Tx FIFO Count
#define    FSR_TX_FIFO_COUNT_MASK          (0xFF << 16)     
#define    FSR_TX_FIFO_COUNT_SHIFT         (16)

//Rx FIFO Full
#define    FSR_RX_FIFO_NOT_FULL            (0 << 8)
#define    FSR_RX_FIFO_FULL                (1 << 8)
#define    FSR_RX_FIFO_MASK                (1 << 8)

//Rx FIFO Count
#define    FSR_RX_FIFO_COUNT_MASK          (0xFF << 0)    
#define    FSR_RX_FIFO_COUNT_SHIFT         (0)

/*---------------------------------------------------------*/
//UART Modem Status Register UMSR
/*---------------------------------------------------------*/
#define    MSR_DELTA_CTS                   (1 << 4)
//Clear to Send (CTS)
#define    MSR_CTS                         (1 << 0)

/*---------------------------------------------------------*/
//UART Interrupt Pending Register, 
//UART Interrupt Source Pending Register,
//UART Interrupt Mask Register
/*---------------------------------------------------------*/
#define    INT_RXD                    (1 << 0)
#define    INT_ERR                    (1 << 1)
#define    INT_TXD                    (1 << 2)
#define    INT_MODEM                  (1 << 3)
////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////
// Required Registry Setting.
#define    PC_REG_UART_IST_TIMEOUTS_VAL_NAME   TEXT("ISTTimeouts")
#define    PC_REG_UART_IST_TIMEOUTS_VAL_LEN    sizeof(DWORD)
#define    PC_REG_UART_MEM_LENGTH_VAL_NAME     TEXT("MemLen")
#define    PC_REG_UART_MEM_LENGTH_VAL_LEN      sizeof(DWORD)
#define    PC_REG_UART_AFC_EN_NAME                   TEXT("AFCEnable") 

#ifdef USE_DMA
#define    PC_REG_UART_TX_DMA_EN_NAME                   TEXT("TXDMAEnable") 
#endif 
/////////////////////////////////////////////////////////////////////////////////////////

// WaterMarker Pairs.
typedef struct  __PAIRS
{
        ULONG   Key;
        ULONG   AssociatedValue;
} PAIRS, *PPAIRS;

static const UINT UDIVSLOT_TABLE[16] = 
{
        0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4A52, 0x54AA,
        0x5555, 0xD555, 0xD5D5, 0xDDD5, 0xDDDD, 0xDFDD, 0xDFDF, 0xFFDF
};

//Forward Declaration of CPddUart
class CPddUart;

class CRegPDDUart
{
    public:
        CRegPDDUart(PULONG pRegAddr);
        virtual ~CRegPDDUart() { ; };
        virtual BOOL    Init() ;
        // We do not virtual Read & Write data because of Performance Concern.
        void    Write_ULCON(ULONG uData) { WRITE_REGISTER_ULONG( m_pReg, (uData)); };
        ULONG   Read_ULCON() { return (READ_REGISTER_ULONG(m_pReg)); } ;
        void    Write_UCON (ULONG uData) { WRITE_REGISTER_ULONG(m_pReg+1 , uData); };
        ULONG   Read_UCON() { return READ_REGISTER_ULONG(m_pReg+1 ); };
        void    Write_UFCON(ULONG uData) { WRITE_REGISTER_ULONG( m_pReg+2, uData);};
        ULONG   Read_UFCON() { return READ_REGISTER_ULONG(m_pReg + 2); };
        void    Write_UMCON(ULONG uData) { WRITE_REGISTER_ULONG(m_pReg + 3, uData);};
        ULONG   Read_UMCON() { return READ_REGISTER_ULONG(m_pReg + 3);};
        ULONG   Read_UTRSTAT() { return READ_REGISTER_ULONG(m_pReg + 4);};
        ULONG   Read_UERSTAT() { return READ_REGISTER_ULONG(m_pReg + 5);};
        ULONG   Read_UFSTAT() { return READ_REGISTER_ULONG(m_pReg + 6);};
        ULONG   Read_UMSTAT() { return READ_REGISTER_ULONG(m_pReg + 7);};
        void    Write_UTXH (UINT8 uData) { WRITE_REGISTER_ULONG( (m_pReg + 8), uData) ; };
        UINT8   Read_URXH() { return (UINT8) READ_REGISTER_ULONG(m_pReg + 9); };
        void    Write_UBRDIV(ULONG uData) { WRITE_REGISTER_ULONG( m_pReg + 10, uData );};
        ULONG   Read_UBRDIV() { return READ_REGISTER_ULONG(m_pReg + 10); };
        void    Write_UDIVSLOT(ULONG uData) { WRITE_REGISTER_ULONG( (m_pReg + 11), uData) ; };
        ULONG    Read_UDIVSLOT() { return READ_REGISTER_ULONG(m_pReg + 11); };
        void    Write_UINTP(ULONG uData) { WRITE_REGISTER_ULONG( (m_pReg + 12), uData) ; };
        ULONG    Read_UINTP() { return READ_REGISTER_ULONG(m_pReg + 12); };
        void    Write_UINTSP(ULONG uData) { WRITE_REGISTER_ULONG( (m_pReg + 13), uData) ; };
        ULONG    Read_UINTSP() { return READ_REGISTER_ULONG(m_pReg + 13); };
        void    Write_UINTM(ULONG uData) { WRITE_REGISTER_ULONG( (m_pReg + 14), uData) ; };
        ULONG    Read_UINTM() { return READ_REGISTER_ULONG(m_pReg + 14); };    

        virtual BOOL    Write_BaudRate(ULONG uData);
        PULONG  GetRegisterVirtualAddr() { return m_pReg; };
        virtual void    Backup();
        virtual void    Restore();
#ifdef DEBUG
        virtual void    DumpRegister();
#endif

                CPddUart * m_hCPddUart;
    protected:
        volatile PULONG const  m_pReg;
        BOOL    m_fIsBackedUp;

    private:
        ULONG    m_ULCONBackup;
        ULONG    m_UCONBackup;
        ULONG    m_UFCONBackup;
        ULONG    m_UMCOMBackup;
        ULONG    m_UBRDIVBackup;
        ULONG    m_UDIVSLOTBackup;
        ULONG    m_UINTMBackup;

        ULONG    m_BaudRate;
        ULONG    m_s5pv210_pclk;
};
class CPddUart: public CSerialPDD, public CMiniThread  
{
    public:
        CPddUart (LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj);
        virtual ~CPddUart();
        virtual BOOL Init();
        virtual void PostInit();
        virtual BOOL MapHardware();
        virtual BOOL CreateHardwareAccess();
        //  Power Manager Required Function.
        virtual void    SerialRegisterBackup() { m_pRegUart->Backup(); };
        virtual void    SerialRegisterRestore() { m_pRegUart->Restore(); };

        // Implement CPddSerial Function.
        virtual BOOL SetDCB(LPDCB lpDCB) 
        {
                BOOL success;

                success = CSerialPDD::SetDCB(lpDCB);

                if (success) 
                {  
                        if (m_UseAutoFlow) 
                        {
                                m_HardwareLock.Lock();

                                DWORD dwBit = m_pRegUart->Read_UMCON();

                                dwBit &= ~MCR_AUTO_FLOW_MASK;
                                dwBit &= ~CH0_MCR_RTS_TRIG_MASK;

                                if (m_DCB.fOutxCtsFlow && (m_DCB.fRtsControl == RTS_CONTROL_HANDSHAKE)) 
                                {
                                        dwBit |= (MCR_AUTO_FLOW_ENABLE | CH0_MCR_RTS_TRIG_224);
                                        m_AutoFlowEnabled = TRUE;          
                                                DBGMSG(TRUE, (TEXT("[UART] *** UART AutoFlow enabled: 0x%X  \r\n"),dwBit));
                                } 
                                else 
                                {
                                        m_AutoFlowEnabled = FALSE;
                                }

                                m_pRegUart->Write_UMCON(dwBit); 

                                m_HardwareLock.Unlock();
                        }
                }

                return success;
        }

        // Interrupt
        virtual BOOL    InitialEnableInterrupt(BOOL bEnable ) ;
    private:
        //  IST
        virtual DWORD ThreadRun(); 
    public:

        //  Tx Function.
        virtual BOOL    InitXmit(BOOL bInit);
        virtual void    XmitInterruptHandler(PUCHAR pTxBuffer, ULONG *pBuffLen);
        virtual void    XmitComChar(UCHAR ComChar);
        virtual BOOL    EnableXmitInterrupt(BOOL bEnable);
        virtual BOOL    CancelXmit();
        virtual DWORD   GetWriteableSize();
        virtual DWORD   GetFifoDepth();
    protected:
        BOOL    m_XmitFifoEnable;
        HANDLE  m_XmitFlushDone;
    public:
        //  Rx Function.
        virtual BOOL    InitReceive(BOOL bInit);
        virtual ULONG   ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen);
        virtual ULONG   CancelReceive();
        virtual DWORD   GetWaterMark();
        virtual BYTE    GetWaterMarkBit();
        virtual void    Rx_Pause(BOOL bSet) {;};
    protected:
        BOOL    m_bReceivedCanceled;
        DWORD   m_dwWaterMark;
    public:
        //  Modem Function
        virtual BOOL    InitModem(BOOL bInit);
        virtual void    ModemInterruptHandler() { GetModemStatus();};
        virtual ULONG   GetModemStatus();
        virtual void    SetDTR(BOOL bSet) {;};
        virtual void    SetRTS(BOOL bSet);
        // Line Function.
        virtual BOOL    InitLine(BOOL bInit) ;
        virtual void    LineInterruptHandler() { GetLineStatus();};
        virtual void    SetBreak(BOOL bSet) ;
        virtual BOOL    SetBaudRate(ULONG BaudRate,BOOL bIrModule) ;
        virtual BOOL    SetByteSize(ULONG ByteSize);
        virtual BOOL    SetParity(ULONG Parity);
        virtual BOOL    SetStopBits(ULONG StopBits);
        // Line Internal Function
        BYTE            GetLineStatus();
        virtual void    SetOutputMode(BOOL UseIR, BOOL Use9Pin) ;

    protected:
        DWORD m_RxInterrupt;
        CRegPDDUart *  m_pRegUart;
        PVOID           m_pRegVirtualAddr;

    public:
        // Interrupt Function
        void    DisableInterrupt(DWORD dwInt)
        { 
                m_pRegUart->Write_UINTM(m_pRegUart->Read_UINTM() | dwInt);
                m_pRegUart->Write_UINTSP(dwInt);
        }

        void    EnableInterrupt(DWORD dwInt)
        { 
                m_pRegUart->Write_UINTSP(dwInt);
                m_pRegUart->Write_UINTM(m_pRegUart->Read_UINTM() & ~dwInt);
        }

        void    ClearInterrupt(DWORD dwInt)
        {
                m_pRegUart->Write_UINTSP(dwInt);
                m_pRegUart->Write_UINTP(dwInt);
        }

        DWORD   GetInterruptStatus()
        { 
                return (m_pRegUart->Read_UINTP()); 
        };

        DWORD   GetInterruptMask ()
        { 
                return (~(m_pRegUart->Read_UINTM()));
        };

        VOID SetClockSelect(DWORD ClockSelect) 
        {
                m_ClockSelect = ClockSelect;
                m_ClockSelectValid = TRUE;
        }

        VOID AllowAutoFlow(BOOL Allow) 
        {
                m_UseAutoFlow = Allow;
        }

    protected:
        CRegistryEdit m_ActiveReg;

        //  Interrupt Handler
        DWORD    m_dwSysIntr;
        HANDLE    m_hISTEvent;

        // Optional Parameter
        DWORD    m_dwDevIndex;
        DWORD    m_dwISTTimeout;
        DWORD    m_dwMemLen;
        BOOL     m_ClockSelectValid;
        DWORD    m_ClockSelect;
        BOOL     m_UseAutoFlow;
        BOOL     m_AutoFlowEnabled;

#ifdef USE_DMA
//DMA
public:
                BSP_ARGS *   m_pBSPArgs;

		   BOOL 		m_IsRXTimeout;
                BOOL 		m_IsRXDMA;
                unsigned int   dwRxLen;
                UINT        DmaRxAddress;
                PHYSICAL_ADDRESS PhysDmaRxBufferAddr;
                PBYTE       pVirtDmaRxBufferAddr;

	UINT        DmaSrcAddress;
        PHYSICAL_ADDRESS PhysDmaSrcBufferAddr;
        PBYTE       pVirtDmaSrcBufferAddr;


        DWORD    m_dwTXDMAEnable;
                DWORD    m_dwAFCEnable;

        DWORD    DMA_Init(void);
        PVOID    InitializeDMA(DWORD nCH);
        BOOL     InitializeChannel(void);
        BOOL     InitializeBuffer(void);
                
                BOOL     InitRxDMA(void); 
                BOOL     StartRxDMA(DWORD len);
                BOOL	  HandleRXDMA(PUCHAR pTxBuffer, ULONG BuffLen);
                
        BOOL     InitXmitDMA(void); 
        BOOL     EnableTxDMA(BOOL fEnable);
        BOOL     StartXmitDMA(PUCHAR pTxBuffer, ULONG BuffLen);


		   DMA_CH_CONTEXT  * pRxDMA;
        DMA_CH_CONTEXT  * pOutputDMA;
        PDMA_PUBLIC_CONTEXT pUartDma;
                
                static  DWORD ThreadForRxDmaDone(CPddUart *);               
static  DWORD ThreadForTxDmaDone(CPddUart *);				
#endif

};

#endif
