99c905c6a1
QCA BTSOC NVM is a customized firmware file and different vendors may want to have different BTSOC configuration (e.g. Configure SCO over PCM or I2S, Setting Tx power, etc.) via this file. This patch will allow vendors to download different NVM firmware file by reading a device property "firmware-name". Signed-off-by: Rocky Liao <rjliao@codeaurora.org> Tested-by: Harish Bandi <c-hbandi@codeaurora.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
171 lines
3.6 KiB
C
171 lines
3.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Bluetooth supports for Qualcomm Atheros ROME chips
|
|
*
|
|
* Copyright (c) 2015 The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#define EDL_PATCH_CMD_OPCODE (0xFC00)
|
|
#define EDL_NVM_ACCESS_OPCODE (0xFC0B)
|
|
#define EDL_WRITE_BD_ADDR_OPCODE (0xFC14)
|
|
#define EDL_PATCH_CMD_LEN (1)
|
|
#define EDL_PATCH_VER_REQ_CMD (0x19)
|
|
#define EDL_PATCH_TLV_REQ_CMD (0x1E)
|
|
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
|
|
#define MAX_SIZE_PER_TLV_SEGMENT (243)
|
|
|
|
#define EDL_CMD_REQ_RES_EVT (0x00)
|
|
#define EDL_PATCH_VER_RES_EVT (0x19)
|
|
#define EDL_APP_VER_RES_EVT (0x02)
|
|
#define EDL_TVL_DNLD_RES_EVT (0x04)
|
|
#define EDL_CMD_EXE_STATUS_EVT (0x00)
|
|
#define EDL_SET_BAUDRATE_RSP_EVT (0x92)
|
|
#define EDL_NVM_ACCESS_CODE_EVT (0x0B)
|
|
|
|
#define EDL_TAG_ID_HCI (17)
|
|
#define EDL_TAG_ID_DEEP_SLEEP (27)
|
|
|
|
#define QCA_WCN3990_POWERON_PULSE 0xFC
|
|
#define QCA_WCN3990_POWEROFF_PULSE 0xC0
|
|
|
|
#define QCA_HCI_CC_OPCODE 0xFC00
|
|
#define QCA_HCI_CC_SUCCESS 0x00
|
|
|
|
enum qca_baudrate {
|
|
QCA_BAUDRATE_115200 = 0,
|
|
QCA_BAUDRATE_57600,
|
|
QCA_BAUDRATE_38400,
|
|
QCA_BAUDRATE_19200,
|
|
QCA_BAUDRATE_9600,
|
|
QCA_BAUDRATE_230400,
|
|
QCA_BAUDRATE_250000,
|
|
QCA_BAUDRATE_460800,
|
|
QCA_BAUDRATE_500000,
|
|
QCA_BAUDRATE_720000,
|
|
QCA_BAUDRATE_921600,
|
|
QCA_BAUDRATE_1000000,
|
|
QCA_BAUDRATE_1250000,
|
|
QCA_BAUDRATE_2000000,
|
|
QCA_BAUDRATE_3000000,
|
|
QCA_BAUDRATE_4000000,
|
|
QCA_BAUDRATE_1600000,
|
|
QCA_BAUDRATE_3200000,
|
|
QCA_BAUDRATE_3500000,
|
|
QCA_BAUDRATE_AUTO = 0xFE,
|
|
QCA_BAUDRATE_RESERVED
|
|
};
|
|
|
|
enum rome_tlv_dnld_mode {
|
|
ROME_SKIP_EVT_NONE,
|
|
ROME_SKIP_EVT_VSE,
|
|
ROME_SKIP_EVT_CC,
|
|
ROME_SKIP_EVT_VSE_CC
|
|
};
|
|
|
|
enum rome_tlv_type {
|
|
TLV_TYPE_PATCH = 1,
|
|
TLV_TYPE_NVM
|
|
};
|
|
|
|
struct rome_config {
|
|
u8 type;
|
|
char fwname[64];
|
|
uint8_t user_baud_rate;
|
|
enum rome_tlv_dnld_mode dnld_mode;
|
|
enum rome_tlv_dnld_mode dnld_type;
|
|
};
|
|
|
|
struct edl_event_hdr {
|
|
__u8 cresp;
|
|
__u8 rtype;
|
|
__u8 data[0];
|
|
} __packed;
|
|
|
|
struct rome_version {
|
|
__le32 product_id;
|
|
__le16 patch_ver;
|
|
__le16 rome_ver;
|
|
__le32 soc_id;
|
|
} __packed;
|
|
|
|
struct tlv_seg_resp {
|
|
__u8 result;
|
|
} __packed;
|
|
|
|
struct tlv_type_patch {
|
|
__le32 total_size;
|
|
__le32 data_length;
|
|
__u8 format_version;
|
|
__u8 signature;
|
|
__u8 download_mode;
|
|
__u8 reserved1;
|
|
__le16 product_id;
|
|
__le16 rom_build;
|
|
__le16 patch_version;
|
|
__le16 reserved2;
|
|
__le32 entry;
|
|
} __packed;
|
|
|
|
struct tlv_type_nvm {
|
|
__le16 tag_id;
|
|
__le16 tag_len;
|
|
__le32 reserve1;
|
|
__le32 reserve2;
|
|
__u8 data[0];
|
|
} __packed;
|
|
|
|
struct tlv_type_hdr {
|
|
__le32 type_len;
|
|
__u8 data[0];
|
|
} __packed;
|
|
|
|
enum qca_btsoc_type {
|
|
QCA_INVALID = -1,
|
|
QCA_AR3002,
|
|
QCA_ROME,
|
|
QCA_WCN3990,
|
|
QCA_WCN3998,
|
|
};
|
|
|
|
#if IS_ENABLED(CONFIG_BT_QCA)
|
|
|
|
int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
|
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|
enum qca_btsoc_type soc_type, u32 soc_ver,
|
|
const char *firmware_name);
|
|
int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
|
|
int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
|
static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
|
|
{
|
|
return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3998;
|
|
}
|
|
#else
|
|
|
|
static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|
enum qca_btsoc_type soc_type, u32 soc_ver,
|
|
const char *firmware_name)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|