/*
 * board/amlogic/tm2_t962x3_ab301_v1/mtk-bt/LD_usbbt.c
 *
 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <command.h>
#include <common.h>
#include <usb.h>
#include <stdio_dev.h>
#include "LD_usbbt.h"
#include "LD_btmtk_usb.h"

/* Reset BT-module */
extern void reset_mt7668(void);

os_usb_vid_pid array_mtk_vid_pid[] = {
    {0x0E8D, 0x7668, "MTK7668"},    // 7668
    {0x0E8D, 0x76A0, "MTK7662T"},   // 7662T
    {0x0E8D, 0x76A1, "MTK7632T"},   // 7632T
};

int max_mtk_wifi_id = (sizeof(array_mtk_vid_pid) / sizeof(array_mtk_vid_pid[0]));
os_usb_vid_pid *pmtk_wifi = &array_mtk_vid_pid[0];

static mtkbt_dev_t *g_DrvData = NULL;

/* Amlogic need do adaptation. */
extern int vfs_mount(char *volume);
extern unsigned long vfs_getsize(char *filedir);
extern int vfs_read(void* addr,char* filedir,unsigned int offset,unsigned int size );

VOID *os_memcpy(VOID *dst, const VOID *src, UINT32 len)
{
    return memcpy(dst, src, len);
}

VOID *os_memmove(VOID *dest, const void *src,UINT32 len)
{
    return memmove(dest, src, len);
}

VOID *os_memset(VOID *s, int c, size_t n)
{
    return memset(s,c,n);
}

VOID *os_kzalloc(size_t size, unsigned int flags)
{
    VOID *ptr = malloc(size);

    os_memset(ptr, 0, size);
    return ptr;
}

void LD_load_code_from_bin(unsigned char **image, char *bin_name, char *path, mtkbt_dev_t *dev, u32 *code_len)
{
    char mtk_patch_bin_patch[128] = "\0";

    /** implement by MTK
     * path: /system/etc/firmware/mt76XX_patch_eX_hdr.bin
     * If argument "path" is NULL, access "/system/etc/firmware" directly like as request_firmware
     * if argument "path" is not NULL, so far only support directory "userdata"
     *     NOTE: latest vfs_mount seems decided this time access directory
     */
    if (path == NULL && vfs_mount("system") != 0) {
        usb_debug("vfs_mount - system fail\n");
        return;
    } else if (path != NULL && vfs_mount("userdata") != 0) {
        usb_debug("vfs_mount - userdata fail\n");
        return;
    }

    if (path) {
        snprintf(mtk_patch_bin_patch, sizeof(mtk_patch_bin_patch), "%s/%s", path, bin_name);
        printf("File: %s\n", mtk_patch_bin_patch);
    } else {
        snprintf(mtk_patch_bin_patch, sizeof(mtk_patch_bin_patch), "%s/%s", "/vendor/firmware", bin_name);
        printf("mtk_patch_bin_patch: %s\n", mtk_patch_bin_patch);
    }
    *code_len = vfs_getsize(mtk_patch_bin_patch);
    if (*code_len == 0) {
        usb_debug("Get file size fail\n");
        return;
    }

    // malloc buffer to store bt patch file data
    *image = malloc(*code_len);
    if (vfs_read(*image, mtk_patch_bin_patch, 0, *code_len) != 0)
    {
        usb_debug("vfs_read fail\n");
        return;
    }
    usb_debug("Load file OK\n");
    //usb_dump((unsigned int)*image, 0x200); //Amlogic had better dump the first segment of fw data.
    return;
}

static int usb_bt_bulk_msg(
        mtkbt_dev_t *dev,
        u32 epType,
        u8 *data,
        int size,
        int* realsize,
        int timeout /* not used */
)
{
    int ret =0 ;
    if (dev == NULL || dev->udev == NULL || dev->bulk_tx_ep ==  NULL)
    {
        usb_debug("bulk out error 00\n");
        return -1;
    }

    //usb_debug("[usb_bt_bulk_msg]ep_addr:%x\n", dev->bulk_tx_ep->bEndpointAddress);
    //usb_debug("[usb_bt_bulk_msg]ep_maxpkt:%x\n", dev->bulk_tx_ep->wMaxPacketSize);

    if (epType == MTKBT_BULK_TX_EP)
    {
        ret = usb_bulk_msg(dev->udev,usb_sndbulkpipe(dev->udev,dev->bulk_tx_ep->bEndpointAddress),data,size,realsize,2000);

        if (ret)
        {
            usb_debug("bulk out error 01\n");
            return -1;
        }

        if (*realsize == size)
        {
            //usb_debug("bulk out success 01,size =0x%x\n",size);
            return 0;
        }
        else
        {
            usb_debug("bulk out fail 02,size =0x%x,realsize =0x%x\n",size,*realsize);
        }
    }
    return -1;
}

static int usb_bt_control_msg(
        mtkbt_dev_t *dev,
        u32 epType,
        u8 request,
        u8 requesttype,
        u16 value,
        u16 index,
        u8 *data,
        int data_length,
        int timeout  /* not used */
)
{
    int ret = -1;
    if (epType == MTKBT_CTRL_TX_EP)
    {
        ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), request,
                  requesttype, value, index, data, data_length,timeout);
    }
    else if (epType == MTKBT_CTRL_RX_EP)
    {
        ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), request,
                  requesttype, value, index, data, data_length,timeout);
    }
    else
    {
        usb_debug("control message wrong Type =0x%x\n",epType);
    }

    if (ret < 0)
    {
        usb_debug("Err1(%d)\n", ret);
        return ret;
    }
    return ret;
}

static int usb_bt_interrupt_msg(
        mtkbt_dev_t *dev,
        u32 epType,
        u8 *data,
        int size,
        int* realsize,
        int timeout  /* unit of 1ms */
)
{
    int ret = -1;

    usb_debug("epType = 0x%x\n",epType);

    if (epType == MTKBT_INTR_EP)
    {
           ret = usb_submit_int_msg(dev->udev,usb_rcvintpipe(dev->udev,dev->intr_ep->bEndpointAddress),data,size,realsize,timeout);
    }

    if (ret < 0 )
    {
        usb_debug("Err1(%d)\n", ret);
        return ret;
    }
    usb_debug("ret = 0x%x\n",ret);
    return ret;
}

static HC_IF usbbt_host_interface =
{
        usb_bt_bulk_msg,
        usb_bt_control_msg,
        usb_bt_interrupt_msg,
};

static void Ldbtusb_diconnect (btusbdev_t *dev)
{
    LD_btmtk_usb_disconnect(g_DrvData);

    if (g_DrvData)
    {
        os_kfree(g_DrvData);
    }
    g_DrvData = NULL;
}

static int Ldbtusb_SetWoble(btusbdev_t *dev)
{
    if (!g_DrvData)
    {
        usb_debug("usb set woble fail ,because no drv data\n");
        return -1;
    }
    else
    {
        LD_btmtk_usb_SetWoble(g_DrvData);
        usb_debug("usb set woble end\n");
    }
    return 0;
}

int Ldbtusb_connect (btusbdev_t *dev)
{
    int ret = 0;

    struct usb_endpoint_descriptor *ep_desc;
    struct usb_interface *iface;
    int i;
    iface = &dev->config.if_desc[0];

    if (g_DrvData == NULL)
    {
        g_DrvData = os_kmalloc(sizeof(mtkbt_dev_t),MTK_GFP_ATOMIC);

        if (!g_DrvData)
        {
            usb_debug("Not enough memory for mtkbt virtual usb device.\n");
            return -1;
        }
        else
        {
            os_memset(g_DrvData,0,sizeof(mtkbt_dev_t));
            g_DrvData->udev = dev;
            g_DrvData->connect = Ldbtusb_connect;
            g_DrvData->disconnect = Ldbtusb_diconnect;
            g_DrvData->SetWoble = Ldbtusb_SetWoble;
        }
    }
    else
    {
            return -1;
    }

    for (i = 0; i < iface->desc.bNumEndpoints; i++)
    {
        ep_desc = &iface->ep_desc[i];

        if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)
        {
            if (ep_desc->bEndpointAddress & USB_DIR_IN)
            {
                g_DrvData->bulk_rx_ep = ep_desc;
            }
            else
            {
                g_DrvData->bulk_tx_ep = ep_desc;
            }
            continue;
        }

        /* is it an interrupt endpoint? */
        if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
        {
            g_DrvData->intr_ep = ep_desc;
            continue;
        }
    }
    if (!g_DrvData->intr_ep || !g_DrvData->bulk_tx_ep || !g_DrvData->bulk_rx_ep)
    {
        os_kfree(g_DrvData);
        g_DrvData = NULL;
        usb_debug("btmtk_usb_probe end Error 3\n");
        return -1;
    }

    /* Init HostController interface */
    g_DrvData->hci_if = &usbbt_host_interface;

    /* btmtk init */
    ret = LD_btmtk_usb_probe(g_DrvData);

    if (ret != 0)
    {
        usb_debug("usb probe fail\n");
        if (g_DrvData)
        {
           os_kfree(g_DrvData);
        }
        g_DrvData = NULL;
        return -1;
    }
    else
    {
        usb_debug("usbbt probe success\n");
    }
    return ret;
}

static int checkUsbDevicePort(struct usb_device* udev, u16 vendorID, u16 productID, u8 port)
{
    struct usb_device* pdev = NULL;
    int i;
#if defined (CONFIG_USB_PREINIT)
    usb_stop(port);
    if (usb_post_init(port) == 0)
#else
	/* Attention:
	 * if BT_USB_PORT_NUM is defined,
	 * Amlogic can only initialize MTK7668 USB port, but NOT all ports.
	 */
    usb_stop();
    if (usb_init() == 0) //if (usb_init(port) == 0)
#endif
    {
        /* get device */
        for (i=0; i<USB_MAX_DEVICE; i++) {
          pdev = usb_get_dev_index(i);
          printf("pdev->descriptor.idVendor=0x%x; pdev->descriptor.idProduct=0x%x\n",pdev->descriptor.idVendor,pdev->descriptor.idProduct);
          if ((pdev != NULL) && (pdev->descriptor.idVendor == vendorID) && (pdev->descriptor.idProduct == productID))  // MTK 7662
          {
              usb_debug("OK\n");
              memcpy(udev, pdev, sizeof(struct usb_device));
              return 0 ;
          }
        }
    }
    return -1;
}

static int findUsbDevice(struct usb_device* udev)
{
    int ret = -1;
    u8 idx = 0;
    u8 i = 0;
    usb_debug("IN\n");
    if (udev == NULL)
    {
        usb_error("udev can not be NULL\n");
        return -1;
    }

#ifdef BT_USB_PORT_NUM
	/* check mtk bt usb port */
	idx = BT_USB_PORT_NUM;
	usb_debug("find mtk bt usb device from usb port[%d]\n", idx);
	while (i < 1 /*max_mtk_wifi_id*/) {
            ret = checkUsbDevicePort(udev, (pmtk_wifi + i)->vid, (pmtk_wifi + i)->pid, idx);
            if (ret == 0) break;
            i++;
	}
	if (ret == 0)
	{
		return 0;
	}
#else
    // not find mt bt usb device from given usb port, so poll every usb port.
    char portNumStr[10] = "\0";
    #if defined(ENABLE_FIFTH_EHC)
    const char u8UsbPortCount = 5;
    #elif defined(ENABLE_FOURTH_EHC)
    const char u8UsbPortCount = 4;
    #elif defined(ENABLE_THIRD_EHC)
    const char u8UsbPortCount = 3;
    #elif defined(ENABLE_SECOND_EHC)
    const char u8UsbPortCount = 2;
    #else
    const char u8UsbPortCount = 1;
    #endif
    for (idx = 0; idx < u8UsbPortCount; idx++)
    {
        i = 0;
        while (i < max_mtk_wifi_id) {
            ret = checkUsbDevicePort(udev, (pmtk_wifi + i)->vid, (pmtk_wifi + i)->pid, idx);
            if (ret == 0) break;
            i++;
        }
        if (ret == 0)
        {
            // set bt_usb_port to store mt bt usb device port
            snprintf(portNumStr, sizeof(portNumStr), "%d", idx);
            setenv(BT_USB_PORT, portNumStr);
            saveenv();
            return 0;
        }
    }
#endif

    usb_error("Not find usb device\n");
    return -1;
}

int do_setMtkBT( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
    int ret = 0;
    struct usb_device udev;
    memset(&udev, 0, sizeof(struct usb_device));
    usb_debug("IN\n");
    if (argc < 1)
    {
        cmd_usage(cmdtp);
        return -1;
    }

    /* Reset BT-module */
    reset_mt7668();

    // MTK USB controller
    ret = findUsbDevice(&udev);
    if (ret != 0)
    {
        usb_error("find bt usb device failed\n");
        return -1;
    }
    ret = Ldbtusb_connect(&udev);
    if (ret != 0)
    {
        usb_error("connect to bt usb device failed\n");
        return -1;
    }
    ret = Ldbtusb_SetWoble(&udev);
    if (ret != 0)
    {
        usb_error("set bt usb device woble cmd failed\n");
        return -1;
    }
    usb_debug("OK\n");
    return ret;
}

