/*
* @file hv_drv_UsbMusb.h
* @brief Musb driver.
*
* @author HiView SoC Software Team
* @version 1.0.0
* @date 2022-06-15
*/


#include "hv_drv_UsbErrNo.h"
#include "hv_drv_UsbCh9.h"
#include "hv_drv_UsbGadget.h"

#include "hv_drv_UsbMusbCoreDev.h"
#include "hv_drv_UsbMusbGadget.h"


static struct musb *gadget;

#ifndef CONFIG_USB_WITH_INTERRUPT
int usb_gadget_handle_interrupts(int index)
{
    if (!gadget || !gadget->isr)
        return -EINVAL;

    return gadget->isr(0, gadget);
}
#endif

int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
    int ret;

    pr_debug("-->usb_gadget_register_driver\n");
    if (!driver /*|| driver->speed < USB_SPEED_FULL*/ || !driver->bind ||
        !driver->setup) {
        pr_info("bad parameter.\n");
        return -EINVAL;
    }

    if (!gadget) {
        pr_info("Controller uninitialized\n");
        return -ENXIO;
    }

    ret = musb_gadget_start(&gadget->g, driver);
    if (ret < 0) {
        pr_info("gadget_start failed with %d\n", ret);
        return ret;
    }

    pr_debug("gadget->g addr pullup is 0x%x.gadget->g.max_speed is %d.\n",gadget->g.ops->pullup,gadget->g.max_speed);
    ret = driver->bind(&gadget->g);
    if (ret < 0) {
        pr_info("bind failed with %d\n", ret);
        return ret;
    }

    return 0;
}

int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
    if (driver->disconnect)
        driver->disconnect(&gadget->g);
    if (driver->unbind)
        driver->unbind(&gadget->g);
    return 0;
}


volatile unsigned char flag_s1 = 0;
int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
            void *ctl_regs)
{
    struct musb **musbp;

    switch (plat->mode) {
        case MUSB_PERIPHERAL:
            musbp = &gadget;
            flag_s1 = 3;
            break;
        default:
            return -EINVAL;
    }

    *musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs);
    if (!*musbp) {
        pr_info("Failed to init the controller\n");
        flag_s1 = 4;
        return -EIO;
    }

#ifdef CONFIG_USB_WITH_INTERRUPT
    unsigned int usbIRQ = 40;    
    Hv_Vos_AttachIsr(usbIRQ, gadget->isr, gadget);
    Hv_Vos_UnmaskIrq(usbIRQ);
#endif

    return 0;
}

void musb_unregister(void)
{

#ifdef CONFIG_USB_WITH_INTERRUPT
    unsigned int usbIRQ = 40;
    if(gadget->isr)
    {
        Hv_Vos_DetachIsr(usbIRQ, gadget->isr);
        Hv_Vos_MaskIrq(usbIRQ);
    }
#endif

    if(gadget)
    {
        musb_deinit_controller(gadget);
    }

    
}

