/*
* @file hv_drv_UsbMusbIO.h
* @brief Header of MUSB driver register I/O.
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2022-06-15
*/

#ifndef __HV_DRV_USB_MUSB_HOST_IO_H
#define __HV_DRV_USB_MUSB_HOST_IO_H

//#define REG_USB_CONTROLLER_RESET 0x10003E04
#define MUSB_REGS_PHY_ADDR_BASE         0x11090400
#define MUSB_REGS_IP_RESET_ADDR         0x11011008

#define MUSB_REGS_ADDR_BASE             0x11090000  //0x41002000
//USB2
//#define MUSB_REGS_ADDR_BASE 0x1C000400

#define MUSB_REQ_PKT_COUNT(epnum, count) \
    USB_W32(MUSB_REGS_ADDR_BASE + 0x300 + 4 * epnum, count)

INLINE u16 musb_readw(u16 offset) {
    return USB_R16(MUSB_REGS_ADDR_BASE + offset);
}

INLINE u32 musb_readl(u16 offset) {
    return USB_R32(MUSB_REGS_ADDR_BASE + offset);
}

INLINE void musb_writew(u16 offset, u16 data) {
    USB_W16(MUSB_REGS_ADDR_BASE + offset, data);
}

INLINE void musb_writew_lo(u16 offset, u16 data) {
    USB_W8(MUSB_REGS_ADDR_BASE + offset, (u8)(data & 0xff));
}

INLINE void musb_writew_hi(u16 offset, u16 data) {
    USB_W8(MUSB_REGS_ADDR_BASE + offset + 1, (u8)(data >> 8));
}

INLINE void musb_writel(u16 offset, u32 data) {
    USB_W32(MUSB_REGS_ADDR_BASE + offset, data);
}

INLINE u8 musb_readb(u16 offset) {
    return USB_R8(MUSB_REGS_ADDR_BASE + offset);
}

INLINE void musb_writeb(u16 offset, u8 data) {
    USB_W8(MUSB_REGS_ADDR_BASE + offset, data);
}

INLINE void musb_write_txfifosz(u8 c_size) {
    musb_writeb(MUSB_TXFIFOSZ, c_size);
}

INLINE void musb_write_txfifoadd(u16 c_off) {
    musb_writew(MUSB_TXFIFOADD, c_off);
}

INLINE void musb_write_rxfifosz(u8 c_size) {
    musb_writeb(MUSB_RXFIFOSZ, c_size);
}

INLINE void  musb_write_rxfifoadd(u16 c_off) {
    musb_writew(MUSB_RXFIFOADD, c_off);
}

INLINE void musb_write_ulpi_buscontrol(u8 val) {
    musb_writeb(MUSB_ULPI_BUSCONTROL, val);
}

INLINE u8 musb_read_txfifosz() {
    return musb_readb(MUSB_TXFIFOSZ);
}

INLINE u16 musb_read_txfifoadd() {
    return musb_readw(MUSB_TXFIFOADD);
}

INLINE u8 musb_read_rxfifosz() {
    return musb_readb(MUSB_RXFIFOSZ);
}

INLINE u16  musb_read_rxfifoadd() {
    return musb_readw(MUSB_RXFIFOADD);
}

INLINE u8 musb_read_ulpi_buscontrol(void) {
    return musb_readb(MUSB_ULPI_BUSCONTROL);
}

INLINE u8 musb_read_configdata(void) {
    musb_writeb(MUSB_INDEX, 0);
    return musb_readb(0x10 + MUSB_CONFIGDATA);
}

INLINE u16 musb_read_hwvers() {
    return musb_readw(MUSB_HWVERS);
}

INLINE void *musb_read_target_reg_base(u8 i) {
    return (void *)(MUSB_BUSCTL_OFFSET(i, 0));
}

#define musb_ep_select(_epnum) \
    musb_writeb(MUSB_INDEX, (_epnum))

static inline void  musb_write_txfunaddr(u8 epnum,
        u8 qh_addr_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
            qh_addr_reg);
}

static inline void  musb_write_txhubaddr(u8 epnum,
        u8 qh_addr_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
            qh_addr_reg);
}

static inline void  musb_write_txhubport(u8 epnum,
        u8 qh_h_port_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
            qh_h_port_reg);
}


static inline void musb_write_rxfunaddr(u8 epnum, u8 qh_addr_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
            qh_addr_reg);
}

static inline void musb_write_rxhubaddr(u8 epnum,
        u8 qh_h_addr_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
            qh_h_addr_reg);
}

static inline void musb_write_rxhubport(u8 epnum,
        u8 qh_h_port_reg)
{
    musb_writeb(MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
            qh_h_port_reg);
}
#endif  /* __MUSB_REGS_H__ */
