/* National 9604 registers */

#define USBN9604_PHYS	0x08000000

extern u8 * USBN9604_Offset;

static u8 last_address = 255;//an invalid address

inline u8 read_9604(u8 addr) {
	u8 tmp;
	if (addr != last_address) {
		outb(addr, USBN9604_Offset + (CONFIG_USBN9604_OFFSET));
		last_address = addr;
	}
	tmp = inb(USBN9604_Offset);
	return tmp;
}

inline void write_9604(u8 value, u8 addr) {
	if (addr != last_address) {
		outb(addr, USBN9604_Offset + (CONFIG_USBN9604_OFFSET));
		last_address = addr;
	}
	outb(value, USBN9604_Offset);
}


	
#define MCNTRL		0x00
#define CCONF		0x01

#define RID		0x03
#define FAR		0x04
#define NFSR		0x05
#define MAEV		0x06
#define MAMSK		0x07
#define ALTEV		0x08
#define ALTMSK		0x09
#define TXEV		0x0A
#define TXMSK		0x0B
#define RXEV		0x0C
#define RXMSK		0x0D
#define NAKEV		0x0E
#define NAKMSK		0x0F
#define FWEV		0x10
#define FWMSK		0x11
#define FNH		0x12
#define FNL		0x13
#define DMACNTRL	0x14
#define DMAEV		0x15
#define DMAMSK		0x16
#define MIR		0x17
#define DMACNT		0x18
#define DMAERR		0x19

#define WKUP		0x1B




#define EPC0		0x20
#define TXD0		0x21
#define TXS0		0x22
#define TXC0		0x23

#define RXD0		0x25
#define RXS0		0x26
#define RXC0		0x27
#define EPC1		0x28
#define TXD1		0x29
#define TXS1		0x2A
#define TXC1		0x2B
#define EPC2		0x2C
#define RXD1		0x2D
#define RXS1		0x2E
#define RXC1		0x2F
#define EPC3		0x30
#define TXD2		0x31
#define TXS2		0x32
#define TXC2		0x33
#define EPC4		0x34
#define RXD2		0x35
#define RXS2		0x36
#define RXC2		0x37
#define EPC5		0x38 
#define TXD3		0x39
#define TXS3		0x3A
#define TXC3		0x3B
#define EPC6		0x3C
#define RXD3		0x3D
#define RXS3		0x3E
#define RXC3		0x3F


/* MCNTRL values */
#define MCNTRL_SRST		(1 << 0)
#define MCNTRL_VGE		(1 << 2)
#define MCNTRL_NAT		(1 << 3)
#define MCNTRL_INTOC_MASK	(3 << 6)
#define MCNTRL_INTOC_DISABLE	0
#define MCNTRL_INTOC_ActLowOpen	(1 << 6)
#define MCNTRL_INTOC_ActHigh	(2 << 6)
#define MCNTRL_INTOC_ActLowPP	(3 << 6)

/* CCONF values */
#define CCONF_CLKDIV_MASK	0x0F
#define CCONF_CODIS		(1 << 7)

/* FAR values */
#define FAR_AD_MASK		0x7F
#define FAR_AD_EN		0x80

/* NFSR values */
#define NFSR_NodeReset		0x0
#define NFSR_NodeResume		0x1
#define NFSR_NodeOperational	0x2
#define NFSR_NodeSuspend	0x3

/* MAEV values */
#define MAEV_WARN		(1 << 0)
#define MAEV_ALT		(1 << 1)
#define MAEV_TX_EV		(1 << 2)
#define MAEV_FRAME		(1 << 3)
#define MAEV_NAK		(1 << 4)
#define MAEV_ULD		(1 << 5)
#define MAEV_RX_EV		(1 << 6)
#define MAEV_INTR		(1 << 7)

/* MAMSK values */
#define MAMSK_WARN		(1 << 0)
#define MAMSK_ALT		(1 << 1)
#define MAMSK_TX_EV		(1 << 2)
#define MAMSK_FRAME		(1 << 3)
#define MAMSK_NAK		(1 << 4)
#define MAMSK_ULD		(1 << 5)
#define MAMSK_RX_EV		(1 << 6)
#define MAMSK_INTR		(1 << 7)

/* ALTEV values */

#define ALTEV_WKUP		(1 << 1)
#define ALTEV_DMA		(1 << 2)
#define ALTEV_EOP		(1 << 3)
#define ALTEV_SD3		(1 << 4)
#define ALTEV_SD5		(1 << 5)
#define ALTEV_RESET		(1 << 6)
#define ALTEV_RESUME		(1 << 7)

/* ALTMSK values */

#define ALTMSK_WKUP		(1 << 1)
#define ALTMSK_DMA		(1 << 2)
#define ALTMSK_EOP		(1 << 3)
#define ALTMSK_SD3		(1 << 4)
#define ALTMSK_SD5		(1 << 5)
#define ALTMSK_RESET		(1 << 6)
#define ALTMSK_RESUME		(1 << 7)

/* NAKEV values */

#define NAKEV_TXFIFO0		(1 << 0)
#define NAKEV_TXFIFO1		(1 << 1)
#define NAKEV_TXFIFO2		(1 << 2)
#define NAKEV_TXFIFO3		(1 << 3)
#define NAKEV_RXFIFO0		(1 << 4)
#define NAKEV_RXFIFO1		(1 << 5)
#define NAKEV_RXFIFO2		(1 << 6)
#define NAKEV_RXFIFO3		(1 << 7)


/* WKUP values */
#define WKUP_PNDUSB		(1 << 0)
#define WKUP_PNDUC		(1 << 1)
#define WKUP_ENUSB		(1 << 2)
#define WKUP_ENUC		(1 << 3)
#define WKUP_WKMODE		(1 << 5)
#define WKUP_HOS		(1 << 6)
#define WKUP_FHT		(1 << 7)

/* EPC values */

#define EPC_EP_MASK		0x0F    //EP0 == 0
#define EPC_EP_EN		(1 << 4)//not EP0
#define EPC_ISO			(1 << 5)//not EP0
#define EPC_DEF			(1 << 6)//EP0 only
#define EPC_STALL		(1 << 7)

/* TXS values */

#define TXS_TCOUNT_MASK		0x1F
#define TXS_TX_DONE		(1 << 5)
#define TXS_ACK_STAT		(1 << 6)
#define TXS_TX_URUN		(1 << 7)

/* TXC values */

#define TXC_TX_EN		(1 << 0)
#define TXC_LAST		(1 << 1)//not for endpoint 0
#define TXC_TOGGLE		(1 << 2)//sets DATA1 when set
#define TXC_FLUSH		(1 << 3)
#define TXC_IGN_IN		(1 << 4)//only endpoint 0
#define TXC_RFF			(1 << 4)//not for endpoint 0
#define TXC_TFWL0		(1 << 5)//"
#define TXC_TFWL1		(1 << 6)//"
#define TXC_IGN_ISOMSK		(1 << 7)//"

/* TXEV values */

#define TXEV_FIFO0		(1 << 0)
#define TXEV_FIFO1		(1 << 1)
#define TXEV_FIFO2		(1 << 2)
#define TXEV_FIFO3		(1 << 3)
#define TXEV_UDRRN0		(1 << 4)
#define TXEV_UDRRN1		(1 << 5)
#define TXEV_UDRRN2		(1 << 6)
#define TXEV_UDRRN3		(1 << 7)


/* RXEV values */

#define RXEV_FIFO0		(1 << 0)
#define RXEV_FIFO1		(1 << 1)
#define RXEV_FIFO2		(1 << 2)
#define RXEV_FIFO3		(1 << 3)
#define RXEV_OVRRN0		(1 << 4)
#define RXEV_OVRRN1		(1 << 5)
#define RXEV_OVRRN2		(1 << 6)
#define RXEV_OVRRN3		(1 << 7)

/* RXC values */

#define RXC_RX_EN		(1 << 0)
#define RXC_IGN_OUT		(1 << 1)
#define RXC_IGN_SETUP		(1 << 2)
#define RXC_FLUSH		(1 << 3)
#define RXC_RFWL0		(1 << 5)
#define RXC_RFWL1		(1 << 6)

/* RXS values */

#define RXS_RCOUNTMASK		0xF
#define RXS_RX_LAST		(1 << 4)
#define RXS_TOGGLE		(1 << 5)
#define RXS_SETUP		(1 << 6)
#define RXS_RX_ERR		(1 << 7)



