/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2 of the GNU General Public License ("GPLv2 License")
 * or BSD License.
 *
 * GPLv2 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
#ifndef __LD_BTMTK_USB_H__
#define __LD_BTMTK_USB_H__

#include <LD_usbbt.h>

/* Memory map for MTK BT */
//#if 0
/* SYS Control */
#define SYSCTL	0x400000

/* WLAN */
#define WLAN		0x410000

/* MCUCTL */
#define CLOCK_CTL		0x0708
#define INT_LEVEL		0x0718
#define COM_REG0		0x0730
#define SEMAPHORE_00	0x07B0
#define SEMAPHORE_01	0x07B4
#define SEMAPHORE_02	0x07B8
#define SEMAPHORE_03	0x07BC

/* Chip definition */

#define CONTROL_TIMEOUT_JIFFIES		(300)
#define DEVICE_VENDOR_REQUEST_OUT	0x40
#define DEVICE_VENDOR_REQUEST_IN	0xc0
#define DEVICE_CLASS_REQUEST_OUT	0x20
#define DEVICE_CLASS_REQUEST_IN		0xa0

#define BTUSB_MAX_ISOC_FRAMES	10
#define BTUSB_INTR_RUNNING	0
#define BTUSB_BULK_RUNNING	1
#define BTUSB_ISOC_RUNNING	2
#define BTUSB_SUSPENDING	3
#define BTUSB_DID_ISO_RESUME	4

/* ROM Patch */
#define PATCH_HCI_HEADER_SIZE_BULK_EP 4
#define PATCH_HCI_HEADER_SIZE_CTRL_EP 3
#define PATCH_WMT_HEADER_SIZE 5
#define PATCH_HEADER_SIZE_BULK_EP (PATCH_WMT_HEADER_SIZE + PATCH_HCI_HEADER_SIZE_BULK_EP)
#define PATCH_HEADER_SIZE_CTRL_EP (PATCH_WMT_HEADER_SIZE + PATCH_HCI_HEADER_SIZE_CTRL_EP)
#define UPLOAD_PATCH_UNIT 512
#define PATCH_INFO_SIZE 30
#define PATCH_PHASE1 1
#define PATCH_PHASE2 2
#define PATCH_PHASE3 3
#define PATCH_LEN_ILM (192 * 1024)

#define BUZZARD_CHIP_ID 0x70010200
#define BUZZARD_FLAVOR 0x70010020
#define BUZZARD_FW_VERSION 0x80021004


#define BT_DOWNLOAD	1
#define WIFI_DOWNLOAD	2

#define DOWNLOAD_BY_INDEX	0
#define DOWNLOAD_BY_TYPE	1
#define BT_BIN_TYP_NUM	6

/**
 * 0: patch download is not complete/BT get patch semaphore fail (WiFi get semaphore success)
 * 1: patch download is complete
 * 2: patch download is not complete/BT get patch semaphore success
 */
#define PATCH_ERR -1
#define PATCH_IS_DOWNLOAD_BY_OTHER 0
#define PATCH_READY 1
#define PATCH_NEED_DOWNLOAD 2

#define MAX_BIN_FILE_NAME_LEN 64
#define LD_BT_MAX_EVENT_SIZE 260
#define BD_ADDR_LEN 6

#define WOBLE_SETTING_FILE_NAME_7961 "woble_setting_7961.bin"
#define WOBLE_SETTING_FILE_NAME_7668 "woble_setting_7668.bin"
#define WOBLE_SETTING_FILE_NAME_7663 "woble_setting_7663.bin"
#define WOBLE_SETTING_FILE_NAME "woble_setting.bin"
#define WOBLE_CFG_NAME_PREFIX "woble_setting"
#define WOBLE_CFG_NAME_SUFFIX "bin"

#define BT_CFG_NAME "bt.cfg"
#define BT_CFG_NAME_PREFIX "bt_mt"
#define BT_CFG_NAME_PREFIX_76XX "bt_"
#define BT_CFG_NAME_SUFFIX "cfg"
#define BT_UNIFY_WOBLE "SUPPORT_UNIFY_WOBLE"
#define BT_UNIFY_WOBLE_TYPE "UNIFY_WOBLE_TYPE"
#define BT_LD_DL_WIFI_ENABLE "LD_DL_WIFI_ENABLE"
#define BT_WMT_CMD "WMT_CMD"
#define CHIP_TYPE_MASK  0xff00
#define CHIP_ID_MASK    0xffff
#define CHIP_ID_MASK1   0xffff0000
#define CHIP_ID_MASK2   0xffffffff
#define FW_VERSION_MASK 0xff
#define CHIP_TYPE_79XX  0x7900
#define CHIP_TYPE_76XX  0x7600
#define CHIP_ID_7668    0x7668
#define CHIP_ID_7663    0x7663
#define CHIP_ID_7961    0x7961
#define CHIP_ID_7902    0x7902
#define CHIP_ID_6639    0x6639
#define CHIP_ID_7630    0x76300000
#define CHIP_ID_7650    0x76500000
#define CHIP_ID_7632    0x76320000
#define CHIP_ID_7632T   0x76320100
#define CHIP_ID_7662    0x76620000
#define CHIP_ID_7662T   0x76620100

#define WMT_CMD_COUNT 255

#define WAKE_DEV_RECORD		 "wake_on_ble.conf"
#define WAKE_DEV_RECORD_PATH	"misc/bluedroid"
#define APCF_SETTING_COUNT	10
#define WOBLE_SETTING_COUNT	10

/* It is for mt7961 download rom patch*/
#define FW_ROM_PATCH_HEADER_SIZE	32
#define FW_ROM_PATCH_GD_SIZE	64
#define FW_ROM_PATCH_SEC_MAP_SIZE	64
#define SEC_MAP_NEED_SEND_SIZE	52
#define PATCH_STATUS	6
#define SECTION_SPEC_NUM	13
#define WMT_HEADER_LEN 4
#define LOAD_PATCH_PHASE_LEN 1

/* this for 79XX need download patch staus
 * 0:
 * patch download is not complete, BT driver need to download patch
 * 1:
 * patch is downloading by Wifi,BT driver need to retry until status = PATCH_READY
 * 2:
 * patch download is complete, BT driver no need to download patch
 */
#define BUZZARD_PATCH_ERR -1
#define BUZZARD_PATCH_NEED_DOWNLOAD 0
#define BUZZARD_PATCH_IS_DOWNLOAD_BY_OTHER 1
#define BUZZARD_PATCH_READY 2

/* 0:
 * using legacy wmt cmd/evt to download fw patch, usb/sdio just support 0 now
 * 1:
 * using DMA to download fw patch
 */
#define PATCH_DOWNLOAD_USING_WMT 0
#define PATCH_DOWNLOAD_USING_DMA 1


#define PATCH_DOWNLOAD_CMD_DELAY_TIME 5
#define PATCH_DOWNLOAD_CMD_RETRY 0
#define PATCH_DOWNLOAD_PHASE1_2_DELAY_TIME 1
#define PATCH_DOWNLOAD_PHASE1_2_RETRY 5
#define PATCH_DOWNLOAD_PHASE3_DELAY_TIME 20
#define PATCH_DOWNLOAD_PHASE3_RETRY 20

#define PM_SOURCE_DISABLE               (0xFF)

#define SECTION_NUM_MAX (0xFF)
#define SECTION_NUM_MIN 1

enum {
	BTMTK_EP_TYPE_OUT_CMD = 0,	/*EP type out for hci cmd and wmt cmd */
	BTMTK_EP_TPYE_OUT_ACL,	/* EP type out for acl pkt with load rompatch */
};

typedef enum {
	TYPE_APCF_CMD,
} woble_setting_type;

enum fw_cfg_index_len {
	FW_CFG_INX_LEN_NONE = 0,
	FW_CFG_INX_LEN_2 = 2,
	FW_CFG_INX_LEN_3 = 3,
};

struct fw_cfg_struct {
	u8	*content;	/* APCF content or radio off content */
	int	length;		/* APCF content or radio off content of length */
};

#define UNIFY_WOBLE_LEGACY 0
#define UNIFY_WOBLE_WAVEFORM 1
struct bt_cfg_struct {
	u8	support_unify_woble;	/* support unify woble or not */
	u8	unify_woble_type;	/* 0: legacy. 1: waveform. 2: IR */
	u8	support_wifi_dl;	/* 0: disable. 1: enable */
	struct fw_cfg_struct wmt_cmd[WMT_CMD_COUNT];
};

struct LD_btmtk_usb_data {
	mtkbt_dev_t *udev; /* store the usb device informaiton */

	unsigned long flags;
	int meta_tx;
	HC_IF *hcif;

	u8 cmdreq_type;

	unsigned int sco_num;
	int isoc_altsetting;
	int suspend_count;

	/* request for different io operation */
	u8 w_request;
	u8 r_request;

	/* io buffer for usb control transfer */
	unsigned char *io_buf;

	unsigned char *fw_image;
	unsigned char *fw_header_image;
	unsigned char *fw_bin_file_name;

	unsigned char *rom_patch;
	unsigned char *rom_patch_header_image;
	unsigned char *rom_patch_bin_file_name;
	u32 chip_id;
	unsigned int	flavor;
	unsigned int	proj;
	unsigned int	fw_version;
	u8 need_load_fw;
	u8 need_load_rom_patch;
	u32 rom_patch_offset;
	u32 rom_patch_len;
	u32 fw_len;
	int recv_evt_len;

	u8 local_addr[BD_ADDR_LEN];
	char *woble_setting_file_name;
	u8 *setting_file;
	u32 setting_file_len;
	u8 *wake_dev;   /* ADDR:NAP-UAP-LAP, VID/PID:Both Little endian */
	u32 wake_dev_len;
	struct fw_cfg_struct		woble_setting_apcf[WOBLE_SETTING_COUNT];
	struct fw_cfg_struct		woble_setting_apcf_fill_mac[WOBLE_SETTING_COUNT];
	struct fw_cfg_struct		woble_setting_apcf_fill_mac_location[WOBLE_SETTING_COUNT];

	struct fw_cfg_struct		woble_setting_radio_off;
	struct fw_cfg_struct		woble_setting_wakeup_type;
	/* complete event */
	struct fw_cfg_struct		woble_setting_radio_off_comp_event;

	struct bt_cfg_struct bt_cfg;
	struct _Section_Map	*sectionMap_table;
};

struct _PATCH_HEADER {
	u8 ucDateTime[16];
	u8 ucPlatform[4];
	u16 u2HwVer;
	u16 u2SwVer;
	u32 u4MagicNum;
};

struct _Global_Descr {
	u32 u4PatchVer;
	u32 u4SubSys;
	u32 u4FeatureOpt;
	u32 u4SectionNum;
};

struct _Section_Map {
	u32 u4SecType;
	u32 u4SecOffset;
	u32 u4SecSize;
	union {
		u32 u4SecSpec[SECTION_SPEC_NUM];
		struct {
			u32 u4DLAddr;
			u32 u4DLSize;
			u32 u4SecKeyIdx;
			u32 u4AlignLen;
			u32 u4SecType;
			u32 u4DLModeCrcType;
			u32 u4Crc;
			u32 reserved[6];	
		}bin_info_spec;
	};
};

u8 LD_btmtk_usb_getWoBTW(void);
int LD_btmtk_usb_probe(mtkbt_dev_t *dev, int flag);
void LD_btmtk_usb_disconnect(mtkbt_dev_t *dev);
void LD_btmtk_usb_SetWoble(mtkbt_dev_t *dev);
int Ldbtusb_getBtWakeT(struct LD_btmtk_usb_data *data);


#define REV_MT76x2E3		0x0022

#define MT_REV_LT(_data, _chip, _rev) \
	is_##_chip(_data) && (((_data)->chip_id & 0x0000ffff) < (_rev))

#define MT_REV_GTE(_data, _chip, _rev) \
	is_##_chip(_data) && (((_data)->chip_id & 0x0000ffff) >= (_rev))

/*
 *  Load code method
 */
enum LOAD_CODE_METHOD {
	BIN_FILE_METHOD,
	HEADER_METHOD,
};
#endif
